Compare commits

..

8 Commits

Author SHA1 Message Date
lizzie ee775219c5 wa 2026-09-05 22:07:41 +02:00
lizzie ae44746c39 sdfsdfdsfdf 2026-09-05 22:07:41 +02:00
lizzie f3ad901c66 fs 2026-09-05 22:07:41 +02:00
lizzie 5caced11bd FDSFDSFSDF 2026-09-05 22:07:41 +02:00
lizzie 1f25224116 fx 2026-09-05 22:07:41 +02:00
lizzie 5dda5d7e74 fx 2026-09-05 22:07:41 +02:00
lizzie 263cd0d51e beware of link_ntoa_r() 2026-09-05 22:07:41 +02:00
lizzie 8acb50d967 [macos, net] add sysctl(RT_xx)-fetched network interfaces
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-05 22:07:41 +02:00
2 changed files with 25 additions and 14 deletions
+5 -9
View File
@@ -399,10 +399,6 @@ private:
// For managarm: see https://github.com/managarm/managarm/issues/1370
#else // ^^^ Windows ^^^ vvv POSIX vvv
#ifndef MAP_NOCORE
#define MAP_NOCORE 0
#endif
#ifdef ARCHITECTURE_arm64
static void* ChooseVirtualBase(size_t virtual_size) {
@@ -427,7 +423,7 @@ static void* ChooseVirtualBase(size_t virtual_size) {
// Note: we may be able to take advantage of MAP_FIXED_NOREPLACE here.
void* map_pointer =
mmap(reinterpret_cast<void*>(hint_address), virtual_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_NOCORE, -1, 0);
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
// If we successfully mapped, we're done.
if (reinterpret_cast<uintptr_t>(map_pointer) == hint_address) {
@@ -447,11 +443,11 @@ static void* ChooseVirtualBase(size_t virtual_size) {
static void* ChooseVirtualBase(size_t virtual_size) {
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__managarm__) || defined(__AIX__)
void* virtual_base = mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER | MAP_NOCORE, -1, 0);
void* virtual_base = mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0);
if (virtual_base != MAP_FAILED)
return virtual_base;
#endif
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_NOCORE, -1, 0);
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
}
#endif
@@ -545,13 +541,13 @@ public:
}
if (use_anon) {
LOG_WARNING(Common_Memory, "Using private mappings instead of shared ones");
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_NOCORE, -1, 0));
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
if (fd > 0) {
fd = -1;
close(fd);
}
} else {
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NOCORE, fd, 0));
backing_base = static_cast<u8*>(mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
}
if (backing_base == MAP_FAILED) {
LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
@@ -13,7 +13,7 @@
#include <winsock2.h>
#include <windows.h>
#include <iphlpapi.h>
#elif defined(__linux__) || defined(__ANDROID__)
#elif defined(__linux__) || defined(__ANDROID__) || defined(__APPLE__)
#include <cerrno>
#include <ifaddrs.h>
#include <net/if.h>
@@ -33,6 +33,13 @@
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <netdb.h>
// Darwin doesn't define this for some very odd reason
// See https://stackoverflow.com/questions/5390164/getting-routing-table-on-macosx-programmatically
#ifndef SA_SIZE
#define SA_SIZE(sa) \
((!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? sizeof(long) \
: 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) )
#endif
#endif
#include "common/common_types.h"
@@ -104,7 +111,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
#else
std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
#if defined(__ANDROID__) || defined(__linux__)
#if defined(__ANDROID__) || defined(__linux__) || defined(__APPLE__) || defined(__managarm__)
struct ifaddrs* ifaddr = nullptr;
if (getifaddrs(&ifaddr) != 0) {
LOG_ERROR(Network, "getifaddrs: {}", std::strerror(errno));
@@ -119,8 +126,9 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
u32 flags;
};
std::vector<RoutingEntry> routes{};
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__APPLE__)
// Even through Linux based, we can't reliably obtain routing information from there :(
// macOS not Linux based and would murder us if we attempt to access /proc
#else
if (std::ifstream file("/proc/net/route"); file.is_open()) {
file.ignore((std::numeric_limits<std::streamsize>::max)(), '\n'); //ignore header
@@ -138,7 +146,10 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
std::vector<Network::NetworkInterface> ifaces;
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr || ifa->ifa_netmask == nullptr /* Have a netmask and address */
// Apple hates human beings so lets pretend all families are fine
#if !defined(__APPLE__) && !defined(__managarm__)
|| ifa->ifa_addr->sa_family != AF_INET /* Must be of kind AF_INET */
#endif
|| (ifa->ifa_flags & IFF_UP) == 0 || (ifa->ifa_flags & IFF_LOOPBACK) != 0) /* Not loopback */
continue;
// Just use 0 as the gateway address if not found OR routes are empty :)
@@ -158,7 +169,7 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
}
freeifaddrs(ifaddr);
return ifaces;
#elif defined(__FreeBSD__)
#elif defined(__FreeBSD__) || defined(__APPLE__)
std::vector<Network::NetworkInterface> ifaces;
int fd = ::socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
if (fd < 0) {
@@ -198,11 +209,15 @@ std::vector<Network::NetworkInterface> GetAvailableNetworkInterfaces() {
if (msglen == 0 || msglen < SA_SIZE(sa))
break;
if (i == RTA_NETMASK && sa->sa_family == AF_LINK) {
size_t namelen = 0;
struct sockaddr_dl const* sdl = reinterpret_cast<struct sockaddr_dl const*>(sa);
#if defined(__FreeBSD__) && __FreeBSD__ < 15
iface.name = std::string{::link_ntoa(sdl)};
#else
size_t namelen = 0;
::link_ntoa_r(sdl, nullptr, &namelen);
iface.name = std::string(namelen, ' ');
::link_ntoa_r(sdl, iface.name.data(), &namelen);
#endif
std::memcpy(&iface.ip_address, sa, sizeof(struct sockaddr_in));
}
msglen -= SA_SIZE(sa);