From 0dbbea76004eda38394287c4b8f36f5cdaa25de7 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sun, 30 Mar 2025 19:57:10 +0300 Subject: [PATCH] implemented sceNetGetMacAddress --- CMakeLists.txt | 3 + src/core/libraries/network/net.cpp | 15 +++- src/core/libraries/network/net.h | 3 +- src/core/libraries/network/net_error.h | 20 +++++ src/core/libraries/network/net_util.cpp | 110 ++++++++++++++++++++++++ src/core/libraries/network/net_util.h | 24 ++++++ 6 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 src/core/libraries/network/net_error.h create mode 100644 src/core/libraries/network/net_util.cpp create mode 100644 src/core/libraries/network/net_util.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 73a0e2c4c..366437485 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,6 +355,9 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp src/core/libraries/network/net_ctl_obj.cpp src/core/libraries/network/net_ctl_obj.h src/core/libraries/network/net_ctl_codes.h + src/core/libraries/network/net_util.cpp + src/core/libraries/network/net_util.h + src/core/libraries/network/net_error.h src/core/libraries/network/net.h src/core/libraries/network/ssl.cpp src/core/libraries/network/ssl.h diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 161fc5214..2e1c3b058 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -12,9 +12,13 @@ #include "common/assert.h" #include "common/logging/log.h" +#include "common/singleton.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/network/net.h" +#include "net_error.h" +#include "net_util.h" +#include "netctl.h" namespace Libraries::Net { @@ -640,8 +644,15 @@ int PS4_SYSV_ABI sceNetGetIfnameNumList() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetGetMacAddress() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); +int PS4_SYSV_ABI sceNetGetMacAddress(Libraries::NetCtl::OrbisNetEtherAddr* addr, int flags) { + if (addr == nullptr) { + LOG_ERROR(Lib_Net, "addr is null!"); + return ORBIS_NET_EINVAL; + } + auto* netinfo = Common::Singleton::Instance(); + netinfo->RetrieveEthernetAddr(); + memcpy(addr->data, netinfo->GetEthernetAddr().data(), 6); + return ORBIS_OK; } diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index beef38b56..871133e70 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -4,6 +4,7 @@ #pragma once #include "common/types.h" +#include "netctl.h" namespace Core::Loader { class SymbolsResolver; @@ -151,7 +152,7 @@ int PS4_SYSV_ABI sceNetGetIfList(); int PS4_SYSV_ABI sceNetGetIfListOnce(); int PS4_SYSV_ABI sceNetGetIfName(); int PS4_SYSV_ABI sceNetGetIfnameNumList(); -int PS4_SYSV_ABI sceNetGetMacAddress(); +int PS4_SYSV_ABI sceNetGetMacAddress(Libraries::NetCtl::OrbisNetEtherAddr* addr, int flags); int PS4_SYSV_ABI sceNetGetMemoryPoolStats(); int PS4_SYSV_ABI sceNetGetNameToIndex(); int PS4_SYSV_ABI sceNetGetpeername(); diff --git a/src/core/libraries/network/net_error.h b/src/core/libraries/network/net_error.h new file mode 100644 index 000000000..fd2f40351 --- /dev/null +++ b/src/core/libraries/network/net_error.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +// net errno codes +constexpr int ORBIS_NET_ENOENT = 2; +constexpr int ORBIS_NET_EBADF = 9; +constexpr int ORBIS_NET_EFAULT = 14; +constexpr int ORBIS_NET_EEXIST = 17; +constexpr int ORBIS_NET_EINVAL = 22; + +// error codes +constexpr int ORBIS_NET_ERROR_EPERM = 0x80410101; +constexpr int ORBIS_NET_ERROR_ENOENT = 0x80410102; +constexpr int ORBIS_NET_ERROR_EBADF = 0x80410109; +constexpr int ORBIS_NET_ERROR_EFAULT = 0x8041010e; +constexpr int ORBIS_NET_ERROR_EEXIST = 0x80410111; +constexpr int ORBIS_NET_ERROR_EINVAL = 0x80410116; +constexpr int ORBIS_NET_ERROR_ENOPROTOOPT = 0x8041012a; diff --git a/src/core/libraries/network/net_util.cpp b/src/core/libraries/network/net_util.cpp new file mode 100644 index 000000000..d0f0a81da --- /dev/null +++ b/src/core/libraries/network/net_util.cpp @@ -0,0 +1,110 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifdef _WIN32 +#define _WINSOCK_DEPRECATED_NO_WARNINGS +#include +#include +#include +typedef SOCKET net_socket; +typedef int socklen_t; +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +typedef int net_socket; +#endif +#if defined(__APPLE__) +#include +#include +#endif + +#include +#include +#include +#include +#include +#include "net_util.h" + +namespace NetUtil { + +const std::array& NetUtilInternal::GetEthernetAddr() const { + return ether_address; +} + +bool NetUtilInternal::RetrieveEthernetAddr() { + std::scoped_lock lock{m_mutex}; +#ifdef _WIN32 + std::vector adapter_infos(sizeof(IP_ADAPTER_INFO)); + ULONG size_infos = sizeof(IP_ADAPTER_INFO); + + if (GetAdaptersInfo(reinterpret_cast(adapter_infos.data()), &size_infos) == + ERROR_BUFFER_OVERFLOW) + adapter_infos.resize(size_infos); + + if (GetAdaptersInfo(reinterpret_cast(adapter_infos.data()), &size_infos) == + NO_ERROR && + size_infos) { + PIP_ADAPTER_INFO info = reinterpret_cast(adapter_infos.data()); + memcpy(ether_address.data(), info[0].Address, 6); + return true; + } +#elif defined(__APPLE__) + ifaddrs* ifap; + + if (getifaddrs(&ifap) == 0) { + ifaddrs* p; + for (p = ifap; p; p = p->ifa_next) { + if (p->ifa_addr->sa_family == AF_LINK) { + sockaddr_dl* sdp = reinterpret_cast(p->ifa_addr); + memcpy(ether_address.data(), sdp->sdl_data + sdp->sdl_nlen, 6); + freeifaddrs(ifap); + return true; + } + } + freeifaddrs(ifap); + } +#else + ifreq ifr; + ifconf ifc; + char buf[1024]; + int success = 0; + + int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sock == -1) + return false; + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) + return false; + + ifreq* it = ifc.ifc_req; + const ifreq* const end = it + (ifc.ifc_len / sizeof(ifreq)); + + for (; it != end; ++it) { + strcpy(ifr.ifr_name, it->ifr_name); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { + if (!(ifr.ifr_flags & IFF_LOOPBACK)) { + if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { + success = 1; + break; + } + } + } + } + + if (success) { + memcpy(ether_address.data(), ifr.ifr_hwaddr.sa_data, 6); + return true; + } +#endif + return false; +} +} // namespace NetUtil \ No newline at end of file diff --git a/src/core/libraries/network/net_util.h b/src/core/libraries/network/net_util.h new file mode 100644 index 000000000..be9dc15a1 --- /dev/null +++ b/src/core/libraries/network/net_util.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "common/types.h" + +namespace NetUtil { + +class NetUtilInternal { +public: + explicit NetUtilInternal() = default; + ~NetUtilInternal() = default; + +private: + std::array ether_address{}; + std::mutex m_mutex; + +public: + const std::array& GetEthernetAddr() const; + bool RetrieveEthernetAddr(); +}; +} // namespace NetUtil \ No newline at end of file