Merge branch 'PCSX2:master' into master

This commit is contained in:
987123879113 2022-06-18 08:00:47 +09:00 committed by GitHub
commit fa14522760
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 648 additions and 656 deletions

View File

@ -347,6 +347,7 @@ set(pcsx2SPU2Headers
# DEV9 sources
set(pcsx2DEV9Sources
DEV9/AdapterUtils.cpp
DEV9/ATA/Commands/ATA_Command.cpp
DEV9/ATA/Commands/ATA_CmdDMA.cpp
DEV9/ATA/Commands/ATA_CmdExecuteDeviceDiag.cpp
@ -391,6 +392,7 @@ set(pcsx2DEV9Sources
# DEV9 headers
set(pcsx2DEV9Headers
DEV9/AdapterUtils.h
DEV9/ATA/ATA.h
DEV9/ATA/HddCreate.h
DEV9/DEV9.h

511
pcsx2/DEV9/AdapterUtils.cpp Normal file
View File

@ -0,0 +1,511 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include <algorithm>
#ifdef __POSIX__
#include <vector>
#include <fstream>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "common/StringUtil.h"
#if defined(__FreeBSD__) || (__APPLE__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/route.h>
#include "common/Assertions.h"
#endif
#endif
#include "AdapterUtils.h"
using namespace PacketReader::IP;
#ifdef _WIN32
bool AdapterUtils::GetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer)
{
int neededSize = 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapterInfo;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: GetWin32Adapter() buffer too small, resizing");
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return false;
pAdapterInfo = AdapterInfo.get();
do
{
if (strcmp(pAdapterInfo->AdapterName, name.c_str()) == 0)
{
*adapter = *pAdapterInfo;
buffer->swap(AdapterInfo);
return true;
}
pAdapterInfo = pAdapterInfo->Next;
} while (pAdapterInfo);
return false;
}
bool AdapterUtils::GetWin32AdapterAuto(PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer)
{
int neededSize = 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapter;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: PCAPGetWin32Adapter() buffer too small, resizing");
//
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return 0;
pAdapter = AdapterInfo.get();
do
{
if (pAdapter->IfType != IF_TYPE_SOFTWARE_LOOPBACK &&
pAdapter->OperStatus == IfOperStatusUp)
{
//Search for an adapter with;
//IPv4 Address
//DNS
//Gateway
bool hasIPv4 = false;
bool hasDNS = false;
bool hasGateway = false;
//IPv4
if (GetAdapterIP(pAdapter).has_value())
hasIPv4 = true;
//DNS
if (GetDNS(pAdapter).size() > 0)
hasDNS = true;
//Gateway
if (GetGateways(pAdapter).size() > 0)
hasGateway = true;
if (hasIPv4 && hasDNS && hasGateway)
{
*adapter = *pAdapter;
buffer->swap(AdapterInfo);
return true;
}
}
pAdapter = pAdapter->Next;
} while (pAdapter);
return false;
}
#elif defined(__POSIX__)
bool AdapterUtils::GetIfAdapter(const std::string& name, ifaddrs* adapter, ifaddrs** buffer)
{
ifaddrs* adapterInfo;
ifaddrs* pAdapter;
int error = getifaddrs(&adapterInfo);
if (error)
return false;
pAdapter = adapterInfo;
do
{
if (pAdapter->ifa_addr->sa_family == AF_INET && strcmp(pAdapter->ifa_name, name.c_str()) == 0)
break;
pAdapter = pAdapter->ifa_next;
} while (pAdapter);
if (pAdapter != nullptr)
{
*adapter = *pAdapter;
*buffer = adapterInfo;
return true;
}
freeifaddrs(adapterInfo);
return false;
}
bool AdapterUtils::GetIfAdapterAuto(ifaddrs* adapter, ifaddrs** buffer)
{
ifaddrs* adapterInfo;
ifaddrs* pAdapter;
int error = getifaddrs(&adapterInfo);
if (error)
return false;
pAdapter = adapterInfo;
do
{
if ((pAdapter->ifa_flags & IFF_LOOPBACK) == 0 &&
(pAdapter->ifa_flags & IFF_UP) != 0)
{
//Search for an adapter with;
//IPv4 Address
//Gateway
bool hasIPv4 = false;
bool hasGateway = false;
if (GetAdapterIP(pAdapter).has_value())
hasIPv4 = true;
if (GetGateways(pAdapter).size() > 0)
hasGateway = true;
if (hasIPv4 && hasGateway)
{
*adapter = *pAdapter;
*buffer = adapterInfo;
return true;
}
}
pAdapter = pAdapter->ifa_next;
} while (pAdapter);
freeifaddrs(adapterInfo);
return false;
}
#endif
//AdapterIP
#ifdef _WIN32
std::optional<IP_Address> AdapterUtils::GetAdapterIP(PIP_ADAPTER_ADDRESSES adapter)
{
PIP_ADAPTER_UNICAST_ADDRESS address = nullptr;
if (adapter != nullptr)
{
address = adapter->FirstUnicastAddress;
while (address != nullptr && address->Address.lpSockaddr->sa_family != AF_INET)
address = address->Next;
}
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
return *(IP_Address*)&sockaddr->sin_addr;
}
return std::nullopt;
}
#elif defined(__POSIX__)
std::optional<IP_Address> AdapterUtils::GetAdapterIP(ifaddrs* adapter)
{
sockaddr* address = nullptr;
if (adapter != nullptr)
{
if (adapter->ifa_addr != nullptr && adapter->ifa_addr->sa_family == AF_INET)
address = adapter->ifa_addr;
}
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address;
return *(IP_Address*)&sockaddr->sin_addr;
}
return std::nullopt;
}
#endif
//Gateways
#ifdef _WIN32
std::vector<IP_Address> AdapterUtils::GetGateways(PIP_ADAPTER_ADDRESSES adapter)
{
if (adapter == nullptr)
return {};
std::vector<IP_Address> collection;
PIP_ADAPTER_GATEWAY_ADDRESS address = adapter->FirstGatewayAddress;
while (address != nullptr)
{
if (address->Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
collection.push_back(*(IP_Address*)&sockaddr->sin_addr);
}
address = address->Next;
}
return collection;
}
#elif defined(__POSIX__)
#ifdef __linux__
std::vector<IP_Address> AdapterUtils::GetGateways(ifaddrs* adapter)
{
///proc/net/route contains some information about gateway addresses,
//and separates the information about by each interface.
if (adapter == nullptr)
return {};
std::vector<IP_Address> collection;
std::vector<std::string> routeLines;
std::fstream route("/proc/net/route", std::ios::in);
if (route.fail())
{
route.close();
Console.Error("DEV9: Failed to open /proc/net/route");
return collection;
}
std::string line;
while (std::getline(route, line))
routeLines.push_back(line);
route.close();
//Columns are as follows (first-line header):
//Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
for (size_t i = 1; i < routeLines.size(); i++)
{
std::string line = routeLines[i];
if (line.rfind(adapter->ifa_name, 0) == 0)
{
std::vector<std::string_view> split = StringUtil::SplitString(line, '\t', true);
std::string gatewayIPHex{split[2]};
int addressValue = std::stoi(gatewayIPHex, 0, 16);
//Skip device routes without valid NextHop IP address
if (addressValue != 0)
{
IP_Address gwIP = *(IP_Address*)&addressValue;
collection.push_back(gwIP);
}
}
}
return collection;
}
#elif defined(__FreeBSD__) || (__APPLE__)
std::vector<IP_Address> AdapterUtils::GetGateways(ifaddrs* adapter)
{
if (adapter == nullptr)
return {};
std::vector<IP_Address> 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("DEV9: if_nameindex Failed");
return collection;
}
struct if_nameindex* i = ifNI;
while (i->if_index != 0 && i->if_name != nullptr)
{
if (strcmp(i->if_name, adapter->ifa_name) == 0)
{
ifIndex = i->if_index;
break;
}
i++;
}
if_freenameindex(ifNI);
//Check if we found the adapter
if (ifIndex == -1)
{
Console.Error("DEV9: 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("DEV9: Failed to perform NET_RT_DUMP");
return collection;
}
//len is an estimate, double it to be safe
bufferLen *= 2;
std::unique_ptr<u8[]> buffer = std::make_unique<u8[]>(bufferLen);
if (sysctl(name, 6, buffer.get(), &bufferLen, NULL, 0) != 0)
{
Console.Error("DEV9: 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;
}
#else
std::vector<IP_Address> AdapterUtils::GetGateways(ifaddrs* adapter)
{
Console.Error("DEV9: Unsupported OS, can't find Gateway");
return {};
}
#endif
#endif
//DNS
#ifdef _WIN32
std::vector<IP_Address> AdapterUtils::GetDNS(PIP_ADAPTER_ADDRESSES adapter)
{
if (adapter == nullptr)
return {};
std::vector<IP_Address> collection;
PIP_ADAPTER_DNS_SERVER_ADDRESS address = adapter->FirstDnsServerAddress;
while (address != nullptr)
{
if (address->Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
collection.push_back(*(IP_Address*)&sockaddr->sin_addr);
}
address = address->Next;
}
return collection;
}
#elif defined(__POSIX__)
std::vector<IP_Address> AdapterUtils::GetDNS(ifaddrs* adapter)
{
//On Linux and OSX, DNS is system wide, not adapter specific, so we can ignore adapter
// Parse /etc/resolv.conf for all of the "nameserver" entries.
// These are the DNS servers the machine is configured to use.
// On OSX, this file is not directly used by most processes for DNS
// queries/routing, but it is automatically generated instead, with
// the machine's DNS servers listed in it.
if (adapter == nullptr)
return {};
std::vector<IP_Address> collection;
std::fstream servers("/etc/resolv.conf", std::ios::in);
if (servers.fail())
{
servers.close();
Console.Error("DEV9: Failed to open /etc/resolv.conf");
return collection;
}
std::string line;
std::vector<std::string> serversLines;
while (std::getline(servers, line))
serversLines.push_back(line);
servers.close();
const IP_Address systemdDNS{127, 0, 0, 53};
for (size_t i = 1; i < serversLines.size(); i++)
{
std::string line = serversLines[i];
if (line.rfind("nameserver", 0) == 0)
{
std::vector<std::string_view> split = StringUtil::SplitString(line, '\t', true);
if (split.size() == 1)
split = StringUtil::SplitString(line, ' ', true);
std::string dns{split[1]};
IP_Address address;
if (inet_pton(AF_INET, dns.c_str(), &address) != 1)
continue;
if (address == systemdDNS)
Console.Error("DEV9: systemd-resolved DNS server is not supported");
collection.push_back(address);
}
}
return collection;
}
#endif

50
pcsx2/DEV9/AdapterUtils.h Normal file
View File

@ -0,0 +1,50 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef _WIN32
#include <winsock2.h>
#include <iphlpapi.h>
#elif defined(__POSIX__)
#include <sys/types.h>
#include <ifaddrs.h>
#endif
#include <string>
#include <optional>
#include "DEV9/PacketReader/IP/IP_Address.h"
namespace AdapterUtils
{
#ifdef _WIN32
bool GetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer);
bool GetWin32AdapterAuto(PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer);
std::optional<PacketReader::IP::IP_Address> GetAdapterIP(PIP_ADAPTER_ADDRESSES adapter);
//Mask
std::vector<PacketReader::IP::IP_Address> GetGateways(PIP_ADAPTER_ADDRESSES adapter);
std::vector<PacketReader::IP::IP_Address> GetDNS(PIP_ADAPTER_ADDRESSES adapter);
#elif defined(__POSIX__)
bool GetIfAdapter(const std::string& name, ifaddrs* adapter, ifaddrs** buffer);
bool GetIfAdapterAuto(ifaddrs* adapter, ifaddrs** buffer);
std::optional<PacketReader::IP::IP_Address> GetAdapterIP(ifaddrs* adapter);
//Mask
std::vector<PacketReader::IP::IP_Address> GetGateways(ifaddrs* adapter);
std::vector<PacketReader::IP::IP_Address> GetDNS(ifaddrs* adapter);
#endif
}; // namespace AdapterUtils

View File

@ -37,6 +37,7 @@
#include "DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.h"
#include "DEV9/DEV9.h"
#include "DEV9/AdapterUtils.h"
using namespace PacketReader;
using namespace PacketReader::IP;
@ -110,195 +111,6 @@ namespace InternalServers
AutoBroadcast(ps2IP, netmask);
}
#ifdef __POSIX__
//skipsEmpty
std::vector<std::string> DHCP_Server::SplitString(std::string str, char delimiter)
{
std::vector<std::string> ret;
size_t last = 0;
size_t next = 0;
std::string token;
while ((next = str.find(delimiter, last)) != std::string::npos)
{
token = str.substr(last, next - last);
if (next != last)
ret.push_back(token);
last = next + 1;
}
token = str.substr(last);
if (next != last)
ret.push_back(token);
return ret;
}
#ifdef __linux__
std::vector<IP_Address> DHCP_Server::GetGatewaysLinux(char* interfaceName)
{
///proc/net/route contains some information about gateway addresses,
//and separates the information about by each interface.
std::vector<IP_Address> collection;
std::vector<std::string> routeLines;
std::fstream route("/proc/net/route", std::ios::in);
if (route.fail())
{
route.close();
Console.Error("DHCP: Failed to open /proc/net/route");
return collection;
}
std::string line;
while (std::getline(route, line))
routeLines.push_back(line);
route.close();
//Columns are as follows (first-line header):
//Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
for (size_t i = 1; i < routeLines.size(); i++)
{
std::string line = routeLines[i];
if (line.rfind(interfaceName, 0) == 0)
{
std::vector<std::string> split = SplitString(line, '\t');
std::string gatewayIPHex = split[2];
int addressValue = std::stoi(gatewayIPHex, 0, 16);
//Skip device routes without valid NextHop IP address
if (addressValue != 0)
{
IP_Address gwIP = *(IP_Address*)&addressValue;
collection.push_back(gwIP);
}
}
}
return collection;
}
#elif defined(__FreeBSD__) || (__APPLE__)
std::vector<IP_Address> DHCP_Server::GetGatewaysBSD(char* interfaceName)
{
std::vector<IP_Address> 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<u8[]> buffer = std::make_unique<u8[]>(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<IP_Address> DHCP_Server::GetDNSUnix()
{
//On Linux and OSX, DNS is system wide, not adapter specific, so we can ignore adapter
// Parse /etc/resolv.conf for all of the "nameserver" entries.
// These are the DNS servers the machine is configured to use.
// On OSX, this file is not directly used by most processes for DNS
// queries/routing, but it is automatically generated instead, with
// the machine's DNS servers listed in it.
std::vector<IP_Address> collection;
std::fstream servers("/etc/resolv.conf", std::ios::in);
if (servers.fail())
{
servers.close();
Console.Error("DHCP: Failed to open /etc/resolv.conf");
return collection;
}
std::string line;
std::vector<std::string> serversLines;
while (std::getline(servers, line))
serversLines.push_back(line);
servers.close();
const IP_Address systemdDNS{127, 0, 0, 53};
for (size_t i = 1; i < serversLines.size(); i++)
{
std::string line = serversLines[i];
if (line.rfind("nameserver", 0) == 0)
{
std::vector<std::string> split = SplitString(line, '\t');
if (split.size() == 1)
split = SplitString(line, ' ');
std::string dns = split[1];
IP_Address address;
if (inet_pton(AF_INET, dns.c_str(), &address) != 1)
continue;
if (address == systemdDNS)
Console.Error("DHCP: systemd-resolved DNS server is not supported");
collection.push_back(address);
}
}
return collection;
}
#endif
#ifdef _WIN32
void DHCP_Server::AutoNetmask(PIP_ADAPTER_ADDRESSES adapter)
{
@ -316,23 +128,6 @@ namespace InternalServers
}
}
}
void DHCP_Server::AutoGateway(PIP_ADAPTER_ADDRESSES adapter)
{
if (adapter != nullptr)
{
PIP_ADAPTER_GATEWAY_ADDRESS address = adapter->FirstGatewayAddress;
while (address != nullptr && address->Address.lpSockaddr->sa_family != AF_INET)
address = address->Next;
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
gateway = *(IP_Address*)&sockaddr->sin_addr;
}
}
}
#elif defined(__POSIX__)
void DHCP_Server::AutoNetmask(ifaddrs* adapter)
{
@ -345,53 +140,28 @@ namespace InternalServers
}
}
}
void DHCP_Server::AutoGateway(ifaddrs* adapter)
{
if (adapter != nullptr)
{
#ifdef __linux__
std::vector<IP_Address> gateways = GetGatewaysLinux(adapter->ifa_name);
if (gateways.size() > 0)
gateway = gateways[0];
#elif defined(__FreeBSD__) || (__APPLE__)
std::vector<IP_Address> gateways = GetGatewaysBSD(adapter->ifa_name);
if (gateways.size() > 0)
gateway = gateways[0];
#else
Console.Error("DHCP: Unsupported OS, can't find Gateway");
#endif
}
}
#endif
#ifdef _WIN32
void DHCP_Server::AutoDNS(PIP_ADAPTER_ADDRESSES adapter, bool autoDNS1, bool autoDNS2)
void DHCP_Server::AutoGateway(PIP_ADAPTER_ADDRESSES adapter)
#elif defined(__POSIX__)
void DHCP_Server::AutoGateway(ifaddrs* adapter)
#endif
{
std::vector<IP_Address> dnsIPs;
std::vector<IP_Address> gateways = AdapterUtils::GetGateways(adapter);
if (adapter != nullptr)
{
PIP_ADAPTER_DNS_SERVER_ADDRESS address = adapter->FirstDnsServerAddress;
while (address != nullptr)
{
if (address->Address.lpSockaddr->sa_family == AF_INET)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
dnsIPs.push_back(*(IP_Address*)&sockaddr->sin_addr);
}
address = address->Next;
}
}
if (gateways.size() > 0)
gateway = gateways[0];
}
#ifdef _WIN32
void DHCP_Server::AutoDNS(PIP_ADAPTER_ADDRESSES adapter, bool autoDNS1, bool autoDNS2)
#elif defined(__POSIX__)
void DHCP_Server::AutoDNS(ifaddrs* adapter, bool autoDNS1, bool autoDNS2)
{
std::vector<IP_Address> dnsIPs = GetDNSUnix();
#endif
{
std::vector<IP_Address> dnsIPs = AdapterUtils::GetDNS(adapter);
if (autoDNS1)
{
//Auto DNS1

View File

@ -61,20 +61,9 @@ namespace InternalServers
PacketReader::IP::UDP::UDP_Packet* Recv();
bool Send(PacketReader::IP::UDP::UDP_Packet* payload);
#ifdef __linux__
static std::vector<PacketReader::IP::IP_Address> GetGatewaysLinux(char* interfaceName);
#elif defined(__FreeBSD__) || (__APPLE__)
static std::vector<PacketReader::IP::IP_Address> GetGatewaysBSD(char* interfaceName);
#endif
~DHCP_Server();
private:
#ifdef __POSIX__
static std::vector<std::string> SplitString(std::string str, char delimiter);
static std::vector<PacketReader::IP::IP_Address> GetDNSUnix();
#endif
#ifdef _WIN32
void AutoNetmask(PIP_ADAPTER_ADDRESSES adapter);
void AutoGateway(PIP_ADAPTER_ADDRESSES adapter);

View File

@ -38,6 +38,7 @@
#include "DEV9/PacketReader/IP/UDP/DNS/DNS_Packet.h"
#include "DEV9/DEV9.h"
#include "DEV9/AdapterUtils.h"
using namespace PacketReader;
using namespace PacketReader::IP;
@ -101,41 +102,13 @@ namespace InternalServers
#endif
{
localhostIP = {127, 0, 0, 1};
//Find IPv4 Address
#ifdef _WIN32
PIP_ADAPTER_UNICAST_ADDRESS address = nullptr;
if (adapter != nullptr)
{
PIP_ADAPTER_ADDRESSES info = (PIP_ADAPTER_ADDRESSES)adapter;
address = info->FirstUnicastAddress;
while (address != nullptr && address->Address.lpSockaddr->sa_family != AF_INET)
address = address->Next;
}
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
localhostIP = *(IP_Address*)&sockaddr->sin_addr;
}
std::optional<IP_Address> adapterIP = AdapterUtils::GetAdapterIP(adapter);
if (adapterIP.has_value())
localhostIP = adapterIP.value();
else
Console.Error("DEV9: Failed To Get Adapter IP");
#elif defined(__POSIX__)
sockaddr* address = nullptr;
if (adapter != nullptr)
{
ifaddrs* info = (ifaddrs*)adapter;
if (info->ifa_addr != nullptr && info->ifa_addr->sa_family == AF_INET)
address = info->ifa_addr;
}
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address;
localhostIP = *(IP_Address*)&sockaddr->sin_addr;
}
else
Console.Error("DEV9: Failed To Get Adapter IP");
#endif
LoadHostList();
}
@ -229,7 +202,7 @@ namespace InternalServers
bool DNS_Server::CheckHostList(std::string url, DNS_State* state)
{
std::transform(url.begin(), url.end(), url.begin(),
[](unsigned char c) { return std::tolower(c); });
[](unsigned char c) { return std::tolower(c); });
auto f = hosts.find(url);
if (f != hosts.end())

View File

@ -37,11 +37,16 @@
#include <stdarg.h>
#include "pcap_io.h"
#include "DEV9.h"
#include "AdapterUtils.h"
#include "net.h"
#ifndef PCAP_NETMASK_UNKNOWN
#define PCAP_NETMASK_UNKNOWN 0xffffffff
#endif
#ifdef _WIN32
#define PCAPPREFIX "\\Device\\NPF_"
#endif
pcap_t* adhandle;
pcap_dumper_t* dump_pcap = nullptr;
char errbuf[PCAP_ERRBUF_SIZE];
@ -58,94 +63,6 @@ ip_address ps2_ip;
mac_address ps2_mac;
mac_address host_mac;
#ifdef _WIN32
//IP_ADAPTER_ADDRESSES is a structure that contains ptrs to data in other regions
//of the buffer, se we need to return both so the caller can free the buffer
//after it's finished reading the needed data from IP_ADAPTER_ADDRESSES
bool PCAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer)
{
const int guidindex = strlen("\\Device\\NPF_");
int neededSize = 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapterInfo;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: GetWin32Adapter() buffer too small, resizing");
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return false;
pAdapterInfo = AdapterInfo.get();
do
{
if (0 == strcmp(pAdapterInfo->AdapterName, &name.c_str()[guidindex]))
{
*adapter = *pAdapterInfo;
buffer->swap(AdapterInfo);
return true;
}
pAdapterInfo = pAdapterInfo->Next;
} while (pAdapterInfo);
return false;
}
#elif defined(__POSIX__)
//getifaddrs is not POSIX, but is supported on MAC & Linux
bool PCAPGetIfAdapter(const std::string& name, ifaddrs* adapter, ifaddrs** buffer)
{
//Note, we don't support "any" adapter, but that also fails in pcap_io_init()
ifaddrs* adapterInfo;
ifaddrs* pAdapter;
int error = getifaddrs(&adapterInfo);
if (error)
return false;
pAdapter = adapterInfo;
do
{
if (pAdapter->ifa_addr != nullptr && pAdapter->ifa_addr->sa_family == AF_INET && strcmp(pAdapter->ifa_name, name.c_str()) == 0)
break;
pAdapter = pAdapter->ifa_next;
} while (pAdapter);
if (pAdapter != nullptr)
{
*adapter = *pAdapter;
*buffer = adapterInfo;
return true;
}
freeifaddrs(adapterInfo);
return false;
}
#endif
// Fetches the MAC address and prints it
int GetMACAddress(const std::string& adapter, mac_address* addr)
{
@ -154,7 +71,7 @@ int GetMACAddress(const std::string& adapter, mac_address* addr)
IP_ADAPTER_ADDRESSES adapterInfo;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
if (PCAPGetWin32Adapter(adapter, &adapterInfo, &buffer))
if (AdapterUtils::GetWin32Adapter(adapter, &adapterInfo, &buffer))
{
memcpy(addr, adapterInfo.PhysicalAddress, 6);
retval = 1;
@ -190,8 +107,13 @@ int pcap_io_init(const std::string& adapter, bool switched, mac_address virtual_
pcap_io_switched = switched;
#ifdef _WIN32
std::string pcapAdapter = PCAPPREFIX + adapter;
#else
std::string pcapAdapter = adapter;
#endif
/* Open the adapter */
if ((adhandle = pcap_open_live(adapter.c_str(), // name of the device
if ((adhandle = pcap_open_live(pcapAdapter.c_str(), // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
switched ? 1 : 0,
@ -390,7 +312,7 @@ PCAPAdapter::PCAPAdapter()
#ifdef _WIN32
IP_ADAPTER_ADDRESSES adapter;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
if (PCAPGetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
if (AdapterUtils::GetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
InitInternalServer(&adapter);
else
{
@ -400,7 +322,7 @@ PCAPAdapter::PCAPAdapter()
#elif defined(__POSIX__)
ifaddrs adapter;
ifaddrs* buffer;
if (PCAPGetIfAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
if (AdapterUtils::GetIfAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
{
InitInternalServer(&adapter);
freeifaddrs(buffer);
@ -462,14 +384,14 @@ void PCAPAdapter::reloadSettings()
#ifdef _WIN32
IP_ADAPTER_ADDRESSES adapter;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
if (PCAPGetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
if (AdapterUtils::GetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
ReloadInternalServer(&adapter);
else
ReloadInternalServer(nullptr);
#elif defined(__POSIX__)
ifaddrs adapter;
ifaddrs* buffer;
if (PCAPGetIfAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
if (AdapterUtils::GetIfAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
{
ReloadInternalServer(&adapter);
freeifaddrs(buffer);
@ -497,9 +419,7 @@ std::vector<AdapterEntry> PCAPAdapter::GetAdapters()
pcap_if_t* d;
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
return nic;
}
d = alldevs;
while (d != NULL)
@ -508,12 +428,19 @@ std::vector<AdapterEntry> PCAPAdapter::GetAdapters()
entry.type = Pcsx2Config::DEV9Options::NetApi::PCAP_Switched;
#ifdef _WIN32
//guid
entry.guid = std::string(d->name);
if (!StringUtil::StartsWith(d->name, PCAPPREFIX))
{
Console.Error("PCAP: Unexpected Device: ", d->name);
d = d->next;
continue;
}
entry.guid = std::string(&d->name[strlen(PCAPPREFIX)]);
IP_ADAPTER_ADDRESSES adapterInfo;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
if (PCAPGetWin32Adapter(entry.guid, &adapterInfo, &buffer))
if (AdapterUtils::GetWin32Adapter(entry.guid, &adapterInfo, &buffer))
entry.name = StringUtil::WideStringToUTF8String(std::wstring(adapterInfo.FriendlyName));
else
{
@ -527,7 +454,7 @@ std::vector<AdapterEntry> PCAPAdapter::GetAdapters()
std::unique_ptr<wchar_t[]> buf = std::make_unique<wchar_t[]>(len_buf);
MultiByteToWideChar(CP_ACP, 0, d->description, len_desc, buf.get(), len_buf);
entry.name = StringUtil::WideStringToUTF8String(std::wstring(buf.get()));
}
#else

View File

@ -17,7 +17,13 @@
#include "common/Assertions.h"
#include "common/StringUtil.h"
#ifdef __POSIX__
#ifdef _WIN32
#include <winsock2.h>
#include <iphlpapi.h>
#elif defined(__POSIX__)
#include <sys/types.h>
#include <ifaddrs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
@ -27,6 +33,7 @@
#endif
#include "sockets.h"
#include "AdapterUtils.h"
#include "DEV9.h"
#include "Sessions/ICMP_Session/ICMP_Session.h"
@ -158,7 +165,7 @@ SocketAdapter::SocketAdapter()
if (strcmp(EmuConfig.DEV9.EthDevice.c_str(), "Auto") != 0)
{
foundAdapter = GetWin32SelectedAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
foundAdapter = AdapterUtils::GetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
if (!foundAdapter)
{
@ -166,17 +173,9 @@ SocketAdapter::SocketAdapter()
return;
}
PIP_ADAPTER_UNICAST_ADDRESS address = nullptr;
address = adapter.FirstUnicastAddress;
while (address != nullptr && address->Address.lpSockaddr->sa_family != AF_INET)
address = address->Next;
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address->Address.lpSockaddr;
adapterIP = *(IP_Address*)&sockaddr->sin_addr;
}
std::optional<IP_Address> adIP = AdapterUtils::GetAdapterIP(&adapter);
if (adIP.has_value())
adapterIP = adIP.value();
else
{
Console.Error("DEV9: Socket: Failed To Get Adapter IP");
@ -185,7 +184,7 @@ SocketAdapter::SocketAdapter()
}
else
{
foundAdapter = GetWin32AutoAdapter(&adapter, &buffer);
foundAdapter = AdapterUtils::GetWin32AdapterAuto(&adapter, &buffer);
adapterIP = {0};
if (!foundAdapter)
@ -200,7 +199,7 @@ SocketAdapter::SocketAdapter()
if (strcmp(EmuConfig.DEV9.EthDevice.c_str(), "Auto") != 0)
{
foundAdapter = GetIfSelectedAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
foundAdapter = AdapterUtils::GetIfAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
if (!foundAdapter)
{
@ -208,16 +207,9 @@ SocketAdapter::SocketAdapter()
return;
}
sockaddr* address = nullptr;
if (adapter.ifa_addr != nullptr && adapter.ifa_addr->sa_family == AF_INET)
address = adapter.ifa_addr;
if (address != nullptr)
{
sockaddr_in* sockaddr = (sockaddr_in*)address;
adapterIP = *(IP_Address*)&sockaddr->sin_addr;
}
std::optional<IP_Address> adIP = AdapterUtils::GetAdapterIP(&adapter);
if (adIP.has_value())
adapterIP = adIP.value();
else
{
Console.Error("DEV9: Socket: Failed To Get Adapter IP");
@ -227,7 +219,7 @@ SocketAdapter::SocketAdapter()
}
else
{
foundAdapter = GetIfAutoAdapter(&adapter, &buffer);
foundAdapter = AdapterUtils::GetIfAdapterAuto(&adapter, &buffer);
adapterIP = {0};
if (!foundAdapter)
@ -297,228 +289,6 @@ SocketAdapter::SocketAdapter()
initialized = true;
}
#ifdef _WIN32
bool SocketAdapter::GetWin32SelectedAdapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer)
{
int neededSize = 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapterInfo;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: GetWin32Adapter() buffer too small, resizing");
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return false;
pAdapterInfo = AdapterInfo.get();
do
{
if (strcmp(pAdapterInfo->AdapterName, name.c_str()) == 0)
{
*adapter = *pAdapterInfo;
buffer->swap(AdapterInfo);
return true;
}
pAdapterInfo = pAdapterInfo->Next;
} while (pAdapterInfo);
return false;
}
bool SocketAdapter::GetWin32AutoAdapter(PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer)
{
int neededSize = 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapterInfo;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: PCAPGetWin32Adapter() buffer too small, resizing");
//
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return 0;
pAdapterInfo = AdapterInfo.get();
do
{
if (pAdapterInfo->IfType != IF_TYPE_SOFTWARE_LOOPBACK &&
pAdapterInfo->OperStatus == IfOperStatusUp)
{
//Search for an adapter with;
//IPv4 Address
//DNS
//Gateway
bool hasIPv4 = false;
bool hasDNS = false;
bool hasGateway = false;
//IPv4
PIP_ADAPTER_UNICAST_ADDRESS ipAddress = nullptr;
ipAddress = pAdapterInfo->FirstUnicastAddress;
while (ipAddress != nullptr && ipAddress->Address.lpSockaddr->sa_family != AF_INET)
ipAddress = ipAddress->Next;
if (ipAddress != nullptr)
hasIPv4 = true;
//DNS
PIP_ADAPTER_DNS_SERVER_ADDRESS dnsAddress = pAdapterInfo->FirstDnsServerAddress;
while (dnsAddress != nullptr && dnsAddress->Address.lpSockaddr->sa_family != AF_INET)
dnsAddress = dnsAddress->Next;
if (dnsAddress != nullptr)
hasDNS = true;
//Gateway
PIP_ADAPTER_GATEWAY_ADDRESS gatewayAddress = pAdapterInfo->FirstGatewayAddress;
while (gatewayAddress != nullptr && gatewayAddress->Address.lpSockaddr->sa_family != AF_INET)
gatewayAddress = gatewayAddress->Next;
if (gatewayAddress != nullptr)
hasGateway = true;
if (hasIPv4 && hasDNS && hasGateway)
{
*adapter = *pAdapterInfo;
buffer->swap(AdapterInfo);
return true;
}
}
pAdapterInfo = pAdapterInfo->Next;
} while (pAdapterInfo);
return false;
}
#elif defined(__POSIX__)
bool SocketAdapter::GetIfSelectedAdapter(const std::string& name, ifaddrs* adapter, ifaddrs** buffer)
{
ifaddrs* adapterInfo;
ifaddrs* pAdapter;
int error = getifaddrs(&adapterInfo);
if (error)
return false;
pAdapter = adapterInfo;
do
{
if (pAdapter->ifa_addr->sa_family == AF_INET && strcmp(pAdapter->ifa_name, name.c_str()) == 0)
break;
pAdapter = pAdapter->ifa_next;
} while (pAdapter);
if (pAdapter != nullptr)
{
*adapter = *pAdapter;
*buffer = adapterInfo;
return true;
}
freeifaddrs(adapterInfo);
return false;
}
bool SocketAdapter::GetIfAutoAdapter(ifaddrs* adapter, ifaddrs** buffer)
{
ifaddrs* adapterInfo;
ifaddrs* pAdapter;
int error = getifaddrs(&adapterInfo);
if (error)
return false;
pAdapter = adapterInfo;
do
{
if ((pAdapter->ifa_flags & IFF_LOOPBACK) == 0 &&
(pAdapter->ifa_flags & IFF_UP) != 0)
{
//Search for an adapter with;
//IPv4 Address
//Gateway
bool hasIPv4 = false;
bool hasGateway = false;
if (pAdapter->ifa_addr->sa_family == AF_INET)
hasIPv4 = true;
#ifdef __linux__
std::vector<IP_Address> gateways = InternalServers::DHCP_Server::GetGatewaysLinux(pAdapter->ifa_name);
if (gateways.size() > 0)
hasGateway = true;
#elif defined(__FreeBSD__) || (__APPLE__)
std::vector<IP_Address> gateways = InternalServers::DHCP_Server::GetGatewaysBSD(pAdapter->ifa_name);
if (gateways.size() > 0)
hasGateway = true;
#else
Console.Error("DHCP: Unsupported OS, can't find Gateway");
#endif
if (hasIPv4 && hasGateway)
{
*adapter = *pAdapter;
*buffer = adapterInfo;
return true;
}
}
pAdapter = pAdapter->ifa_next;
} while (pAdapter);
freeifaddrs(adapterInfo);
return false;
}
#endif
bool SocketAdapter::blocks()
{
return false;
@ -664,18 +434,18 @@ void SocketAdapter::reloadSettings()
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
if (strcmp(EmuConfig.DEV9.EthDevice.c_str(), "Auto") != 0)
foundAdapter = GetWin32SelectedAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
foundAdapter = AdapterUtils::GetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
else
foundAdapter = GetWin32AutoAdapter(&adapter, &buffer);
foundAdapter = AdapterUtils::GetWin32AdapterAuto(&adapter, &buffer);
#elif defined(__POSIX__)
ifaddrs adapter;
ifaddrs* buffer;
if (strcmp(EmuConfig.DEV9.EthDevice.c_str(), "Auto") != 0)
foundAdapter = GetIfSelectedAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
foundAdapter = AdapterUtils::GetIfAdapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer);
else
foundAdapter = GetIfAutoAdapter(&adapter, &buffer);
foundAdapter = AdapterUtils::GetIfAdapterAuto(&adapter, &buffer);
#endif
const IP_Address ps2IP = {internalIP.bytes[0], internalIP.bytes[1], internalIP.bytes[2], 100};

View File

@ -16,14 +16,6 @@
#pragma once
#include <vector>
#ifdef _WIN32
#include <winsock2.h>
#include <iphlpapi.h>
#elif defined(__POSIX__)
#include <sys/types.h>
#include <ifaddrs.h>
#endif
#include "net.h"
#include "PacketReader/IP/IP_Packet.h"
@ -64,14 +56,6 @@ public:
static AdapterOptions GetAdapterOptions();
private:
#ifdef _WIN32
bool GetWin32SelectedAdapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer);
bool GetWin32AutoAdapter(PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer);
#elif defined(__POSIX__)
bool GetIfSelectedAdapter(const std::string& name, ifaddrs* adapter, ifaddrs** buffer);
bool GetIfAutoAdapter(ifaddrs* adapter, ifaddrs** buffer);
#endif // _WIN32
bool SendIP(PacketReader::IP::IP_Packet* ipPkt);
bool SendICMP(Sessions::ConnectionKey Key, PacketReader::IP::IP_Packet* ipPkt);
bool SendIGMP(Sessions::ConnectionKey Key, PacketReader::IP::IP_Packet* ipPkt);

View File

@ -374,6 +374,7 @@
<ClCompile Include="DebugTools\MipsAssemblerTables.cpp" />
<ClCompile Include="DebugTools\MipsStackWalk.cpp" />
<ClCompile Include="DebugTools\SymbolMap.cpp" />
<ClCompile Include="DEV9\AdapterUtils.cpp" />
<ClCompile Include="DEV9\ATA\Commands\ATA_Command.cpp" />
<ClCompile Include="DEV9\ATA\Commands\ATA_CmdDMA.cpp" />
<ClCompile Include="DEV9\ATA\Commands\ATA_CmdExecuteDeviceDiag.cpp" />
@ -866,6 +867,7 @@
<ClInclude Include="DebugTools\MipsAssemblerTables.h" />
<ClInclude Include="DebugTools\MipsStackWalk.h" />
<ClInclude Include="DebugTools\SymbolMap.h" />
<ClInclude Include="DEV9\AdapterUtils.h" />
<ClInclude Include="DEV9\ATA\ATA.h" />
<ClInclude Include="DEV9\ATA\HddCreate.h" />
<ClInclude Include="DEV9\ATA\HddCreateWx.h" />

View File

@ -1196,6 +1196,9 @@
<ClCompile Include="SPU2\Wavedump_wav.cpp">
<Filter>System\Ps2\SPU2</Filter>
</ClCompile>
<ClCompile Include="DEV9\AdapterUtils.cpp">
<Filter>System\Ps2\DEV9</Filter>
</ClCompile>
<ClCompile Include="DEV9\ATA\Commands\ATA_Command.cpp">
<Filter>System\Ps2\DEV9\ATA\Commands</Filter>
</ClCompile>
@ -2407,6 +2410,9 @@
<ClInclude Include="Recording\Utilities\InputRecordingLogger.h">
<Filter>Recording\Utilities</Filter>
</ClInclude>
<ClInclude Include="DEV9\AdapterUtils.h">
<Filter>System\Ps2\DEV9</Filter>
</ClInclude>
<ClInclude Include="DEV9\ATA\ATA.h">
<Filter>System\Ps2\DEV9\ATA</Filter>
</ClInclude>

View File

@ -143,6 +143,7 @@
<ClCompile Include="DebugTools\MipsAssemblerTables.cpp" />
<ClCompile Include="DebugTools\MipsStackWalk.cpp" />
<ClCompile Include="DebugTools\SymbolMap.cpp" />
<ClCompile Include="DEV9\AdapterUtils.cpp" />
<ClCompile Include="DEV9\ATA\Commands\ATA_Command.cpp" />
<ClCompile Include="DEV9\ATA\Commands\ATA_CmdDMA.cpp" />
<ClCompile Include="DEV9\ATA\Commands\ATA_CmdExecuteDeviceDiag.cpp" />
@ -466,6 +467,7 @@
<ClInclude Include="DebugTools\MipsAssemblerTables.h" />
<ClInclude Include="DebugTools\MipsStackWalk.h" />
<ClInclude Include="DebugTools\SymbolMap.h" />
<ClInclude Include="DEV9\AdapterUtils.h" />
<ClInclude Include="DEV9\ATA\ATA.h" />
<ClInclude Include="DEV9\ATA\HddCreate.h" />
<ClInclude Include="DEV9\DEV9.h" />

View File

@ -845,6 +845,9 @@
<ClCompile Include="SPU2\Wavedump_wav.cpp">
<Filter>System\Ps2\SPU2</Filter>
</ClCompile>
<ClCompile Include="DEV9\AdapterUtils.cpp">
<Filter>System\Ps2\DEV9</Filter>
</ClCompile>
<ClCompile Include="DEV9\ATA\Commands\ATA_Command.cpp">
<Filter>System\Ps2\DEV9\ATA\Commands</Filter>
</ClCompile>
@ -1661,6 +1664,9 @@
<ClInclude Include="SPU2\spdif.h">
<Filter>System\Ps2\SPU2</Filter>
</ClInclude>
<ClInclude Include="DEV9\AdapterUtils.h">
<Filter>System\Ps2\DEV9</Filter>
</ClInclude>
<ClInclude Include="DEV9\ATA\ATA.h">
<Filter>System\Ps2\DEV9\ATA</Filter>
</ClInclude>