diff --git a/src/Cafe/OS/libs/nn_ac/nn_ac.cpp b/src/Cafe/OS/libs/nn_ac/nn_ac.cpp index 61e7a677..54a38ab5 100644 --- a/src/Cafe/OS/libs/nn_ac/nn_ac.cpp +++ b/src/Cafe/OS/libs/nn_ac/nn_ac.cpp @@ -5,6 +5,9 @@ #if BOOST_OS_WINDOWS #include +#elif BOOST_OS_LINUX +#include +#include #endif // AC lib (manages internet connection) @@ -81,6 +84,37 @@ void _GetLocalIPAndSubnetMask(uint32& localIp, uint32& subnetMask) cemuLog_logDebug(LogType::Force, "_GetLocalIPAndSubnetMask(): Failed to find network IP and subnet mask"); _GetLocalIPAndSubnetMaskFallback(localIp, subnetMask); } +#elif BOOST_OS_LINUX +void _GetLocalIPAndSubnetMask(uint32& localIp, uint32& subnetMask) +{ + struct ifaddrs *ifaddr; + if (getifaddrs(&ifaddr) == -1) + { + cemuLog_log(LogType::Force, "Failed to acquire local IP and subnet mask"); + _GetLocalIPAndSubnetMaskFallback(localIp, subnetMask); + } + stdx::scope_exit _ifa([&]{ freeifaddrs(ifaddr); }); + + for (const struct ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == nullptr || ifa->ifa_addr->sa_family != AF_INET) + continue; + + if (!(ifa->ifa_flags & IFF_UP) || !(ifa->ifa_flags & IFF_RUNNING)) + continue; + + if (ifa->ifa_flags & IFF_LOOPBACK) + continue; + + const auto* addr_in = reinterpret_cast(ifa->ifa_addr); + localIp = ntohl(addr_in->sin_addr.s_addr); + const auto* mask_in = reinterpret_cast(ifa->ifa_netmask); + subnetMask = ntohl(mask_in->sin_addr.s_addr); + return; + } + cemuLog_logDebug(LogType::Force, "_GetLocalIPAndSubnetMask(): Failed to find network IP and subnet mask"); + _GetLocalIPAndSubnetMaskFallback(localIp, subnetMask); +} #else void _GetLocalIPAndSubnetMask(uint32& localIp, uint32& subnetMask) {