diff --git a/src/core/libraries/network/net_util.cpp b/src/core/libraries/network/net_util.cpp index e7b1bddcc..aaedcc12a 100644 --- a/src/core/libraries/network/net_util.cpp +++ b/src/core/libraries/network/net_util.cpp @@ -24,6 +24,11 @@ typedef int net_socket; #if defined(__APPLE__) #include #endif +#if __linux__ +#include +#include +#include +#endif #include #include @@ -110,6 +115,45 @@ bool NetUtilInternal::RetrieveEthernetAddr() { return false; } +const std::string& NetUtilInternal::GetDefaultGateway() const { + return default_gateway; +} + +bool NetUtilInternal::RetrieveDefaultGateway() { + std::scoped_lock lock{m_mutex}; + +#ifdef _WIN32 + +#elif defined(__APPLE__) + +#else + std::ifstream route{"/proc/net/route"}; + std::string line; + + std::getline(route, line); + while(std::getline(route, line)) { + std::istringstream iss{line}; + std::string iface, destination, gateway; + int flags; + + iss >> iface >> destination >> gateway >> std::hex >> flags; + + if (destination == "00000000") { + u64 default_gateway{}; + std::stringstream ss; + ss << std::hex << gateway; + ss >> default_gateway; + + in_addr addr; + addr.s_addr = default_gateway; + this->default_gateway = inet_ntoa(addr); + return true; + } + } +#endif + return false; +} + const std::string& NetUtilInternal::GetNetmask() const { return netmask; } diff --git a/src/core/libraries/network/net_util.h b/src/core/libraries/network/net_util.h index 97f671705..fce55c2ff 100644 --- a/src/core/libraries/network/net_util.h +++ b/src/core/libraries/network/net_util.h @@ -15,13 +15,16 @@ public: private: std::array ether_address{}; + std::string default_gateway{}; std::string netmask{}; std::mutex m_mutex; public: const std::array& GetEthernetAddr() const; + const std::string& GetDefaultGateway() const; const std::string& GetNetmask() const; bool RetrieveEthernetAddr(); + bool RetrieveDefaultGateway(); bool RetrieveNetmask(); }; } // namespace NetUtil \ No newline at end of file diff --git a/src/core/libraries/network/netctl.cpp b/src/core/libraries/network/netctl.cpp index 6c874b400..4ba96fb1a 100644 --- a/src/core/libraries/network/netctl.cpp +++ b/src/core/libraries/network/netctl.cpp @@ -164,13 +164,13 @@ int PS4_SYSV_ABI sceNetCtlGetIfStat() { int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) { LOG_DEBUG(Lib_NetCtl, "code = {}", code); + auto* netinfo = Common::Singleton::Instance(); switch (code) { case ORBIS_NET_CTL_INFO_DEVICE: info->device = ORBIS_NET_CTL_DEVICE_WIRED; break; case ORBIS_NET_CTL_INFO_ETHER_ADDR: { - auto* netinfo = Common::Singleton::Instance(); netinfo->RetrieveEthernetAddr(); memcpy(info->ether_addr.data, netinfo->GetEthernetAddr().data(), 6); } break; @@ -221,7 +221,6 @@ int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) { // info-> = ; break; case ORBIS_NET_CTL_INFO_NETMASK: { - auto* netinfo = Common::Singleton::Instance(); auto success = netinfo->RetrieveNetmask(); if (success) { strncpy(info->netmask, netinfo->GetNetmask().data(), sizeof(info->netmask)); @@ -231,6 +230,16 @@ int PS4_SYSV_ABI sceNetCtlGetInfo(int code, OrbisNetCtlInfo* info) { } break; } + case ORBIS_NET_CTL_INFO_DEFAULT_ROUTE: { + auto success = netinfo->RetrieveDefaultGateway(); + if (success) { + strncpy(info->netmask, netinfo->GetDefaultGateway().data(), sizeof(info->netmask)); + LOG_DEBUG(Lib_NetCtl, "default gateway: {}", info->netmask); + } else { + LOG_WARNING(Lib_NetCtl, "default gateway: failed to retrieve"); + } + break; + } default: LOG_ERROR(Lib_NetCtl, "{} unsupported code", code); }