diff --git a/src/core/libraries/kernel/thread_management.h b/src/core/libraries/kernel/thread_management.h index 3cdb300f7c9..3931b48e208 100644 --- a/src/core/libraries/kernel/thread_management.h +++ b/src/core/libraries/kernel/thread_management.h @@ -200,6 +200,7 @@ int PS4_SYSV_ABI scePthreadSetprio(ScePthread thread, int prio); */ int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr, const char* name); +int PS4_SYSV_ABI scePthreadMutexDestroy(ScePthreadMutex* mutex); int PS4_SYSV_ABI scePthreadMutexattrInit(ScePthreadMutexattr* attr); int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type); int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol); @@ -210,6 +211,7 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex); */ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, const char* name); +int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond); int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr); int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond); int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex); diff --git a/src/core/libraries/network/error_codes.h b/src/core/libraries/network/error_codes.h new file mode 100644 index 00000000000..23f8d6de2d9 --- /dev/null +++ b/src/core/libraries/network/error_codes.h @@ -0,0 +1,246 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +constexpr int ORBIS_NET_ERROR_EPERM = 0x80410101; +constexpr int ORBIS_NET_ERROR_ENOENT = 0x80410102; +constexpr int ORBIS_NET_ERROR_ESRCH = 0x80410103; +constexpr int ORBIS_NET_ERROR_EINTR = 0x80410104; +constexpr int ORBIS_NET_ERROR_EIO = 0x80410105; +constexpr int ORBIS_NET_ERROR_ENXIO = 0x80410106; +constexpr int ORBIS_NET_ERROR_E2BIG = 0x80410107; +constexpr int ORBIS_NET_ERROR_ENOEXEC = 0x80410108; +constexpr int ORBIS_NET_ERROR_EBADF = 0x80410109; +constexpr int ORBIS_NET_ERROR_ECHILD = 0x8041010A; +constexpr int ORBIS_NET_ERROR_EDEADLK = 0x8041010B; +constexpr int ORBIS_NET_ERROR_ENOMEM = 0x8041010C; +constexpr int ORBIS_NET_ERROR_EACCES = 0x8041010D; +constexpr int ORBIS_NET_ERROR_EFAULT = 0x8041010E; +constexpr int ORBIS_NET_ERROR_ENOTBLK = 0x8041010F; +constexpr int ORBIS_NET_ERROR_EBUSY = 0x80410110; +constexpr int ORBIS_NET_ERROR_EEXIST = 0x80410111; +constexpr int ORBIS_NET_ERROR_EXDEV = 0x80410112; +constexpr int ORBIS_NET_ERROR_ENODEV = 0x80410113; +constexpr int ORBIS_NET_ERROR_ENOTDIR = 0x80410114; +constexpr int ORBIS_NET_ERROR_EISDIR = 0x80410115; +constexpr int ORBIS_NET_ERROR_EINVAL = 0x80410116; +constexpr int ORBIS_NET_ERROR_ENFILE = 0x80410117; +constexpr int ORBIS_NET_ERROR_EMFILE = 0x80410118; +constexpr int ORBIS_NET_ERROR_ENOTTY = 0x80410119; +constexpr int ORBIS_NET_ERROR_ETXTBSY = 0x8041011A; +constexpr int ORBIS_NET_ERROR_EFBIG = 0x8041011B; +constexpr int ORBIS_NET_ERROR_ENOSPC = 0x8041011C; +constexpr int ORBIS_NET_ERROR_ESPIPE = 0x8041011D; +constexpr int ORBIS_NET_ERROR_EROFS = 0x8041011E; +constexpr int ORBIS_NET_ERROR_EMLINK = 0x8041011F; +constexpr int ORBIS_NET_ERROR_EPIPE = 0x80410120; +constexpr int ORBIS_NET_ERROR_EDOM = 0x80410121; +constexpr int ORBIS_NET_ERROR_ERANGE = 0x80410122; +constexpr int ORBIS_NET_ERROR_EAGAIN = 0x80410123; +constexpr int ORBIS_NET_ERROR_EWOULDBLOCK = 0x80410123; +constexpr int ORBIS_NET_ERROR_EINPROGRESS = 0x80410124; +constexpr int ORBIS_NET_ERROR_EALREADY = 0x80410125; +constexpr int ORBIS_NET_ERROR_ENOTSOCK = 0x80410126; +constexpr int ORBIS_NET_ERROR_EDESTADDRREQ = 0x80410127; +constexpr int ORBIS_NET_ERROR_EMSGSIZE = 0x80410128; +constexpr int ORBIS_NET_ERROR_EPROTOTYPE = 0x80410129; +constexpr int ORBIS_NET_ERROR_ENOPROTOOPT = 0x8041012A; +constexpr int ORBIS_NET_ERROR_EPROTONOSUPPORT = 0x8041012B; +constexpr int ORBIS_NET_ERROR_ESOCKTNOSUPPORT = 0x8041012C; +constexpr int ORBIS_NET_ERROR_EOPNOTSUPP = 0x8041012D; +constexpr int ORBIS_NET_ERROR_ENOTSUP = 0x8041012D; +constexpr int ORBIS_NET_ERROR_EPFNOSUPPORT = 0x8041012E; +constexpr int ORBIS_NET_ERROR_EAFNOSUPPORT = 0x8041012F; +constexpr int ORBIS_NET_ERROR_EADDRINUSE = 0x80410130; +constexpr int ORBIS_NET_ERROR_EADDRNOTAVAIL = 0x80410131; +constexpr int ORBIS_NET_ERROR_ENETDOWN = 0x80410132; +constexpr int ORBIS_NET_ERROR_ENETUNREACH = 0x80410133; +constexpr int ORBIS_NET_ERROR_ENETRESET = 0x80410134; +constexpr int ORBIS_NET_ERROR_ECONNABORTED = 0x80410135; +constexpr int ORBIS_NET_ERROR_ECONNRESET = 0x80410136; +constexpr int ORBIS_NET_ERROR_ENOBUFS = 0x80410137; +constexpr int ORBIS_NET_ERROR_EISCONN = 0x80410138; +constexpr int ORBIS_NET_ERROR_ENOTCONN = 0x80410139; +constexpr int ORBIS_NET_ERROR_ESHUTDOWN = 0x8041013A; +constexpr int ORBIS_NET_ERROR_ETOOMANYREFS = 0x8041013B; +constexpr int ORBIS_NET_ERROR_ETIMEDOUT = 0x8041013C; +constexpr int ORBIS_NET_ERROR_ECONNREFUSED = 0x8041013D; +constexpr int ORBIS_NET_ERROR_ELOOP = 0x8041013E; +constexpr int ORBIS_NET_ERROR_ENAMETOOLONG = 0x8041013F; +constexpr int ORBIS_NET_ERROR_EHOSTDOWN = 0x80410140; +constexpr int ORBIS_NET_ERROR_EHOSTUNREACH = 0x80410141; +constexpr int ORBIS_NET_ERROR_ENOTEMPTY = 0x80410142; +constexpr int ORBIS_NET_ERROR_EPROCLIM = 0x80410143; +constexpr int ORBIS_NET_ERROR_EUSERS = 0x80410144; +constexpr int ORBIS_NET_ERROR_EDQUOT = 0x80410145; +constexpr int ORBIS_NET_ERROR_ESTALE = 0x80410146; +constexpr int ORBIS_NET_ERROR_EREMOTE = 0x80410147; +constexpr int ORBIS_NET_ERROR_EBADRPC = 0x80410148; +constexpr int ORBIS_NET_ERROR_ERPCMISMATCH = 0x80410149; +constexpr int ORBIS_NET_ERROR_EPROGUNAVAIL = 0x8041014A; +constexpr int ORBIS_NET_ERROR_EPROGMISMATCH = 0x8041014B; +constexpr int ORBIS_NET_ERROR_EPROCUNAVAIL = 0x8041014C; +constexpr int ORBIS_NET_ERROR_ENOLCK = 0x8041014D; +constexpr int ORBIS_NET_ERROR_ENOSYS = 0x8041014E; +constexpr int ORBIS_NET_ERROR_EFTYPE = 0x8041014F; +constexpr int ORBIS_NET_ERROR_EAUTH = 0x80410150; +constexpr int ORBIS_NET_ERROR_ENEEDAUTH = 0x80410151; +constexpr int ORBIS_NET_ERROR_EIDRM = 0x80410152; +constexpr int ORBIS_NET_ERROR_ENOMS = 0x80410153; +constexpr int ORBIS_NET_ERROR_EOVERFLOW = 0x80410154; +constexpr int ORBIS_NET_ERROR_ECANCELED = 0x80410155; +constexpr int ORBIS_NET_ERROR_EPROTO = 0x8041015C; +constexpr int ORBIS_NET_ERROR_EADHOC = 0x804101A0; +constexpr int ORBIS_NET_ERROR_ERESERVED161 = 0x804101A1; +constexpr int ORBIS_NET_ERROR_ERESERVED162 = 0x804101A2; +constexpr int ORBIS_NET_ERROR_EINACTIVEDISABLED = 0x804101A3; +constexpr int ORBIS_NET_ERROR_ENODATA = 0x804101A4; +constexpr int ORBIS_NET_ERROR_EDESC = 0x804101A5; +constexpr int ORBIS_NET_ERROR_EDESCTIMEDOUT = 0x804101A6; +constexpr int ORBIS_NET_ERROR_ENETINTR = 0x804101A7; +constexpr int ORBIS_NET_ERROR_ENOTINIT = 0x804101C8; +constexpr int ORBIS_NET_ERROR_ENOLIBMEM = 0x804101C9; +constexpr int ORBIS_NET_ERROR_ERESERVED202 = 0x804101CA; +constexpr int ORBIS_NET_ERROR_ECALLBACK = 0x804101CB; +constexpr int ORBIS_NET_ERROR_EINTERNAL = 0x804101CC; +constexpr int ORBIS_NET_ERROR_ERETURN = 0x804101CD; +constexpr int ORBIS_NET_ERROR_ENOALLOCMEM = 0x804101CE; +constexpr int ORBIS_NET_ERROR_RESOLVER_EINTERNAL = 0x804101DC; +constexpr int ORBIS_NET_ERROR_RESOLVER_EBUSY = 0x804101DD; +constexpr int ORBIS_NET_ERROR_RESOLVER_ENOSPACE = 0x804101DE; +constexpr int ORBIS_NET_ERROR_RESOLVER_EPACKET = 0x804101DF; +constexpr int ORBIS_NET_ERROR_RESOLVER_ERESERVED224 = 0x804101E0; +constexpr int ORBIS_NET_ERROR_RESOLVER_ENODNS = 0x804101E1; +constexpr int ORBIS_NET_ERROR_RESOLVER_ETIMEDOUT = 0x804101E2; +constexpr int ORBIS_NET_ERROR_RESOLVER_ENOSUPPORT = 0x804101E3; +constexpr int ORBIS_NET_ERROR_RESOLVER_EFORMAT = 0x804101E4; +constexpr int ORBIS_NET_ERROR_RESOLVER_ESERVERFAILURE = 0x804101E5; +constexpr int ORBIS_NET_ERROR_RESOLVER_ENOHOST = 0x804101E6; +constexpr int ORBIS_NET_ERROR_RESOLVER_ENOTIMPLEMENTED = 0x804101E7; +constexpr int ORBIS_NET_ERROR_RESOLVER_ESERVERREFUSED = 0x804101E8; +constexpr int ORBIS_NET_ERROR_RESOLVER_ENORECORD = 0x804101E9; +constexpr int ORBIS_NET_ERROR_RESOLVER_EALIGNMENT = 0x804101EA; + +constexpr int ORBIS_NET_EPERM = 1; +constexpr int ORBIS_NET_ENOENT = 2; +constexpr int ORBIS_NET_ESRCH = 3; +constexpr int ORBIS_NET_EINTR = 4; +constexpr int ORBIS_NET_EIO = 5; +constexpr int ORBIS_NET_ENXIO = 6; +constexpr int ORBIS_NET_E2BIG = 7; +constexpr int ORBIS_NET_ENOEXEC = 8; +constexpr int ORBIS_NET_EBADF = 9; +constexpr int ORBIS_NET_ECHILD = 10; +constexpr int ORBIS_NET_EDEADLK = 11; +constexpr int ORBIS_NET_ENOMEM = 12; +constexpr int ORBIS_NET_EACCES = 13; +constexpr int ORBIS_NET_EFAULT = 14; +constexpr int ORBIS_NET_ENOTBLK = 15; +constexpr int ORBIS_NET_EBUSY = 16; +constexpr int ORBIS_NET_EEXIST = 17; +constexpr int ORBIS_NET_EXDEV = 18; +constexpr int ORBIS_NET_ENODEV = 19; +constexpr int ORBIS_NET_ENOTDIR = 20; +constexpr int ORBIS_NET_EISDIR = 21; +constexpr int ORBIS_NET_EINVAL = 22; +constexpr int ORBIS_NET_ENFILE = 23; +constexpr int ORBIS_NET_EMFILE = 24; +constexpr int ORBIS_NET_ENOTTY = 25; +constexpr int ORBIS_NET_ETXTBSY = 26; +constexpr int ORBIS_NET_EFBIG = 27; +constexpr int ORBIS_NET_ENOSPC = 28; +constexpr int ORBIS_NET_ESPIPE = 29; +constexpr int ORBIS_NET_EROFS = 30; +constexpr int ORBIS_NET_EMLINK = 31; +constexpr int ORBIS_NET_EPIPE = 32; +constexpr int ORBIS_NET_EDOM = 33; +constexpr int ORBIS_NET_ERANGE = 34; +constexpr int ORBIS_NET_EAGAIN = 35; +constexpr int ORBIS_NET_EWOULDBLOCK = ORBIS_NET_EAGAIN; +constexpr int ORBIS_NET_EINPROGRESS = 36; +constexpr int ORBIS_NET_EALREADY = 37; +constexpr int ORBIS_NET_ENOTSOCK = 38; +constexpr int ORBIS_NET_EDESTADDRREQ = 39; +constexpr int ORBIS_NET_EMSGSIZE = 40; +constexpr int ORBIS_NET_EPROTOTYPE = 41; +constexpr int ORBIS_NET_ENOPROTOOPT = 42; +constexpr int ORBIS_NET_EPROTONOSUPPORT = 43; +constexpr int ORBIS_NET_ESOCKTNOSUPPORT = 44; +constexpr int ORBIS_NET_EOPNOTSUPP = 45; +constexpr int ORBIS_NET_ENOTSUP = ORBIS_NET_EOPNOTSUPP; +constexpr int ORBIS_NET_EPFNOSUPPORT = 46; +constexpr int ORBIS_NET_EAFNOSUPPORT = 47; +constexpr int ORBIS_NET_EADDRINUSE = 48; +constexpr int ORBIS_NET_EADDRNOTAVAIL = 49; +constexpr int ORBIS_NET_ENETDOWN = 50; +constexpr int ORBIS_NET_ENETUNREACH = 51; +constexpr int ORBIS_NET_ENETRESET = 52; +constexpr int ORBIS_NET_ECONNABORTED = 53; +constexpr int ORBIS_NET_ECONNRESET = 54; +constexpr int ORBIS_NET_ENOBUFS = 55; +constexpr int ORBIS_NET_EISCONN = 56; +constexpr int ORBIS_NET_ENOTCONN = 57; +constexpr int ORBIS_NET_ESHUTDOWN = 58; +constexpr int ORBIS_NET_ETOOMANYREFS = 59; +constexpr int ORBIS_NET_ETIMEDOUT = 60; +constexpr int ORBIS_NET_ECONNREFUSED = 61; +constexpr int ORBIS_NET_ELOOP = 62; +constexpr int ORBIS_NET_ENAMETOOLONG = 63; +constexpr int ORBIS_NET_EHOSTDOWN = 64; +constexpr int ORBIS_NET_EHOSTUNREACH = 65; +constexpr int ORBIS_NET_ENOTEMPTY = 66; +constexpr int ORBIS_NET_EPROCLIM = 67; +constexpr int ORBIS_NET_EUSERS = 68; +constexpr int ORBIS_NET_EDQUOT = 69; +constexpr int ORBIS_NET_ESTALE = 70; +constexpr int ORBIS_NET_EREMOTE = 71; +constexpr int ORBIS_NET_EBADRPC = 72; +constexpr int ORBIS_NET_ERPCMISMATCH = 73; +constexpr int ORBIS_NET_EPROGUNAVAIL = 74; +constexpr int ORBIS_NET_EPROGMISMATCH = 75; +constexpr int ORBIS_NET_EPROCUNAVAIL = 76; +constexpr int ORBIS_NET_ENOLCK = 77; +constexpr int ORBIS_NET_ENOSYS = 78; +constexpr int ORBIS_NET_EFTYPE = 79; +constexpr int ORBIS_NET_EAUTH = 80; +constexpr int ORBIS_NET_ENEEDAUTH = 81; +constexpr int ORBIS_NET_EIDRM = 82; +constexpr int ORBIS_NET_ENOMSG = 83; +constexpr int ORBIS_NET_EOVERFLOW = 84; +constexpr int ORBIS_NET_ECANCELED = 85; +constexpr int ORBIS_NET_EPROTO = 92; +constexpr int ORBIS_NET_EADHOC = 160; +constexpr int ORBIS_NET_ERESERVED161 = 161; +constexpr int ORBIS_NET_ERESERVED162 = 162; +constexpr int ORBIS_NET_EINACTIVEDISABLED = 163; +constexpr int ORBIS_NET_ENODATA = 164; +constexpr int ORBIS_NET_EDESC = 165; +constexpr int ORBIS_NET_EDESCTIMEDOUT = 166; +constexpr int ORBIS_NET_ENETINTR = 167; + +/* libnet */ +constexpr int ORBIS_NET_ENOTINIT = 200; +constexpr int ORBIS_NET_ENOLIBMEM = 201; +constexpr int ORBIS_NET_ETLS = 202; +constexpr int ORBIS_NET_ECALLBACK = 203; +constexpr int ORBIS_NET_EINTERNAL = 204; +constexpr int ORBIS_NET_ERETURN = 205; +constexpr int ORBIS_NET_ENOALLOCMEM = 206; + +/* resolver */ +constexpr int SCE_NET_RESOLVER_EINTERNAL = 220; +constexpr int SCE_NET_RESOLVER_EBUSY = 221; +constexpr int SCE_NET_RESOLVER_ENOSPACE = 222; +constexpr int SCE_NET_RESOLVER_EPACKET = 223; +constexpr int SCE_NET_RESOLVER_ERESERVED224 = 224; +constexpr int SCE_NET_RESOLVER_ENODNS = 225; +constexpr int SCE_NET_RESOLVER_ETIMEDOUT = 226; +constexpr int SCE_NET_RESOLVER_ENOSUPPORT = 227; +constexpr int SCE_NET_RESOLVER_EFORMAT = 228; +constexpr int SCE_NET_RESOLVER_ESERVERFAILURE = 229; +constexpr int SCE_NET_RESOLVER_ENOHOST = 230; +constexpr int SCE_NET_RESOLVER_ENOTIMPLEMENTED = 231; +constexpr int SCE_NET_RESOLVER_ESERVERREFUSED = 232; +constexpr int SCE_NET_RESOLVER_ENORECORD = 233; +constexpr int SCE_NET_RESOLVER_EALIGNMENT = 234; \ No newline at end of file diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 161fc521476..2b07ee1dfd3 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -1,6 +1,20 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/thread_management.h" +#include "core/libraries/libs.h" +#include "core/libraries/network/net.h" +#include "error_codes.h" + +#include + +#include +#include +#include + #ifdef WIN32 #define _WINSOCK_DEPRECATED_NO_WARNINGS #include @@ -10,57 +24,525 @@ #include #endif -#include "common/assert.h" -#include "common/logging/log.h" -#include "core/libraries/error_codes.h" -#include "core/libraries/libs.h" -#include "core/libraries/network/net.h" - namespace Libraries::Net { -static thread_local int32_t net_errno = 0; +#define orbis_net_errno (*sceNetErrnoLoc()) + +#ifdef WIN32 + +struct SocketInternal {}; + +using Index = OrbisNetId; +using T = SocketInternal; +static Index MaxIndex = std::numeric_limits::max(); + +// template +class IndexedResources { + IndexedResources() { + m_free_indices += boost::icl::interval::closed(0, MaxIndex); + } + + T& Create() { + std::unique_lock lock{m_mutex}; + auto index = first(*m_free_indices.begin()); + m_free_indices -= index; + return m_container[index]; + } + + void Destroy(Index index) { + std::unique_lock lock{m_mutex}; + m_container.erase(index); + m_free_indices += index; + } + + std::optional> Get(Index index) { + std::shared_lock lock{m_mutex}; + auto it = m_container.find(index); + if (it == m_container.end()) { + return {}; + } + return it->second; + } + +private: + std::shared_mutex m_mutex; + std::unordered_map m_container; + boost::icl::interval_set m_free_indices; +}; + +// static IndexedResources::max()> +// g_index_manager; +#endif + +struct OrbisNetSync { + int Init(s32 init, const char* name) { + mutex = nullptr; + auto res = Kernel::scePthreadMutexInit(&mutex, nullptr, name); + if (res < 0) { + return res; + } + cond = nullptr; + res = Kernel::scePthreadCondInit(&cond, nullptr, name); + if (res < 0) { + Kernel::scePthreadMutexDestroy(&mutex); + return res; + } + this->init = init; + return 0; + } + + ~OrbisNetSync() { + init = false; + if (cond != nullptr) { + Kernel::scePthreadCondDestroy(&cond); + } + if (mutex != nullptr) { + Kernel::scePthreadMutexDestroy(&mutex); + } + } + + Kernel::ScePthreadMutex mutex = nullptr; + Kernel::ScePthreadCond cond = nullptr; + s32 init = 0; +}; + +struct OrbisNetGlobalState { + OrbisNetGlobalState() { + Init(); + } + + int Init() { + if (is_initialized) { + return 0; + } + auto res = dhcp_sync.Init(1, "LibnetSync"); + if (res < 0) { + return res; + } + res = dhcp_sync.Init(1, "DhcpSync"); + if (res < 0) { + return res; + } + res = dhcpd_sync.Init(1, "DhcpdSync"); + if (res < 0) { + return res; + } + res = dup_ip_det_sync.Init(1, "DupIpDetSync"); + if (res < 0) { + return res; + } + res = net_addrconfig6_sync.Init(1, "Addrconfig6Sync"); + if (res < 0) { + return res; + } + res = info_sync.Init(1, "InfoSync"); + if (res < 0) { + return res; + } + // FUN_01009640((GlobalState *)&DAT_0104c1e8,(unk1 *)&DAT_0103c108,0x10000,0); + is_initialized = true; + return 0; + } + + bool is_initialized = false; + + OrbisNetSync libnet_sync; + OrbisNetSync dhcp_sync; + OrbisNetSync dhcpd_sync; + OrbisNetSync dup_ip_det_sync; + OrbisNetSync net_addrconfig6_sync; + OrbisNetSync info_sync; + + OrbisNetSync mem_sync; +}; + +// static OrbisNetGlobalState g_net_state; + +#ifdef WIN32 +WSADATA Init() { + WSADATA data{}; + WSAStartup(MAKEWORD(2, 2), &data); + return data; +} + +static WSADATA wsaData = Init(); +#else +#define INVALID_SOCKET -1 +#endif + +#ifndef WIN32 +#define POSIX_ERRNO_CASES \ + CASE(EPERM) \ + CASE(ENOENT) \ + CASE(ESRCH) \ + CASE(EIO) \ + CASE(ENXIO) \ + CASE(E2BIG) \ + CASE(ENOEXEC) \ + CASE(EDEADLK) \ + CASE(ENOMEM) \ + CASE(ECHILD) \ + CASE(EBUSY) \ + CASE(EEXIST) \ + CASE(EXDEV) \ + CASE(ENODEV) \ + CASE(ENOTDIR) \ + CASE(EISDIR) \ + CASE(ENFILE) \ + CASE(ENOTTY) \ + CASE(ETXTBSY) \ + CASE(EFBIG) \ + CASE(ENOSPC) \ + CASE(ESPIPE) \ + CASE(EROFS) \ + CASE(EMLINK) \ + CASE(EPIPE) \ + CASE(EDOM) \ + CASE(ERANGE) \ + CASE(ENOLCK) \ + CASE(ENOSYS) \ + CASE(EIDRM) \ + CASE(EOVERFLOW) \ + CASE(EILSEQ) \ + CASE(ENOTSUP) \ + CASE(ECANCELED) \ + CASE(EBADMSG) \ + CASE(ENODATA) \ + CASE(ENOSR) \ + CASE(ENOSTR) \ + CASE(ETIME) +#else +#define POSIX_ERRNO_CASES +#endif + +#if defined(__APPLE__) || defined(WIN32) +#define APPLE_WIN32_ERRNO_CASES CASE(EOPNOTSUPP) +#else +#define APPLE_WIN32_ERRNO_CASES +#endif + +#define ERRNO_CASES \ + POSIX_ERRNO_CASES \ + APPLE_WIN32_ERRNO_CASES \ + CASE(EINTR) \ + CASE(EBADF) \ + CASE(EACCES) \ + CASE(EFAULT) \ + CASE(EINVAL) \ + CASE(EMFILE) \ + CASE(EWOULDBLOCK) \ + CASE(EINPROGRESS) \ + CASE(EALREADY) \ + CASE(ENOTSOCK) \ + CASE(EDESTADDRREQ) \ + CASE(EMSGSIZE) \ + CASE(EPROTOTYPE) \ + CASE(ENOPROTOOPT) \ + CASE(EPROTONOSUPPORT) \ + CASE(EAFNOSUPPORT) \ + CASE(EADDRINUSE) \ + CASE(EADDRNOTAVAIL) \ + CASE(ENETDOWN) \ + CASE(ENETUNREACH) \ + CASE(ENETRESET) \ + CASE(ECONNABORTED) \ + CASE(ECONNRESET) \ + CASE(ENOBUFS) \ + CASE(EISCONN) \ + CASE(ENOTCONN) \ + CASE(ETIMEDOUT) \ + CASE(ECONNREFUSED) \ + CASE(ELOOP) \ + CASE(ENAMETOOLONG) \ + CASE(EHOSTUNREACH) \ + CASE(ENOTEMPTY) + +#ifdef WIN32 +#define net_errno (WSAGetLastError()) +#else +#define net_errno errno +#endif + +static int ToOrbisNetError(int err) { + switch (err) { +#ifdef WIN32 +#define CASE(err) \ + case WSA##err: \ + return ORBIS_NET_ERROR_##err; +#else +#define CASE(err) \ + case (err): \ + return ORBIS_NET_ERROR_##err; +#endif + ERRNO_CASES +#undef CASE + default: + return ORBIS_NET_ERROR_EINTERNAL; + } +} + +static int ToOrbisNetErrno(int err) { + switch (err) { +#ifdef WIN32 +#define CASE(err) \ + case WSA##err: \ + return ORBIS_NET_##err; +#else +#define CASE(err) \ + case (err): \ + return ORBIS_NET_##err; +#endif + ERRNO_CASES +#undef CASE + default: + return ORBIS_NET_EINTERNAL; + } +} + +static void ToOrbisSockaddr(const sockaddr& src, OrbisNetSockaddr& dst) { + dst = OrbisNetSockaddr{}; + const auto& src_sin = reinterpret_cast(src); + auto& dst_sin = reinterpret_cast(dst); + dst_sin.sin_len = sizeof(OrbisNetSockaddrIn); + dst_sin.sin_family = src_sin.sin_family; + dst_sin.sin_port = src_sin.sin_port; + std::memcpy(&dst_sin.sin_addr, &src_sin.sin_addr, 4); +} + +static void FromOrbisSockaddr(const OrbisNetSockaddr& src, sockaddr& dst) { + auto& dst_sin = reinterpret_cast(dst); + const auto& src_sin = reinterpret_cast(src); + dst_sin.sin_family = src_sin.sin_family; + dst_sin.sin_port = src_sin.sin_port; + memcpy(&dst_sin.sin_addr, &src_sin.sin_addr, 4); +} + +static int NetError(int err) { + orbis_net_errno = ToOrbisNetErrno(err); + return ToOrbisNetError(err); +} + +OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* paddr, u32* paddrlen) { + LOG_TRACE(Lib_Net, "called, s = {}", s); + if (paddr == nullptr) { + return NetError(EINVAL); + } + sockaddr addr{}; + int addrlen = sizeof(sockaddr_in); + auto sock = accept(s, &addr, &addrlen); + if (sock == INVALID_SOCKET) { + return NetError(net_errno); + } + ToOrbisSockaddr(addr, *paddr); + *paddrlen = sizeof(OrbisNetSockaddrIn); + return sock; +} + +int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* paddr, u32 addrlen) { + LOG_TRACE(Lib_Net, "called, s = {}", s); + if (paddr == nullptr) { + return NetError(EINVAL); + } + sockaddr addr{}; + FromOrbisSockaddr(*paddr, addr); + const auto res = bind(s, &addr, sizeof(sockaddr_in)); + if (res < 0) { + return NetError(net_errno); + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNetConnect(OrbisNetId s, const OrbisNetSockaddr* paddr, u32 addrlen) { + LOG_TRACE(Lib_Net, "called, s = {}", s); + if (paddr == nullptr) { + return NetError(EINVAL); + } + sockaddr addr{}; + FromOrbisSockaddr(*paddr, addr); + const auto res = connect(s, &addr, sizeof(sockaddr_in)); + if (res < 0) { + return NetError(net_errno); + } + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNetGetpeername(OrbisNetId s, OrbisNetSockaddr* paddr, u32* paddrlen) { + LOG_TRACE(Lib_Net, "called, s = {}", s); + if (paddr == nullptr || paddrlen == nullptr) { + return NetError(EINVAL); + } + sockaddr addr{}; + int addrlen = sizeof(sockaddr_in); + const auto res = getpeername(s, &addr, &addrlen); + if (res < 0) { + return NetError(net_errno); + } + ToOrbisSockaddr(addr, *paddr); + *paddrlen = sizeof(OrbisNetSockaddrIn); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* paddr, u32* paddrlen) { + LOG_TRACE(Lib_Net, "called, s = {}", s); + if (paddr == nullptr || paddrlen == nullptr) { + return NetError(EINVAL); + } + sockaddr addr{}; + int addrlen = sizeof(sockaddr_in); + const auto res = getsockname(s, &addr, &addrlen); + if (res < 0) { + return NetError(net_errno); + } + ToOrbisSockaddr(addr, *paddr); + *paddrlen = sizeof(OrbisNetSockaddrIn); + return ORBIS_OK; +} + +#ifdef WIN32 +#ifndef SO_REUSEPORT +#define SO_REUSEPORT SO_REUSEADDR +#endif +#endif + +static int FromOrbisOptlevel(int level) { + switch (level) { +#define CASE(level) \ + case ORBIS_NET_##level: \ + return level + CASE(IPPROTO_IP); + CASE(IPPROTO_ICMP); + CASE(IPPROTO_IGMP); + CASE(IPPROTO_TCP); + CASE(IPPROTO_UDP); + CASE(SOL_SOCKET); + default: + UNREACHABLE_MSG("Unexpected optlevel"); + } +} + +int FromOrbisSocketOptname(int optname) { + switch (optname) { +#define CASE(name) \ + case ORBIS_NET_##name: \ + return name + CASE(SO_REUSEADDR); + CASE(SO_KEEPALIVE); + CASE(SO_BROADCAST); + CASE(SO_LINGER); + CASE(SO_REUSEPORT); + CASE(SO_SNDBUF); + CASE(SO_RCVBUF); + CASE(SO_ERROR); + CASE(SO_TYPE); + CASE(SO_SNDTIMEO); + CASE(SO_RCVTIMEO); +#undef CASE + // CASE(SO_ONESBCAST); + // CASE(SO_USECRYPTO); + // CASE(SO_USESIGNATURE); + // CASE(SO_ERROR_EX); + // CASE(SO_ACCEPTTIMEO); + // CASE(SO_CONNECTTIMEO); + // CASE(SO_NBIO); + // CASE(SO_POLICY); + // CASE(SO_NAME); + // CASE(SO_PRIORITY); + default: + LOG_ERROR(Lib_Net, "Unsupported socket optname 0x%08X", optname); + return -1; + } +} + +int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) { + LOG_ERROR(Lib_Net, "(STUBBED) called"); + switch (level) { + case ORBIS_NET_IPPROTO_IP: + case ORBIS_NET_IPPROTO_ICMP: + case ORBIS_NET_IPPROTO_IGMP: + case ORBIS_NET_IPPROTO_TCP: + case ORBIS_NET_IPPROTO_UDP: + case ORBIS_NET_SOL_SOCKET: { + switch (optname) { + case ORBIS_NET_SO_NBIO: { + DWORD ret; + WSAIoctl(s, FIONBIO, nullptr, 0, optval, *optlen, &ret, nullptr, nullptr); + break; + } + default: + break; + } + } + } + + optname = FromOrbisSocketOptname(optname); + if (optname < 0) { + // Can't do anything with those, just return OK + return ORBIS_OK; + } + level = FromOrbisOptlevel(level); + getsockopt(s, level, optname, reinterpret_cast(optval), reinterpret_cast(optlen)); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNetListen(OrbisNetId s, int backlog) { + LOG_ERROR(Lib_Net, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNetRecv(OrbisNetId s, void* buf, size_t len, int flags) { + LOG_ERROR(Lib_Net, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, + OrbisNetSockaddr* addr, u32* paddrlen) { + LOG_ERROR(Lib_Net, "(STUBBED) called"); + return ORBIS_OK; +} -int PS4_SYSV_ABI in6addr_any() { +int PS4_SYSV_ABI sceNetRecvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI in6addr_loopback() { +int PS4_SYSV_ABI sceNetSend(OrbisNetId s, const void* buf, size_t len, int flags) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sce_net_dummy() { +int PS4_SYSV_ABI sceNetSendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sce_net_in6addr_any() { +int PS4_SYSV_ABI sceNetSendto(OrbisNetId s, const void* buf, size_t len, int flags, + const OrbisNetSockaddr* addr, u32 addrlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sce_net_in6addr_linklocal_allnodes() { +int PS4_SYSV_ABI sceNetSetsockopt(OrbisNetId s, int level, int optname, const void* optval, + u32 optlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sce_net_in6addr_linklocal_allrouters() { +int PS4_SYSV_ABI sceNetShutdown(OrbisNetId s, int how) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sce_net_in6addr_loopback() { +int PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sce_net_in6addr_nodelocal_allnodes() { +int PS4_SYSV_ABI sceNetSocketAbort(OrbisNetId s, int flags) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) { +int PS4_SYSV_ABI sceNetSocketClose(OrbisNetId s) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } @@ -120,11 +602,6 @@ int PS4_SYSV_ABI sceNetBandwidthControlSetPolicy() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetClearDnsCache() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -465,11 +942,6 @@ int PS4_SYSV_ABI sceNetConfigWlanSetDeviceConfig() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetConnect() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetControl() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -565,9 +1037,10 @@ int PS4_SYSV_ABI sceNetEpollWait() { return ORBIS_OK; } +static thread_local int g_sce_net_errno; int* PS4_SYSV_ABI sceNetErrnoLoc() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return &net_errno; + LOG_TRACE(Lib_Net, "called"); + return &g_sce_net_errno; } int PS4_SYSV_ABI sceNetEtherNtostr() { @@ -655,11 +1128,6 @@ int PS4_SYSV_ABI sceNetGetNameToIndex() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetGetpeername() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetGetRandom() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -680,16 +1148,6 @@ int PS4_SYSV_ABI sceNetGetSockInfo6() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetGetStatisticsInfo() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -781,11 +1239,6 @@ int PS4_SYSV_ABI sceNetIoctl() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetListen() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetMemoryAllocate() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -829,22 +1282,6 @@ int PS4_SYSV_ABI sceNetPppoeStop() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetRecv() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, - OrbisNetSockaddr* addr, u32* paddrlen) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetRecvmsg() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetResolverAbort() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -915,21 +1352,6 @@ int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetSend() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetSendmsg() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetSendto() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetSetDns6Info() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -950,11 +1372,6 @@ int PS4_SYSV_ABI sceNetSetDnsInfoToKernel() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetSetsockopt() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetShowIfconfig() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -1035,26 +1452,6 @@ int PS4_SYSV_ABI sceNetShowRouteWithMemory() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetShutdown() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetSocketAbort() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - -int PS4_SYSV_ABI sceNetSocketClose() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; -} - int PS4_SYSV_ABI sceNetSyncCreate() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -1125,19 +1522,51 @@ int PS4_SYSV_ABI sceNetEmulationSet() { return ORBIS_OK; } +OrbisNetIn6Addr g_in6addr_any{.sin_addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; +OrbisNetIn6Addr g_in6addr_loopback{.sin_addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}; +OrbisNetIn6Addr g_in6addr_dummy{.sin_addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; +OrbisNetIn6Addr g_sce_net_in6addr_linklocal_allnodes{ + .sin_addr = {255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}; +OrbisNetIn6Addr g_sce_net_in6addr_linklocal_allrouters{ + .sin_addr = {255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}}; +OrbisNetIn6Addr g_sce_net_in6addr_any{.sin_addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; +OrbisNetIn6Addr g_sce_net_in6addr_loopback{ + .sin_addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}; +OrbisNetIn6Addr g_sce_net_in6addr_nodelocal_allnodes{ + .sin_addr = {255, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}; + void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { - LIB_FUNCTION("ZRAJo-A-ukc", "libSceNet", 1, "libSceNet", 1, 1, in6addr_any); - LIB_FUNCTION("XCuA-GqjA-k", "libSceNet", 1, "libSceNet", 1, 1, in6addr_loopback); - LIB_FUNCTION("VZgoeBxPXUQ", "libSceNet", 1, "libSceNet", 1, 1, sce_net_dummy); - LIB_FUNCTION("GAtITrgxKDE", "libSceNet", 1, "libSceNet", 1, 1, sce_net_in6addr_any); - LIB_FUNCTION("84MgU4MMTLQ", "libSceNet", 1, "libSceNet", 1, 1, - sce_net_in6addr_linklocal_allnodes); - LIB_FUNCTION("2uSWyOKYc1M", "libSceNet", 1, "libSceNet", 1, 1, - sce_net_in6addr_linklocal_allrouters); - LIB_FUNCTION("P3AeWBvPrkg", "libSceNet", 1, "libSceNet", 1, 1, sce_net_in6addr_loopback); - LIB_FUNCTION("PgNI+j4zxzM", "libSceNet", 1, "libSceNet", 1, 1, - sce_net_in6addr_nodelocal_allnodes); + LIB_OBJ("ZRAJo-A-ukc", "libSceNet", 1, "libSceNet", 1, 1, &g_in6addr_any); + LIB_OBJ("XCuA-GqjA-k", "libSceNet", 1, "libSceNet", 1, 1, &g_in6addr_loopback); + LIB_OBJ("VZgoeBxPXUQ", "libSceNet", 1, "libSceNet", 1, 1, &g_in6addr_dummy); + LIB_OBJ("GAtITrgxKDE", "libSceNet", 1, "libSceNet", 1, 1, &g_sce_net_in6addr_any); + LIB_OBJ("84MgU4MMTLQ", "libSceNet", 1, "libSceNet", 1, 1, + &g_sce_net_in6addr_linklocal_allnodes); + LIB_OBJ("2uSWyOKYc1M", "libSceNet", 1, "libSceNet", 1, 1, + &g_sce_net_in6addr_linklocal_allrouters); + LIB_OBJ("P3AeWBvPrkg", "libSceNet", 1, "libSceNet", 1, 1, &g_sce_net_in6addr_loopback); + LIB_OBJ("PgNI+j4zxzM", "libSceNet", 1, "libSceNet", 1, 1, + &g_sce_net_in6addr_nodelocal_allnodes); + LIB_FUNCTION("PIWqhn9oSxc", "libSceNet", 1, "libSceNet", 1, 1, sceNetAccept); + LIB_FUNCTION("bErx49PgxyY", "libSceNet", 1, "libSceNet", 1, 1, sceNetBind); + LIB_FUNCTION("OXXX4mUk3uk", "libSceNet", 1, "libSceNet", 1, 1, sceNetConnect); + LIB_FUNCTION("TCkRD0DWNLg", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetpeername); + LIB_FUNCTION("hoOAofhhRvE", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockname); + LIB_FUNCTION("xphrZusl78E", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockopt); + LIB_FUNCTION("kOj1HiAGE54", "libSceNet", 1, "libSceNet", 1, 1, sceNetListen); + LIB_FUNCTION("9wO9XrMsNhc", "libSceNet", 1, "libSceNet", 1, 1, sceNetRecv); + LIB_FUNCTION("304ooNZxWDY", "libSceNet", 1, "libSceNet", 1, 1, sceNetRecvfrom); + LIB_FUNCTION("wvuUDv0jrMI", "libSceNet", 1, "libSceNet", 1, 1, sceNetRecvmsg); + LIB_FUNCTION("beRjXBn-z+o", "libSceNet", 1, "libSceNet", 1, 1, sceNetSend); + LIB_FUNCTION("2eKbgcboJso", "libSceNet", 1, "libSceNet", 1, 1, sceNetSendmsg); + LIB_FUNCTION("gvD1greCu0A", "libSceNet", 1, "libSceNet", 1, 1, sceNetSendto); + LIB_FUNCTION("2mKX2Spso7I", "libSceNet", 1, "libSceNet", 1, 1, sceNetSetsockopt); + LIB_FUNCTION("TSM6whtekok", "libSceNet", 1, "libSceNet", 1, 1, sceNetShutdown); + LIB_FUNCTION("Q4qBuN-c0ZM", "libSceNet", 1, "libSceNet", 1, 1, sceNetSocket); + LIB_FUNCTION("zJGf8xjFnQE", "libSceNet", 1, "libSceNet", 1, 1, sceNetSocketAbort); + LIB_FUNCTION("45ggEzakPJQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetSocketClose); + LIB_FUNCTION("BTUvkWzrP68", "libSceNet", 1, "libSceNet", 1, 1, sceNetAddrConfig6GetInfo); LIB_FUNCTION("3qG7UJy2Fq8", "libSceNet", 1, "libSceNet", 1, 1, sceNetAddrConfig6Start); LIB_FUNCTION("P+0ePpDfUAQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetAddrConfig6Stop); @@ -1154,7 +1583,6 @@ void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("g4DKkzV2qC4", "libSceNet", 1, "libSceNet", 1, 1, sceNetBandwidthControlSetIfParam); LIB_FUNCTION("7Z1hhsEmkQU", "libSceNet", 1, "libSceNet", 1, 1, sceNetBandwidthControlSetPolicy); - LIB_FUNCTION("bErx49PgxyY", "libSceNet", 1, "libSceNet", 1, 1, sceNetBind); LIB_FUNCTION("eyLyLJrdEOU", "libSceNet", 1, "libSceNet", 1, 1, sceNetClearDnsCache); LIB_FUNCTION("Ea2NaVMQNO8", "libSceNet", 1, "libSceNet", 1, 1, sceNetConfigAddArp); LIB_FUNCTION("0g0qIuPN3ZQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetConfigAddArpWithInterface); @@ -1241,7 +1669,6 @@ void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("273-I-zD8+8", "libSceNet", 1, "libSceNet", 1, 1, sceNetConfigWlanInfraScanJoin); LIB_FUNCTION("-Mi5hNiWC4c", "libSceNet", 1, "libSceNet", 1, 1, sceNetConfigWlanScan); LIB_FUNCTION("U1q6DrPbY6k", "libSceNet", 1, "libSceNet", 1, 1, sceNetConfigWlanSetDeviceConfig); - LIB_FUNCTION("OXXX4mUk3uk", "libSceNet", 1, "libSceNet", 1, 1, sceNetConnect); LIB_FUNCTION("lDTIbqNs0ps", "libSceNet", 1, "libSceNet", 1, 1, sceNetControl); LIB_FUNCTION("Q6T-zIblNqk", "libSceNet", 1, "libSceNet", 1, 1, sceNetDhcpdStart); LIB_FUNCTION("xwWm8jzrpeM", "libSceNet", 1, "libSceNet", 1, 1, sceNetDhcpdStop); @@ -1279,13 +1706,10 @@ void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("6Oc0bLsIYe0", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetMacAddress); LIB_FUNCTION("rMyh97BU5pY", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetMemoryPoolStats); LIB_FUNCTION("+S-2-jlpaBo", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetNameToIndex); - LIB_FUNCTION("TCkRD0DWNLg", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetpeername); LIB_FUNCTION("G3O2j9f5z00", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetRandom); LIB_FUNCTION("6Nx1hIQL9h8", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetRouteInfo); LIB_FUNCTION("hLuXdjHnhiI", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSockInfo); LIB_FUNCTION("Cidi9Y65mP8", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSockInfo6); - LIB_FUNCTION("hoOAofhhRvE", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockname); - LIB_FUNCTION("xphrZusl78E", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetsockopt); LIB_FUNCTION("GA5ZDaLtUBE", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetStatisticsInfo); LIB_FUNCTION("9mIcUExH34w", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetStatisticsInfoInternal); LIB_FUNCTION("p2vxsE2U3RQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetGetSystemTime); @@ -1302,7 +1726,6 @@ void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("Nlev7Lg8k3A", "libSceNet", 1, "libSceNet", 1, 1, sceNetInit); LIB_FUNCTION("6MojQ8uFHEI", "libSceNet", 1, "libSceNet", 1, 1, sceNetInitParam); LIB_FUNCTION("ghqRRVQxqKo", "libSceNet", 1, "libSceNet", 1, 1, sceNetIoctl); - LIB_FUNCTION("kOj1HiAGE54", "libSceNet", 1, "libSceNet", 1, 1, sceNetListen); LIB_FUNCTION("HKIa-WH0AZ4", "libSceNet", 1, "libSceNet", 1, 1, sceNetMemoryAllocate); LIB_FUNCTION("221fvqVs+sQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetMemoryFree); LIB_FUNCTION("pQGpHYopAIY", "libSceNet", 1, "libSceNet", 1, 1, sceNetNtohl); @@ -1312,9 +1735,6 @@ void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("K7RlrTkI-mw", "libSceNet", 1, "libSceNet", 1, 1, sceNetPoolDestroy); LIB_FUNCTION("QGOqGPnk5a4", "libSceNet", 1, "libSceNet", 1, 1, sceNetPppoeStart); LIB_FUNCTION("FIV95WE1EuE", "libSceNet", 1, "libSceNet", 1, 1, sceNetPppoeStop); - LIB_FUNCTION("9wO9XrMsNhc", "libSceNet", 1, "libSceNet", 1, 1, sceNetRecv); - LIB_FUNCTION("304ooNZxWDY", "libSceNet", 1, "libSceNet", 1, 1, sceNetRecvfrom); - LIB_FUNCTION("wvuUDv0jrMI", "libSceNet", 1, "libSceNet", 1, 1, sceNetRecvmsg); LIB_FUNCTION("AzqoBha7js4", "libSceNet", 1, "libSceNet", 1, 1, sceNetResolverAbort); LIB_FUNCTION("JQk8ck8vnPY", "libSceNet", 1, "libSceNet", 1, 1, sceNetResolverConnect); LIB_FUNCTION("bonnMiDoOZg", "libSceNet", 1, "libSceNet", 1, 1, sceNetResolverConnectAbort); @@ -1331,14 +1751,10 @@ void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { sceNetResolverStartNtoaMultipleRecords); LIB_FUNCTION("sT4nBQKUPqM", "libSceNet", 1, "libSceNet", 1, 1, sceNetResolverStartNtoaMultipleRecordsEx); - LIB_FUNCTION("beRjXBn-z+o", "libSceNet", 1, "libSceNet", 1, 1, sceNetSend); - LIB_FUNCTION("2eKbgcboJso", "libSceNet", 1, "libSceNet", 1, 1, sceNetSendmsg); - LIB_FUNCTION("gvD1greCu0A", "libSceNet", 1, "libSceNet", 1, 1, sceNetSendto); LIB_FUNCTION("15Ywg-ZsSl0", "libSceNet", 1, "libSceNet", 1, 1, sceNetSetDns6Info); LIB_FUNCTION("E3oH1qsdqCA", "libSceNet", 1, "libSceNet", 1, 1, sceNetSetDns6InfoToKernel); LIB_FUNCTION("B-M6KjO8-+w", "libSceNet", 1, "libSceNet", 1, 1, sceNetSetDnsInfo); LIB_FUNCTION("8s+T0bJeyLQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetSetDnsInfoToKernel); - LIB_FUNCTION("2mKX2Spso7I", "libSceNet", 1, "libSceNet", 1, 1, sceNetSetsockopt); LIB_FUNCTION("k1V1djYpk7k", "libSceNet", 1, "libSceNet", 1, 1, sceNetShowIfconfig); LIB_FUNCTION("j6pkkO2zJtg", "libSceNet", 1, "libSceNet", 1, 1, sceNetShowIfconfigForBuffer); LIB_FUNCTION("E8dTcvQw3hg", "libSceNet", 1, "libSceNet", 1, 1, sceNetShowIfconfigWithMemory); @@ -1355,10 +1771,6 @@ void RegisterlibSceNet(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("TCZyE2YI1uM", "libSceNet", 1, "libSceNet", 1, 1, sceNetShowRoute6WithMemory); LIB_FUNCTION("n-IAZb7QB1Y", "libSceNet", 1, "libSceNet", 1, 1, sceNetShowRouteForBuffer); LIB_FUNCTION("0-XSSp1kEFM", "libSceNet", 1, "libSceNet", 1, 1, sceNetShowRouteWithMemory); - LIB_FUNCTION("TSM6whtekok", "libSceNet", 1, "libSceNet", 1, 1, sceNetShutdown); - LIB_FUNCTION("Q4qBuN-c0ZM", "libSceNet", 1, "libSceNet", 1, 1, sceNetSocket); - LIB_FUNCTION("zJGf8xjFnQE", "libSceNet", 1, "libSceNet", 1, 1, sceNetSocketAbort); - LIB_FUNCTION("45ggEzakPJQ", "libSceNet", 1, "libSceNet", 1, 1, sceNetSocketClose); LIB_FUNCTION("6AJE2jKg-c0", "libSceNet", 1, "libSceNet", 1, 1, sceNetSyncCreate); LIB_FUNCTION("atGfzCaXMak", "libSceNet", 1, "libSceNet", 1, 1, sceNetSyncDestroy); LIB_FUNCTION("sAleh-BoxLA", "libSceNet", 1, "libSceNet", 1, 1, sceNetSyncGet); diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index beef38b5619..f1e5b70a452 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -9,6 +9,38 @@ namespace Core::Loader { class SymbolsResolver; } +constexpr int ORBIS_NET_IPPROTO_IP = 0x0000; +constexpr int ORBIS_NET_IPPROTO_ICMP = 0x0001; +constexpr int ORBIS_NET_IPPROTO_IGMP = 0x0002; +constexpr int ORBIS_NET_IPPROTO_TCP = 0x0006; +constexpr int ORBIS_NET_IPPROTO_UDP = 0x0011; +constexpr int ORBIS_NET_SOL_SOCKET = 0xffff; + +constexpr int ORBIS_NET_SO_REUSEADDR = 0x00000004; +constexpr int ORBIS_NET_SO_KEEPALIVE = 0x00000008; +constexpr int ORBIS_NET_SO_BROADCAST = 0x00000020; +constexpr int ORBIS_NET_SO_LINGER = 0x00000080; +constexpr int ORBIS_NET_SO_REUSEPORT = 0x00000200; +constexpr int ORBIS_NET_SO_ONESBCAST = 0x00010000; +constexpr int ORBIS_NET_SO_USECRYPTO = 0x00020000; +constexpr int ORBIS_NET_SO_USESIGNATURE = 0x00040000; + +constexpr int ORBIS_NET_SO_SNDBUF = 0x1001; +constexpr int ORBIS_NET_SO_RCVBUF = 0x1002; +constexpr int ORBIS_NET_SO_ERROR = 0x1007; +constexpr int ORBIS_NET_SO_TYPE = 0x1008; + +constexpr int ORBIS_NET_SO_SNDTIMEO = 0x1105; +constexpr int ORBIS_NET_SO_RCVTIMEO = 0x1106; +constexpr int ORBIS_NET_SO_ERROR_EX = 0x1107; +constexpr int ORBIS_NET_SO_ACCEPTTIMEO = 0x1108; +constexpr int ORBIS_NET_SO_CONNECTTIMEO = 0x1109; + +constexpr int ORBIS_NET_SO_NBIO = 0x1200; +constexpr int ORBIS_NET_SO_POLICY = 0x1201; +constexpr int ORBIS_NET_SO_NAME = 0x1202; +constexpr int ORBIS_NET_SO_PRIORITY = 0x1203; + // Define our own htonll and ntohll because its not available in some systems/platforms #ifndef HTONLL #define HTONLL(x) (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32)) @@ -21,21 +53,69 @@ namespace Libraries::Net { using OrbisNetId = s32; +struct OrbisNetInAddr { + u32 sin_addr; +}; + +struct OrbisNetIn6Addr { + u8 sin_addr[16]; +}; + struct OrbisNetSockaddr { u8 sa_len; u8 sa_family; char sa_data[14]; }; -int PS4_SYSV_ABI in6addr_any(); -int PS4_SYSV_ABI in6addr_loopback(); -int PS4_SYSV_ABI sce_net_dummy(); -int PS4_SYSV_ABI sce_net_in6addr_any(); -int PS4_SYSV_ABI sce_net_in6addr_linklocal_allnodes(); -int PS4_SYSV_ABI sce_net_in6addr_linklocal_allrouters(); -int PS4_SYSV_ABI sce_net_in6addr_loopback(); -int PS4_SYSV_ABI sce_net_in6addr_nodelocal_allnodes(); +struct OrbisNetSockaddrIn { + u8 sin_len; + u8 sin_family; + u16 sin_port; + OrbisNetInAddr sin_addr; + u16 sin_vport; + u8 sin_zero[6]; +}; + +static_assert(sizeof(OrbisNetSockaddrIn) == sizeof(OrbisNetSockaddr)); + +struct OrbisNetIovec { + void* iov_base; + size_t iov_len; +}; + +struct OrbisNetMsghdr { + void* msg_name; + u32 msg_namelen; + OrbisNetIovec* msg_iov; + int msg_iovlen; + void* msg_control; + u32 msg_controllen; + int msg_flags; +}; + +// Network Communication Functions OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen); +int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen); +int PS4_SYSV_ABI sceNetConnect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen); +int PS4_SYSV_ABI sceNetGetpeername(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen); +int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen); +int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen); +int PS4_SYSV_ABI sceNetListen(OrbisNetId s, int backlog); +int PS4_SYSV_ABI sceNetRecv(OrbisNetId s, void* buf, size_t len, int flags); +int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, + OrbisNetSockaddr* addr, u32* paddrlen); +int PS4_SYSV_ABI sceNetRecvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags); +int PS4_SYSV_ABI sceNetSend(OrbisNetId s, const void* buf, size_t len, int flags); +int PS4_SYSV_ABI sceNetSendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags); +int PS4_SYSV_ABI sceNetSendto(OrbisNetId s, const void* buf, size_t len, int flags, + const OrbisNetSockaddr* addr, u32 addrlen); +int PS4_SYSV_ABI sceNetSetsockopt(OrbisNetId s, int level, int optname, const void* optval, + u32 optlen); +int PS4_SYSV_ABI sceNetShutdown(OrbisNetId s, int how); +int PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol); +int PS4_SYSV_ABI sceNetSocketAbort(OrbisNetId s, int flags); +int PS4_SYSV_ABI sceNetSocketClose(OrbisNetId s); + int PS4_SYSV_ABI sceNetAddrConfig6GetInfo(); int PS4_SYSV_ABI sceNetAddrConfig6Start(); int PS4_SYSV_ABI sceNetAddrConfig6Stop(); @@ -47,7 +127,6 @@ int PS4_SYSV_ABI sceNetBandwidthControlGetPolicy(); int PS4_SYSV_ABI sceNetBandwidthControlSetDefaultParam(); int PS4_SYSV_ABI sceNetBandwidthControlSetIfParam(); int PS4_SYSV_ABI sceNetBandwidthControlSetPolicy(); -int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen); int PS4_SYSV_ABI sceNetClearDnsCache(); int PS4_SYSV_ABI sceNetConfigAddArp(); int PS4_SYSV_ABI sceNetConfigAddArpWithInterface(); @@ -116,7 +195,6 @@ int PS4_SYSV_ABI sceNetConfigWlanInfraLeave(); int PS4_SYSV_ABI sceNetConfigWlanInfraScanJoin(); int PS4_SYSV_ABI sceNetConfigWlanScan(); int PS4_SYSV_ABI sceNetConfigWlanSetDeviceConfig(); -int PS4_SYSV_ABI sceNetConnect(); int PS4_SYSV_ABI sceNetControl(); int PS4_SYSV_ABI sceNetDhcpdStart(); int PS4_SYSV_ABI sceNetDhcpdStop(); @@ -154,13 +232,10 @@ int PS4_SYSV_ABI sceNetGetIfnameNumList(); int PS4_SYSV_ABI sceNetGetMacAddress(); int PS4_SYSV_ABI sceNetGetMemoryPoolStats(); int PS4_SYSV_ABI sceNetGetNameToIndex(); -int PS4_SYSV_ABI sceNetGetpeername(); int PS4_SYSV_ABI sceNetGetRandom(); int PS4_SYSV_ABI sceNetGetRouteInfo(); int PS4_SYSV_ABI sceNetGetSockInfo(); int PS4_SYSV_ABI sceNetGetSockInfo6(); -int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen); -int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen); int PS4_SYSV_ABI sceNetGetStatisticsInfo(); int PS4_SYSV_ABI sceNetGetStatisticsInfoInternal(); int PS4_SYSV_ABI sceNetGetSystemTime(); @@ -177,7 +252,6 @@ int PS4_SYSV_ABI sceNetInfoDumpStop(); int PS4_SYSV_ABI sceNetInit(); int PS4_SYSV_ABI sceNetInitParam(); int PS4_SYSV_ABI sceNetIoctl(); -int PS4_SYSV_ABI sceNetListen(); int PS4_SYSV_ABI sceNetMemoryAllocate(); int PS4_SYSV_ABI sceNetMemoryFree(); u32 PS4_SYSV_ABI sceNetNtohl(u32 net32); @@ -187,10 +261,6 @@ int PS4_SYSV_ABI sceNetPoolCreate(const char* name, int size, int flags); int PS4_SYSV_ABI sceNetPoolDestroy(); int PS4_SYSV_ABI sceNetPppoeStart(); int PS4_SYSV_ABI sceNetPppoeStop(); -int PS4_SYSV_ABI sceNetRecv(); -int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, - OrbisNetSockaddr* addr, u32* paddrlen); -int PS4_SYSV_ABI sceNetRecvmsg(); int PS4_SYSV_ABI sceNetResolverAbort(); int PS4_SYSV_ABI sceNetResolverConnect(); int PS4_SYSV_ABI sceNetResolverConnectAbort(); @@ -205,14 +275,10 @@ int PS4_SYSV_ABI sceNetResolverStartNtoa(); int PS4_SYSV_ABI sceNetResolverStartNtoa6(); int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecords(); int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx(); -int PS4_SYSV_ABI sceNetSend(); -int PS4_SYSV_ABI sceNetSendmsg(); -int PS4_SYSV_ABI sceNetSendto(); int PS4_SYSV_ABI sceNetSetDns6Info(); int PS4_SYSV_ABI sceNetSetDns6InfoToKernel(); int PS4_SYSV_ABI sceNetSetDnsInfo(); int PS4_SYSV_ABI sceNetSetDnsInfoToKernel(); -int PS4_SYSV_ABI sceNetSetsockopt(); int PS4_SYSV_ABI sceNetShowIfconfig(); int PS4_SYSV_ABI sceNetShowIfconfigForBuffer(); int PS4_SYSV_ABI sceNetShowIfconfigWithMemory(); @@ -229,10 +295,6 @@ int PS4_SYSV_ABI sceNetShowRoute6ForBuffer(); int PS4_SYSV_ABI sceNetShowRoute6WithMemory(); int PS4_SYSV_ABI sceNetShowRouteForBuffer(); int PS4_SYSV_ABI sceNetShowRouteWithMemory(); -int PS4_SYSV_ABI sceNetShutdown(); -int PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol); -int PS4_SYSV_ABI sceNetSocketAbort(); -int PS4_SYSV_ABI sceNetSocketClose(); int PS4_SYSV_ABI sceNetSyncCreate(); int PS4_SYSV_ABI sceNetSyncDestroy(); int PS4_SYSV_ABI sceNetSyncGet();