diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index b772e39779..1e6aa902ba 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -107,7 +107,7 @@ if(UNIX) endif() if(WIN32) - target_link_libraries(rpcs3 ws2_32.lib Winmm.lib Psapi.lib gdi32.lib setupapi.lib) + target_link_libraries(rpcs3 ws2_32.lib Iphlpapi.lib Winmm.lib Psapi.lib gdi32.lib setupapi.lib) else() target_link_libraries(rpcs3 ${CMAKE_DL_LIBS}) endif() diff --git a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp index b398798089..6f11dccb02 100644 --- a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp @@ -193,8 +193,7 @@ error_code cellNetCtlGetInfo(s32 code, vm::ptr info) if (code == CELL_NET_CTL_INFO_ETHER_ADDR) { - // dummy values set - std::memset(info->ether_addr.data, 0xFF, sizeof(info->ether_addr.data)); + memcpy(info->ether_addr.data, nph->get_ether_addr().data(), 6); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_net.cpp b/rpcs3/Emu/Cell/lv2/sys_net.cpp index 0bf57e1a5b..6f8cb53fb6 100644 --- a/rpcs3/Emu/Cell/lv2/sys_net.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_net.cpp @@ -29,6 +29,7 @@ #include LOG_CHANNEL(sys_net); +LOG_CHANNEL(sys_net_dump); template<> void fmt_class_string::format(std::string& out, u64 arg) @@ -177,7 +178,7 @@ void windows_poll(pollfd* fds, unsigned long nfds, int timeout, bool* connecting // Error helper functions static int get_native_error() { - int native_error = 0; + int native_error; #ifdef _WIN32 native_error = WSAGetLastError(); #else @@ -2247,7 +2248,7 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr buf, u32 if (native_result >= 0) { - if (sys_net.enabled == logs::level::trace) + if (sys_net_dump.enabled == logs::level::trace) { std::string datrace; const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; @@ -2263,7 +2264,7 @@ error_code sys_net_bnet_recvfrom(ppu_thread& ppu, s32 s, vm::ptr buf, u32 datrace += hex[(dabuf[index]) & 15]; datrace += ' '; } - sys_net.trace("DNS RESULT: %s", datrace); + sys_net.trace("recvfrom dump: %s", datrace); } return true; diff --git a/rpcs3/Emu/NP/np_handler.cpp b/rpcs3/Emu/NP/np_handler.cpp index 3b17dc41bb..3bd910c881 100644 --- a/rpcs3/Emu/NP/np_handler.cpp +++ b/rpcs3/Emu/NP/np_handler.cpp @@ -16,14 +16,21 @@ #ifdef _WIN32 #include #include +#include #else #include #include +#include #include #include #include #endif +#ifdef __FreeBSD__ +#include +#include +#endif + LOG_CHANNEL(sys_net); LOG_CHANNEL(sceNp2); LOG_CHANNEL(sceNp); @@ -47,6 +54,13 @@ np_handler::np_handler() is_psn_active = false; } + if (!discover_ether_address()) + { + nph_log.error("Failed to discover ethernet address!"); + is_connected = false; + is_psn_active = false; + } + // Convert dns address // TODO: recover actual user dns through OS specific API in_addr conv{}; @@ -113,9 +127,97 @@ bool np_handler::discover_ip_address() // Set public address to local discovered address for now, may be updated later; public_ip_addr = local_ip_addr; + nph_log.notice("IP was determined to be %s", ip_to_string(local_ip_addr)); + return true; } +bool np_handler::discover_ether_address() +{ +#ifdef __FreeBSD__ + 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); + nph_log.notice("Determined Ethernet address to be %s", ether_to_string(ether_address)); + return true; + } + } + freeifaddrs(ifap); + } +#elif defined(_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); + nph_log.notice("Determined Ethernet address to be %s", ether_to_string(ether_address)); + return true; + } +#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); + nph_log.notice("Determined Ethernet address to be %s", ether_to_string(ether_address)); + + return true; + } +#endif + + return false; +} + +const std::array& np_handler::get_ether_addr() const +{ + return ether_address; +} + u32 np_handler::get_local_ip_addr() const { return local_ip_addr; @@ -172,6 +274,11 @@ std::string np_handler::ip_to_string(u32 ip_addr) return result; } +std::string np_handler::ether_to_string(std::array& ether) +{ + return fmt::format("%02X:%02X:%02X:%02X:%02X:%02X", ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]); +} + void np_handler::string_to_npid(const char* str, SceNpId* npid) { strncpy(npid->handle.data, str, sizeof(npid->handle.data)); diff --git a/rpcs3/Emu/NP/np_handler.h b/rpcs3/Emu/NP/np_handler.h index 68ceac5a7f..20c7138a61 100644 --- a/rpcs3/Emu/NP/np_handler.h +++ b/rpcs3/Emu/NP/np_handler.h @@ -17,6 +17,7 @@ class np_handler public: np_handler(); + const std::array& get_ether_addr() const; u32 get_local_ip_addr() const; u32 get_public_ip_addr() const; u32 get_dns_ip() const; @@ -31,6 +32,7 @@ public: // Public helpers static std::string ip_to_string(u32 addr); + static std::string ether_to_string(std::array& ether); // Helpers for setting various structures from string static void string_to_npid(const char* str, SceNpId* npid); static void string_to_online_name(const char* str, SceNpOnlineName* online_name); @@ -250,6 +252,7 @@ public: protected: // Various generic helpers bool discover_ip_address(); + bool discover_ether_address(); bool error_and_disconnect(const std::string& error_msg); // Notification handlers @@ -301,6 +304,7 @@ protected: std::vector current_ticket; // IP & DNS info + std::array ether_address{}; be_t local_ip_addr{}; be_t public_ip_addr{}; be_t dns_ip = 0x08080808; diff --git a/rpcs3_default.props b/rpcs3_default.props index 0252b99c1b..a51f2711b3 100644 --- a/rpcs3_default.props +++ b/rpcs3_default.props @@ -23,7 +23,7 @@ /Zc:throwingNew /constexpr:steps16777216 %(AdditionalOptions) - xxhash.lib;ws2_32.lib;Bcrypt.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib + xxhash.lib;ws2_32.lib;Iphlpapi.lib;Bcrypt.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib ..\3rdparty\ffmpeg\windows\x86_64 8388608 1048576