diff --git a/pcsx2/DEV9/InternalServers/DHCP_Server.cpp b/pcsx2/DEV9/InternalServers/DHCP_Server.cpp index b4ed4afb57..a41fa4cdc5 100644 --- a/pcsx2/DEV9/InternalServers/DHCP_Server.cpp +++ b/pcsx2/DEV9/InternalServers/DHCP_Server.cpp @@ -20,12 +20,16 @@ #include #include #include -#include -#endif - -#if defined(__FreeBSD__) -#include #include +#include + +#if defined(__FreeBSD__) || (__APPLE__) +#include +#include +#include +#include +#include +#endif #endif #include "DHCP_Server.h" @@ -167,6 +171,83 @@ namespace InternalServers } return collection; } +#elif defined(__FreeBSD__) || (__APPLE__) + std::vector DHCP_Server::GetGatewaysBSD(char* interfaceName) + { + std::vector collection; + + //Get index for our adapter by matching the adapter name + int ifIndex = -1; + + struct if_nameindex* ifNI; + ifNI = if_nameindex(); + if (ifNI == nullptr) + { + Console.Error("DHCP: if_nameindex Failed"); + return collection; + } + + struct if_nameindex* i = ifNI; + while (i->if_index != 0 && i->if_name != nullptr) + { + if (strcmp(i->if_name, interfaceName) == 0) + { + ifIndex = i->if_index; + break; + } + i++; + } + if_freenameindex(ifNI); + + //Check if we found the adapter + if (ifIndex == -1) + { + Console.Error("DHCP: Failed to get index for adapter"); + return collection; + } + + //Find the gateway by looking though the routing information + int name[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0}; + size_t bufferLen = 0; + + if (sysctl(name, 6, NULL, &bufferLen, NULL, 0) != 0) + { + Console.Error("DHCP: Failed to perform NET_RT_DUMP"); + return collection; + } + + //len is an estimate, double it to be safe + bufferLen *= 2; + std::unique_ptr buffer = std::make_unique(bufferLen); + + if (sysctl(name, 6, buffer.get(), &bufferLen, NULL, 0) != 0) + { + Console.Error("DHCP: Failed to perform NET_RT_DUMP"); + return collection; + } + + rt_msghdr* hdr; + for (size_t i = 0; i < bufferLen; i += hdr->rtm_msglen) + { + hdr = (rt_msghdr*)&buffer[i]; + + if (hdr->rtm_flags & RTF_GATEWAY && hdr->rtm_addrs & RTA_GATEWAY && (hdr->rtm_index == ifIndex)) + { + sockaddr* sockaddrs = (sockaddr*)(hdr + 1); + pxAssert(sockaddrs[RTAX_DST].sa_family == AF_INET); + + //Default gateway has no destination address + sockaddr_in* sockaddr = (sockaddr_in*)&sockaddrs[RTAX_DST]; + if (sockaddr->sin_addr.s_addr != 0) + continue; + + sockaddr = (sockaddr_in*)&sockaddrs[RTAX_GATEWAY]; + IP_Address gwIP = *(IP_Address*)&sockaddr->sin_addr; + collection.push_back(gwIP); + } + } + return collection; + } #endif std::vector DHCP_Server::GetDNSUnix() { @@ -274,6 +355,13 @@ namespace InternalServers if (gateways.size() > 0) gateway = gateways[0]; + +#elif defined(__FreeBSD__) || (__APPLE__) + std::vector gateways = GetGatewaysBSD(adapter->ifa_name); + + if (gateways.size() > 0) + gateway = gateways[0]; + #else Console.Error("DHCP: Unsupported OS, can't find Gateway"); #endif diff --git a/pcsx2/DEV9/InternalServers/DHCP_Server.h b/pcsx2/DEV9/InternalServers/DHCP_Server.h index 32290374d0..ff24a01f4d 100644 --- a/pcsx2/DEV9/InternalServers/DHCP_Server.h +++ b/pcsx2/DEV9/InternalServers/DHCP_Server.h @@ -63,6 +63,8 @@ namespace InternalServers #ifdef __linux__ static std::vector GetGatewaysLinux(char* interfaceName); +#elif defined(__FreeBSD__) || (__APPLE__) + static std::vector GetGatewaysBSD(char* interfaceName); #endif ~DHCP_Server();