mirror of https://github.com/PCSX2/pcsx2.git
DEV9: Add internal DNS server
This commit is contained in:
parent
ca3b857f22
commit
24f97fd221
|
@ -355,6 +355,7 @@ set(pcsx2DEV9Sources
|
||||||
DEV9/ATA/ATA_Transfer.cpp
|
DEV9/ATA/ATA_Transfer.cpp
|
||||||
DEV9/ATA/HddCreate.cpp
|
DEV9/ATA/HddCreate.cpp
|
||||||
DEV9/InternalServers/DHCP_Server.cpp
|
DEV9/InternalServers/DHCP_Server.cpp
|
||||||
|
DEV9/InternalServers/DNS_Server.cpp
|
||||||
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.cpp
|
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.cpp
|
||||||
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.cpp
|
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.cpp
|
||||||
DEV9/PacketReader/IP/UDP/DNS/DNS_Classes.cpp
|
DEV9/PacketReader/IP/UDP/DNS/DNS_Classes.cpp
|
||||||
|
@ -366,6 +367,7 @@ set(pcsx2DEV9Sources
|
||||||
DEV9/PacketReader/NetLib.cpp
|
DEV9/PacketReader/NetLib.cpp
|
||||||
DEV9/smap.cpp
|
DEV9/smap.cpp
|
||||||
DEV9/DEV9.cpp
|
DEV9/DEV9.cpp
|
||||||
|
DEV9/DEV9Config.cpp
|
||||||
DEV9/flash.cpp
|
DEV9/flash.cpp
|
||||||
DEV9/pcap_io.cpp
|
DEV9/pcap_io.cpp
|
||||||
DEV9/net.cpp
|
DEV9/net.cpp
|
||||||
|
@ -378,6 +380,7 @@ set(pcsx2DEV9Headers
|
||||||
DEV9/ATA/HddCreate.h
|
DEV9/ATA/HddCreate.h
|
||||||
DEV9/DEV9.h
|
DEV9/DEV9.h
|
||||||
DEV9/InternalServers/DHCP_Server.cpp
|
DEV9/InternalServers/DHCP_Server.cpp
|
||||||
|
DEV9/InternalServers/DNS_Server.h
|
||||||
DEV9/net.h
|
DEV9/net.h
|
||||||
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.h
|
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.h
|
||||||
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.h
|
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.h
|
||||||
|
|
|
@ -15,3 +15,6 @@
|
||||||
|
|
||||||
void SaveConf();
|
void SaveConf();
|
||||||
void LoadConf();
|
void LoadConf();
|
||||||
|
|
||||||
|
void SaveDnsHosts();
|
||||||
|
void LoadDnsHosts();
|
||||||
|
|
|
@ -55,6 +55,14 @@ bool rx_fifo_can_rx();
|
||||||
#define HDD_MIN_GB 40
|
#define HDD_MIN_GB 40
|
||||||
#define HDD_MAX_GB 120
|
#define HDD_MAX_GB 120
|
||||||
|
|
||||||
|
struct ConfigHost
|
||||||
|
{
|
||||||
|
std::string Url;
|
||||||
|
std::string Desc;
|
||||||
|
u8 Address[4];
|
||||||
|
bool Enabled;
|
||||||
|
};
|
||||||
|
|
||||||
struct ConfigDEV9
|
struct ConfigDEV9
|
||||||
{
|
{
|
||||||
char Eth[256];
|
char Eth[256];
|
||||||
|
@ -69,6 +77,7 @@ struct ConfigDEV9
|
||||||
int AutoGateway;
|
int AutoGateway;
|
||||||
int AutoDNS1;
|
int AutoDNS1;
|
||||||
int AutoDNS2;
|
int AutoDNS2;
|
||||||
|
std::vector<ConfigHost> EthHosts;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
wchar_t Hdd[256];
|
wchar_t Hdd[256];
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
|
* Copyright (C) 2002-2021 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 "ghc/filesystem.h"
|
||||||
|
#include <wx/fileconf.h>
|
||||||
|
|
||||||
|
#include "DEV9.h"
|
||||||
|
#include "gui/AppConfig.h"
|
||||||
|
#include "common/IniInterface.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "ws2tcpip.h"
|
||||||
|
#elif defined(__POSIX__)
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void SaveDnsHosts()
|
||||||
|
{
|
||||||
|
std::unique_ptr<wxFileConfig> hini(OpenFileConfig(GetSettingsFolder().Combine(wxString("DEV9Hosts.ini")).GetFullPath()));
|
||||||
|
IniSaver ini((wxConfigBase*)hini.get());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < config.EthHosts.size(); i++)
|
||||||
|
{
|
||||||
|
std::wstring groupName(L"Host" + std::to_wstring(i));
|
||||||
|
ScopedIniGroup iniEntry(ini, groupName);
|
||||||
|
ConfigHost entry = config.EthHosts[i];
|
||||||
|
|
||||||
|
wxString url(entry.Url);
|
||||||
|
ini.Entry(L"Url", url);
|
||||||
|
//TODO UTF8(?)
|
||||||
|
wxString desc(entry.Desc);
|
||||||
|
ini.Entry(L"Desc", desc);
|
||||||
|
|
||||||
|
char addrBuff[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, entry.Address, addrBuff, INET_ADDRSTRLEN);
|
||||||
|
wxString address(addrBuff);
|
||||||
|
ini.Entry(L"Address", address);
|
||||||
|
|
||||||
|
ini.Entry(L"Enabled", entry.Enabled);
|
||||||
|
}
|
||||||
|
ini.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadDnsHosts()
|
||||||
|
{
|
||||||
|
wxFileName iniPath = GetSettingsFolder().Combine(wxString("DEV9Hosts.ini"));
|
||||||
|
config.EthHosts.clear();
|
||||||
|
//If no file exists, create one to provice an example config
|
||||||
|
if (!iniPath.FileExists())
|
||||||
|
{
|
||||||
|
//Load Default settings
|
||||||
|
ConfigHost exampleHost;
|
||||||
|
exampleHost.Url = "www.example.com";
|
||||||
|
exampleHost.Desc = "Set DNS to 192.0.2.1 to use this host list";
|
||||||
|
memset(exampleHost.Address, 0, 4);
|
||||||
|
exampleHost.Enabled = false;
|
||||||
|
config.EthHosts.push_back(exampleHost);
|
||||||
|
SaveDnsHosts();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<wxFileConfig> hini(OpenFileConfig(iniPath.GetFullPath()));
|
||||||
|
IniLoader ini((wxConfigBase*)hini.get());
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::wstring groupName(L"Host" + std::to_wstring(i));
|
||||||
|
ScopedIniGroup iniEntry(ini, groupName);
|
||||||
|
wxString tmp = wxEmptyString;
|
||||||
|
ini.Entry(L"Url", tmp, wxEmptyString);
|
||||||
|
//An empty url means we tried to read beyond end of the host list
|
||||||
|
if (tmp.IsEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
ConfigHost entry;
|
||||||
|
entry.Url = tmp.ToUTF8();
|
||||||
|
|
||||||
|
ini.Entry(L"Desc", tmp, wxEmptyString);
|
||||||
|
entry.Desc = tmp.ToUTF8();
|
||||||
|
|
||||||
|
ini.Entry(L"Address", tmp, L"0.0.0.0");
|
||||||
|
|
||||||
|
int ret = inet_pton(AF_INET, tmp.ToUTF8(), entry.Address);
|
||||||
|
//Only check Enabled if valid ip
|
||||||
|
if (ret != 1)
|
||||||
|
{
|
||||||
|
memset(entry.Address, 0, 4);
|
||||||
|
entry.Enabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ini.Entry(L"Enabled", entry.Enabled, false);
|
||||||
|
|
||||||
|
if (entry.Enabled)
|
||||||
|
Console.WriteLn("DEV9: Host entry %i: url %s mapped to %s", i, entry.Url.c_str(), tmp.ToStdString().c_str());
|
||||||
|
|
||||||
|
config.EthHosts.push_back(entry);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,435 @@
|
||||||
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
|
* Copyright (C) 2002-2021 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 <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#elif defined(__POSIX__)
|
||||||
|
//Note that getaddrinfo_a() exists which allows asynchronous operation
|
||||||
|
//however, that function is not standard POSIX, and is instead part of glibc
|
||||||
|
//So we will run with getaddrinfo() in a thread ourself
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "DNS_Server.h"
|
||||||
|
#include "DEV9/PacketReader/IP/UDP/UDP_Packet.h"
|
||||||
|
#include "DEV9/PacketReader/IP/UDP/DNS/DNS_Packet.h"
|
||||||
|
|
||||||
|
#include "DEV9/DEV9.h"
|
||||||
|
|
||||||
|
using namespace PacketReader;
|
||||||
|
using namespace PacketReader::IP;
|
||||||
|
using namespace PacketReader::IP::UDP;
|
||||||
|
using namespace PacketReader::IP::UDP::DNS;
|
||||||
|
|
||||||
|
namespace InternalServers
|
||||||
|
{
|
||||||
|
DNS_Server::DNS_State::DNS_State(int count, std::vector<std::string> dnsQuestions, DNS_Packet* dnsPacket, u16 port)
|
||||||
|
{
|
||||||
|
dns = dnsPacket;
|
||||||
|
counter.store(count);
|
||||||
|
questions = dnsQuestions;
|
||||||
|
clientPort = port;
|
||||||
|
|
||||||
|
//Prefill unordered_map, allowing use to modify it from seperate threads
|
||||||
|
//See https://en.cppreference.com/w/cpp/container#Thread_safety
|
||||||
|
//Different elements in the same container can be modified concurrently by different threads
|
||||||
|
for (size_t i = 0; i < dnsQuestions.size(); i++)
|
||||||
|
answers[dnsQuestions[i]] = {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
int DNS_Server::DNS_State::AddAnswer(const std::string& answer, IP_Address address)
|
||||||
|
{
|
||||||
|
answers[answer] = address;
|
||||||
|
return --counter;
|
||||||
|
}
|
||||||
|
int DNS_Server::DNS_State::AddNoAnswer(const std::string& answer)
|
||||||
|
{
|
||||||
|
return --counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, IP_Address> DNS_Server::DNS_State::GetAnswers()
|
||||||
|
{
|
||||||
|
return answers;
|
||||||
|
}
|
||||||
|
|
||||||
|
DNS_Server::DNS_Server(std::function<void()> receivedcallback)
|
||||||
|
: callback{receivedcallback}
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
|
||||||
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||||
|
|
||||||
|
WSADATA wsaData{0};
|
||||||
|
const int err = WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
if (err != 0)
|
||||||
|
Console.Error("DEV9: WSAStartup failed with error: %d\n", err);
|
||||||
|
else
|
||||||
|
wsa_init = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//We remap 127.0.0.1 to the PC's IP address
|
||||||
|
//We specificly use the address assigned to
|
||||||
|
//the adapter we are using
|
||||||
|
#ifdef _WIN32
|
||||||
|
void DNS_Server::Init(PIP_ADAPTER_ADDRESSES adapter)
|
||||||
|
#elif defined(__POSIX__)
|
||||||
|
void DNS_Server::Init(ifaddrs* adapter)
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNS_Server::LoadHostList()
|
||||||
|
{
|
||||||
|
hosts.clear();
|
||||||
|
for (size_t i = 0; i < config.EthHosts.size(); i++)
|
||||||
|
{
|
||||||
|
ConfigHost entry = config.EthHosts[i];
|
||||||
|
if (entry.Enabled)
|
||||||
|
hosts.insert_or_assign(entry.Url, *(IP_Address*)entry.Address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UDP_Packet* DNS_Server::Recv()
|
||||||
|
{
|
||||||
|
UDP_Packet* retPay;
|
||||||
|
if (dnsQueue.Dequeue(&retPay))
|
||||||
|
{
|
||||||
|
outstandingQueries--;
|
||||||
|
return retPay;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DNS_Server::Send(UDP_Packet* payload)
|
||||||
|
{
|
||||||
|
PayloadPtr* udpPayload = static_cast<PayloadPtr*>(payload->GetPayload());
|
||||||
|
DNS_Packet dns(udpPayload->data, udpPayload->GetLength());
|
||||||
|
|
||||||
|
if (dns.GetOpCode() == (u8)DNS_OPCode::Query && dns.questions.size() > 0 && dns.GetQR() == false)
|
||||||
|
{
|
||||||
|
std::vector<std::string> reqs;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < dns.questions.size(); i++)
|
||||||
|
{
|
||||||
|
DNS_QuestionEntry q = dns.questions[i];
|
||||||
|
if (q.entryType == 1 && q.entryClass == 1)
|
||||||
|
reqs.push_back(q.name);
|
||||||
|
else
|
||||||
|
Console.Error("DEV9: Unexpected question type of class, T: %d C: %d", q.entryType, q.entryClass);
|
||||||
|
}
|
||||||
|
if (reqs.size() == 0)
|
||||||
|
return true;
|
||||||
|
if (dns.GetTC() == true)
|
||||||
|
{
|
||||||
|
Console.Error("DEV9: Truncated DNS packet Not Supported");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DNS_Packet* ret = new DNS_Packet();
|
||||||
|
ret->id = dns.id; //TODO, drop duplicate requests based on ID
|
||||||
|
ret->SetQR(true);
|
||||||
|
ret->SetOpCode((u8)DNS_OPCode::Query);
|
||||||
|
ret->SetAA(false);
|
||||||
|
ret->SetTC(false);
|
||||||
|
ret->SetRD(true);
|
||||||
|
ret->SetRA(true);
|
||||||
|
ret->SetAD(false);
|
||||||
|
ret->SetCD(false);
|
||||||
|
ret->SetRCode((u8)DNS_RCode::NoError);
|
||||||
|
//Counts
|
||||||
|
ret->questions = dns.questions;
|
||||||
|
|
||||||
|
DNS_State* state = new DNS_State(reqs.size(), reqs, ret, payload->sourcePort);
|
||||||
|
outstandingQueries++;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < reqs.size(); i++)
|
||||||
|
{
|
||||||
|
if (CheckHostList(reqs[i], state))
|
||||||
|
continue;
|
||||||
|
GetHost(reqs[i], state);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.Error("DEV9: Unexpected DNS OPCode, Code: %s", dns.GetOpCode());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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); });
|
||||||
|
|
||||||
|
auto f = hosts.find(url);
|
||||||
|
if (f != hosts.end())
|
||||||
|
{
|
||||||
|
const int remaining = state->AddAnswer(url, hosts[url]);
|
||||||
|
Console.WriteLn("DEV9: DNS: %s found in hosts", url.c_str());
|
||||||
|
if (remaining == 0)
|
||||||
|
FinaliseDNS(state);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNS_Server::FinaliseDNS(DNS_State* state)
|
||||||
|
{
|
||||||
|
DNS_Packet* retPay = state->dns;
|
||||||
|
std::vector<std::string> reqs = state->questions;
|
||||||
|
std::unordered_map<std::string, IP_Address> answers = state->GetAnswers();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < reqs.size(); i++)
|
||||||
|
{
|
||||||
|
IP_Address ans = answers[reqs[i]];
|
||||||
|
if (ans.integer != 0)
|
||||||
|
{
|
||||||
|
//TODO, might not be effective on pcap
|
||||||
|
const IP_Address local{127, 0, 0, 1};
|
||||||
|
if (ans == local)
|
||||||
|
ans = localhostIP;
|
||||||
|
|
||||||
|
std::vector<u8> ansVector;
|
||||||
|
ansVector.resize(4);
|
||||||
|
*(IP_Address*)&ansVector[0] = ans;
|
||||||
|
DNS_ResponseEntry ansEntry(reqs[i], 1, 1, ansVector, 10800);
|
||||||
|
retPay->answers.push_back(ansEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retPay->SetRCode(2); //ServerFailure
|
||||||
|
}
|
||||||
|
|
||||||
|
const u16 clientPort = state->clientPort;
|
||||||
|
delete state;
|
||||||
|
|
||||||
|
if (retPay->GetLength() > 512)
|
||||||
|
{
|
||||||
|
Console.Error("DEV9: Generated DNS response too large, dropping");
|
||||||
|
delete retPay;
|
||||||
|
outstandingQueries--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UDP_Packet* retUdp = new UDP_Packet(retPay);
|
||||||
|
retUdp->sourcePort = 53;
|
||||||
|
retUdp->destinationPort = clientPort;
|
||||||
|
dnsQueue.Enqueue(retUdp);
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
DNS_Server::~DNS_Server()
|
||||||
|
{
|
||||||
|
//Block untill DNS finished &
|
||||||
|
//Delete entries in queue
|
||||||
|
while (outstandingQueries != 0)
|
||||||
|
{
|
||||||
|
UDP_Packet* retPay = nullptr;
|
||||||
|
if (!dnsQueue.Dequeue(&retPay))
|
||||||
|
{
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
std::this_thread::sleep_for(10ms);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete retPay;
|
||||||
|
outstandingQueries--;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (wsa_init)
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void DNS_Server::GetHost(std::string url, DNS_State* state)
|
||||||
|
{
|
||||||
|
//Need to convert to UTF16
|
||||||
|
const int size = MultiByteToWideChar(CP_UTF8, 0, url.c_str(), -1, nullptr, 0);
|
||||||
|
std::vector<wchar_t> converted_string(size);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, url.c_str(), -1, converted_string.data(), converted_string.size());
|
||||||
|
|
||||||
|
ADDRINFOEX hints{0};
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
|
||||||
|
GetAddrInfoExCallbackData* data = new GetAddrInfoExCallbackData();
|
||||||
|
data->state = state;
|
||||||
|
data->session = this;
|
||||||
|
data->url = url;
|
||||||
|
|
||||||
|
int ret = GetAddrInfoEx(converted_string.data(), nullptr, NS_ALL, 0, &hints, (ADDRINFOEX**)&data->result, nullptr, &data->overlapped, &DNS_Server::GetAddrInfoExCallback, &data->cancelHandle);
|
||||||
|
|
||||||
|
if (ret == WSA_IO_PENDING)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
GetAddrInfoExCallback(ret, -1, &data->overlapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __stdcall DNS_Server::GetAddrInfoExCallback(DWORD dwError, DWORD dwBytes, OVERLAPPED* lpOverlapped)
|
||||||
|
{
|
||||||
|
GetAddrInfoExCallbackData* data = reinterpret_cast<GetAddrInfoExCallbackData*>(lpOverlapped);
|
||||||
|
|
||||||
|
int remaining = -1;
|
||||||
|
switch (dwError)
|
||||||
|
{
|
||||||
|
case NO_ERROR:
|
||||||
|
{
|
||||||
|
ADDRINFOEX* addrInfo = (ADDRINFOEX*)data->result;
|
||||||
|
while (addrInfo != nullptr && addrInfo->ai_family != AF_INET)
|
||||||
|
addrInfo = addrInfo->ai_next;
|
||||||
|
|
||||||
|
if (addrInfo == nullptr)
|
||||||
|
{
|
||||||
|
Console.Error("DEV9: Internal DNS failed to find host %s", data->url.c_str());
|
||||||
|
Console.Error("DEV9: with unexpected error code %d", -1);
|
||||||
|
remaining = data->state->AddNoAnswer(data->url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_in* sockaddr = (sockaddr_in*)addrInfo->ai_addr;
|
||||||
|
remaining = data->state->AddAnswer(data->url, *(IP_Address*)&sockaddr->sin_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WSAHOST_NOT_FOUND:
|
||||||
|
case WSATRY_AGAIN: //Nonauthoritative host not found
|
||||||
|
Console.Error("DEV9: Internal DNS failed to find host %s", data->url.c_str());
|
||||||
|
remaining = data->state->AddNoAnswer(data->url);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Console.Error("DEV9: Internal DNS failed to find host %s", data->url.c_str());
|
||||||
|
Console.Error("DEV9: with unexpected error code %d", dwError);
|
||||||
|
remaining = data->state->AddNoAnswer(data->url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxAssert(remaining != -1);
|
||||||
|
|
||||||
|
if (remaining == 0)
|
||||||
|
data->session->FinaliseDNS(data->state);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
if (data->result != nullptr)
|
||||||
|
FreeAddrInfoEx((ADDRINFOEX*)data->result);
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
#elif defined(__POSIX__)
|
||||||
|
void DNS_Server::GetHost(std::string url, DNS_State* state)
|
||||||
|
{
|
||||||
|
//Need to spin up thread, pass the parms to it
|
||||||
|
|
||||||
|
std::thread GetHostThread(&DNS_Server::GetAddrInfoThread, this, url, state);
|
||||||
|
//detatch thread so that it can clean up itself
|
||||||
|
//we use another method of waiting for thread compleation
|
||||||
|
GetHostThread.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNS_Server::GetAddrInfoThread(std::string url, DNS_State* state)
|
||||||
|
{
|
||||||
|
addrinfo hints{0};
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
addrinfo* result = nullptr;
|
||||||
|
|
||||||
|
int error = getaddrinfo(url.c_str(), nullptr, &hints, &result);
|
||||||
|
int remaining = -1;
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
addrinfo* retInfo = result;
|
||||||
|
while (retInfo != nullptr && retInfo->ai_family != AF_INET)
|
||||||
|
retInfo = retInfo->ai_next;
|
||||||
|
|
||||||
|
if (retInfo == nullptr)
|
||||||
|
{
|
||||||
|
Console.Error("DEV9: Internal DNS failed to find host %s", url.c_str());
|
||||||
|
Console.Error("DEV9: with unexpected error code %d", -1);
|
||||||
|
remaining = state->AddNoAnswer(url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_in* sockaddr = (sockaddr_in*)retInfo->ai_addr;
|
||||||
|
remaining = state->AddAnswer(url, *(IP_Address*)&sockaddr->sin_addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EAI_NONAME:
|
||||||
|
case EAI_AGAIN: //Nonauthoritative host not found
|
||||||
|
Console.Error("DEV9: Internal DNS failed to find host %s", url.c_str());
|
||||||
|
remaining = state->AddNoAnswer(url);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Console.Error("DEV9: Internal DNS failed to find host %s", url.c_str());
|
||||||
|
Console.Error("DEV9: with unexpected error code %d", error);
|
||||||
|
remaining = state->AddNoAnswer(url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxAssert(remaining != -1);
|
||||||
|
|
||||||
|
if (remaining == 0)
|
||||||
|
FinaliseDNS(state);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
if (result != nullptr)
|
||||||
|
freeaddrinfo(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // namespace InternalServers
|
|
@ -0,0 +1,117 @@
|
||||||
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
|
* Copyright (C) 2002-2021 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
|
||||||
|
#include <atomic>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <minwinbase.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "DEV9/SimpleQueue.h"
|
||||||
|
|
||||||
|
#include "DEV9/PacketReader/IP/IP_Packet.h"
|
||||||
|
#include "DEV9/PacketReader/IP/UDP/UDP_Packet.h"
|
||||||
|
#include "DEV9/PacketReader/IP/UDP/DNS/DNS_Packet.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
#elif defined(__POSIX__)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace InternalServers
|
||||||
|
{
|
||||||
|
class DNS_Server
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class DNS_State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::atomic<int> counter;
|
||||||
|
|
||||||
|
std::vector<std::string> questions;
|
||||||
|
PacketReader::IP::UDP::DNS::DNS_Packet* dns;
|
||||||
|
u16 clientPort;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, PacketReader::IP::IP_Address> answers;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DNS_State(int count, std::vector<std::string> dnsQuestions, PacketReader::IP::UDP::DNS::DNS_Packet* dnsPacket, u16 port);
|
||||||
|
|
||||||
|
int AddAnswer(const std::string& answer, PacketReader::IP::IP_Address address);
|
||||||
|
int AddNoAnswer(const std::string& answer);
|
||||||
|
|
||||||
|
std::unordered_map<std::string, PacketReader::IP::IP_Address> GetAnswers();
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
bool wsa_init = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::function<void()> callback;
|
||||||
|
|
||||||
|
PacketReader::IP::IP_Address localhostIP{127, 0, 0, 1};
|
||||||
|
std::unordered_map<std::string, PacketReader::IP::IP_Address> hosts;
|
||||||
|
std::atomic<int> outstandingQueries{0};
|
||||||
|
SimpleQueue<PacketReader::IP::UDP::UDP_Packet*> dnsQueue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DNS_Server(std::function<void()> receivedcallback);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void Init(PIP_ADAPTER_ADDRESSES adapter);
|
||||||
|
#elif defined(__POSIX__)
|
||||||
|
void Init(ifaddrs* adapter);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Recv
|
||||||
|
PacketReader::IP::UDP::UDP_Packet* Recv();
|
||||||
|
//Expects a UDP_payload
|
||||||
|
bool Send(PacketReader::IP::UDP::UDP_Packet* payload);
|
||||||
|
|
||||||
|
//This might block for a large amount of time
|
||||||
|
//if destruction takes place during DNS request
|
||||||
|
//and the OS configured DNS server is unreachable
|
||||||
|
~DNS_Server();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void LoadHostList();
|
||||||
|
bool CheckHostList(std::string url, DNS_State* state);
|
||||||
|
void GetHost(std::string url, DNS_State* state);
|
||||||
|
void FinaliseDNS(DNS_State* state);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
struct GetAddrInfoExCallbackData
|
||||||
|
{
|
||||||
|
OVERLAPPED overlapped{0};
|
||||||
|
void* result = nullptr;
|
||||||
|
HANDLE cancelHandle = nullptr;
|
||||||
|
DNS_State* state;
|
||||||
|
DNS_Server* session;
|
||||||
|
std::string url;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __stdcall GetAddrInfoExCallback(DWORD dwError, DWORD dwBytes, OVERLAPPED* lpOverlapped);
|
||||||
|
#elif defined(__POSIX__)
|
||||||
|
void GetAddrInfoThread(std::string url, DNS_State* state);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
} // namespace InternalServers
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "DEV9/DEV9.h"
|
#include "DEV9/DEV9.h"
|
||||||
#include "gui/AppConfig.h"
|
#include "gui/AppConfig.h"
|
||||||
|
#include "DEV9/Config.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -31,7 +32,6 @@
|
||||||
|
|
||||||
void SaveConf()
|
void SaveConf()
|
||||||
{
|
{
|
||||||
|
|
||||||
xmlDocPtr doc = NULL; /* document pointer */
|
xmlDocPtr doc = NULL; /* document pointer */
|
||||||
xmlNodePtr root_node = NULL;
|
xmlNodePtr root_node = NULL;
|
||||||
char buff[256];
|
char buff[256];
|
||||||
|
@ -124,11 +124,12 @@ void SaveConf()
|
||||||
*have been allocated by the parser.
|
*have been allocated by the parser.
|
||||||
*/
|
*/
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
|
|
||||||
|
SaveDnsHosts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadConf()
|
void LoadConf()
|
||||||
{
|
{
|
||||||
|
|
||||||
const std::string file(GetSettingsFolder().Combine(wxString("DEV9.cfg")).GetFullPath());
|
const std::string file(GetSettingsFolder().Combine(wxString("DEV9.cfg")).GetFullPath());
|
||||||
if (-1 == access(file.c_str(), F_OK))
|
if (-1 == access(file.c_str(), F_OK))
|
||||||
return;
|
return;
|
||||||
|
@ -222,4 +223,6 @@ void LoadConf()
|
||||||
// free(configFile);
|
// free(configFile);
|
||||||
xmlFreeDoc(doc);
|
xmlFreeDoc(doc);
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
|
|
||||||
|
LoadDnsHosts();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "DEV9/DEV9.h"
|
#include "DEV9/DEV9.h"
|
||||||
#include "gui/AppConfig.h"
|
#include "gui/AppConfig.h"
|
||||||
|
#include "DEV9/Config.h"
|
||||||
|
|
||||||
#include "ws2tcpip.h"
|
#include "ws2tcpip.h"
|
||||||
|
|
||||||
|
@ -81,13 +82,18 @@ void SaveConf()
|
||||||
|
|
||||||
WritePrivateProfileInt(L"DEV9", L"ethEnable", config.ethEnable, file.c_str());
|
WritePrivateProfileInt(L"DEV9", L"ethEnable", config.ethEnable, file.c_str());
|
||||||
WritePrivateProfileInt(L"DEV9", L"hddEnable", config.hddEnable, file.c_str());
|
WritePrivateProfileInt(L"DEV9", L"hddEnable", config.hddEnable, file.c_str());
|
||||||
|
|
||||||
|
SaveDnsHosts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadConf()
|
void LoadConf()
|
||||||
{
|
{
|
||||||
const std::wstring file(GetSettingsFolder().Combine(wxString("DEV9.cfg")).GetFullPath());
|
const std::wstring file(GetSettingsFolder().Combine(wxString("DEV9.cfg")).GetFullPath());
|
||||||
if (FileExists(file.c_str()) == false)
|
if (FileExists(file.c_str()) == false)
|
||||||
|
{
|
||||||
|
LoadDnsHosts();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wchar_t addrBuff[INET_ADDRSTRLEN] = {0};
|
wchar_t addrBuff[INET_ADDRSTRLEN] = {0};
|
||||||
wchar_t wEth[sizeof(config.Eth)] = {0};
|
wchar_t wEth[sizeof(config.Eth)] = {0};
|
||||||
|
@ -123,4 +129,6 @@ void LoadConf()
|
||||||
|
|
||||||
config.ethEnable = GetPrivateProfileInt(L"DEV9", L"ethEnable", config.ethEnable, file.c_str());
|
config.ethEnable = GetPrivateProfileInt(L"DEV9", L"ethEnable", config.ethEnable, file.c_str());
|
||||||
config.hddEnable = GetPrivateProfileInt(L"DEV9", L"hddEnable", config.hddEnable, file.c_str());
|
config.hddEnable = GetPrivateProfileInt(L"DEV9", L"hddEnable", config.hddEnable, file.c_str());
|
||||||
|
|
||||||
|
LoadDnsHosts();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#if defined(__POSIX__)
|
#if defined(__POSIX__)
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "DEV9.h"
|
#include "DEV9.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -279,6 +280,8 @@ void NetAdapter::InitInternalServer(ifaddrs* adapter)
|
||||||
if (config.InterceptDHCP)
|
if (config.InterceptDHCP)
|
||||||
dhcpServer.Init(adapter);
|
dhcpServer.Init(adapter);
|
||||||
|
|
||||||
|
dnsServer.Init(adapter);
|
||||||
|
|
||||||
if (blocks())
|
if (blocks())
|
||||||
{
|
{
|
||||||
internalRxThreadRunning.store(true);
|
internalRxThreadRunning.store(true);
|
||||||
|
@ -297,6 +300,8 @@ void NetAdapter::ReloadInternalServer(ifaddrs* adapter)
|
||||||
|
|
||||||
if (config.InterceptDHCP)
|
if (config.InterceptDHCP)
|
||||||
dhcpServer.Init(adapter);
|
dhcpServer.Init(adapter);
|
||||||
|
|
||||||
|
dnsServer.Init(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetAdapter::InternalServerRecv(NetPacket* pkt)
|
bool NetAdapter::InternalServerRecv(NetPacket* pkt)
|
||||||
|
@ -314,6 +319,22 @@ bool NetAdapter::InternalServerRecv(NetPacket* pkt)
|
||||||
frame.WritePacket(pkt);
|
frame.WritePacket(pkt);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IP_Payload* ippay;
|
||||||
|
ippay = dnsServer.Recv();
|
||||||
|
if (ippay != nullptr)
|
||||||
|
{
|
||||||
|
IP_Packet* ippkt = new IP_Packet(ippay);
|
||||||
|
ippkt->destinationIP = ps2IP;
|
||||||
|
ippkt->sourceIP = internalIP;
|
||||||
|
EthernetFrame frame(ippkt);
|
||||||
|
memcpy(frame.sourceMAC, internalMAC, 6);
|
||||||
|
memcpy(frame.destinationMAC, ps2MAC, 6);
|
||||||
|
frame.protocol = (u16)EtherType::IPv4;
|
||||||
|
frame.WritePacket(pkt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,6 +361,19 @@ bool NetAdapter::InternalServerSend(NetPacket* pkt)
|
||||||
|
|
||||||
if (ippkt.destinationIP == internalIP)
|
if (ippkt.destinationIP == internalIP)
|
||||||
{
|
{
|
||||||
|
if (ippkt.protocol == (u16)IP_Type::UDP)
|
||||||
|
{
|
||||||
|
ps2IP = ippkt.sourceIP;
|
||||||
|
|
||||||
|
IP_PayloadPtr* ipPayload = static_cast<IP_PayloadPtr*>(ippkt.GetPayload());
|
||||||
|
UDP_Packet udppkt(ipPayload->data, ipPayload->GetLength());
|
||||||
|
|
||||||
|
if (udppkt.destinationPort == 53)
|
||||||
|
{
|
||||||
|
//Send DNS
|
||||||
|
return dnsServer.Send(&udppkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "PacketReader/IP/IP_Address.h"
|
#include "PacketReader/IP/IP_Address.h"
|
||||||
#include "InternalServers/DHCP_Server.h"
|
#include "InternalServers/DHCP_Server.h"
|
||||||
|
#include "InternalServers/DNS_Server.h"
|
||||||
|
|
||||||
struct ConfigDEV9;
|
struct ConfigDEV9;
|
||||||
|
|
||||||
|
@ -87,6 +88,8 @@ protected:
|
||||||
static const u8 internalMAC[6];
|
static const u8 internalMAC[6];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//Only set if packet sent to the internal IP address
|
||||||
|
PacketReader::IP::IP_Address ps2IP{0};
|
||||||
std::thread internalRxThread;
|
std::thread internalRxThread;
|
||||||
std::atomic<bool> internalRxThreadRunning{false};
|
std::atomic<bool> internalRxThreadRunning{false};
|
||||||
|
|
||||||
|
@ -95,6 +98,7 @@ private:
|
||||||
bool internalRxHasData = false;
|
bool internalRxHasData = false;
|
||||||
|
|
||||||
InternalServers::DHCP_Server dhcpServer = InternalServers::DHCP_Server([&] { InternalSignalReceived(); });
|
InternalServers::DHCP_Server dhcpServer = InternalServers::DHCP_Server([&] { InternalSignalReceived(); });
|
||||||
|
InternalServers::DNS_Server dnsServer = InternalServers::DNS_Server([&] { InternalSignalReceived(); });
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NetAdapter();
|
NetAdapter();
|
||||||
|
|
|
@ -276,9 +276,11 @@
|
||||||
<ClCompile Include="DEV9\ATA\ATA_State.cpp" />
|
<ClCompile Include="DEV9\ATA\ATA_State.cpp" />
|
||||||
<ClCompile Include="DEV9\ATA\ATA_Transfer.cpp" />
|
<ClCompile Include="DEV9\ATA\ATA_Transfer.cpp" />
|
||||||
<ClCompile Include="DEV9\ATA\HddCreate.cpp" />
|
<ClCompile Include="DEV9\ATA\HddCreate.cpp" />
|
||||||
|
<ClCompile Include="DEV9\DEV9Config.cpp" />
|
||||||
<ClCompile Include="DEV9\DEV9.cpp" />
|
<ClCompile Include="DEV9\DEV9.cpp" />
|
||||||
<ClCompile Include="DEV9\flash.cpp" />
|
<ClCompile Include="DEV9\flash.cpp" />
|
||||||
<ClCompile Include="DEV9\InternalServers\DHCP_Server.cpp" />
|
<ClCompile Include="DEV9\InternalServers\DHCP_Server.cpp" />
|
||||||
|
<ClCompile Include="DEV9\InternalServers\DNS_Server.cpp" />
|
||||||
<ClCompile Include="DEV9\PacketReader\EthernetFrame.cpp" />
|
<ClCompile Include="DEV9\PacketReader\EthernetFrame.cpp" />
|
||||||
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp" />
|
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp" />
|
||||||
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Packet.cpp" />
|
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Packet.cpp" />
|
||||||
|
@ -724,6 +726,7 @@
|
||||||
<ClInclude Include="DEV9\Config.h" />
|
<ClInclude Include="DEV9\Config.h" />
|
||||||
<ClInclude Include="DEV9\DEV9.h" />
|
<ClInclude Include="DEV9\DEV9.h" />
|
||||||
<ClInclude Include="DEV9\InternalServers\DHCP_Server.h" />
|
<ClInclude Include="DEV9\InternalServers\DHCP_Server.h" />
|
||||||
|
<ClInclude Include="DEV9\InternalServers\DNS_Server.h" />
|
||||||
<ClInclude Include="DEV9\net.h" />
|
<ClInclude Include="DEV9\net.h" />
|
||||||
<ClInclude Include="DEV9\PacketReader\EthernetFrame.h" />
|
<ClInclude Include="DEV9\PacketReader\EthernetFrame.h" />
|
||||||
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.h" />
|
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.h" />
|
||||||
|
|
|
@ -1175,6 +1175,9 @@
|
||||||
<ClCompile Include="DEV9\ATA\HddCreate.cpp">
|
<ClCompile Include="DEV9\ATA\HddCreate.cpp">
|
||||||
<Filter>System\Ps2\DEV9\ATA</Filter>
|
<Filter>System\Ps2\DEV9\ATA</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="DEV9\DEV9Config.cpp">
|
||||||
|
<Filter>System\Ps2\DEV9</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="DEV9\DEV9.cpp">
|
<ClCompile Include="DEV9\DEV9.cpp">
|
||||||
<Filter>System\Ps2\DEV9</Filter>
|
<Filter>System\Ps2\DEV9</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -1184,6 +1187,9 @@
|
||||||
<ClCompile Include="DEV9\InternalServers\DHCP_Server.cpp">
|
<ClCompile Include="DEV9\InternalServers\DHCP_Server.cpp">
|
||||||
<Filter>System\Ps2\DEV9\InternalServers</Filter>
|
<Filter>System\Ps2\DEV9\InternalServers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="DEV9\InternalServers\DNS_Server.cpp">
|
||||||
|
<Filter>System\Ps2\DEV9\InternalServers</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp">
|
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp">
|
||||||
<Filter>System\Ps2\DEV9\PacketReader\IP\UDP\DHCP</Filter>
|
<Filter>System\Ps2\DEV9\PacketReader\IP\UDP\DHCP</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -2233,6 +2239,9 @@
|
||||||
<ClInclude Include="DEV9\InternalServers\DHCP_Server.h">
|
<ClInclude Include="DEV9\InternalServers\DHCP_Server.h">
|
||||||
<Filter>System\Ps2\DEV9\InternalServers</Filter>
|
<Filter>System\Ps2\DEV9\InternalServers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="DEV9\InternalServers\DNS_Server.h">
|
||||||
|
<Filter>System\Ps2\DEV9\InternalServers</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="DEV9\net.h">
|
<ClInclude Include="DEV9\net.h">
|
||||||
<Filter>System\Ps2\DEV9</Filter>
|
<Filter>System\Ps2\DEV9</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
Loading…
Reference in New Issue