This commit is contained in:
TheLastRar 2024-12-31 11:25:33 +07:00 committed by GitHub
commit 404f541367
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 410 additions and 66 deletions

View File

@ -286,6 +286,7 @@ set(pcsx2DEV9Sources
DEV9/ATA/ATA_State.cpp
DEV9/ATA/ATA_Transfer.cpp
DEV9/ATA/HddCreate.cpp
DEV9/InternalServers/ARP_Logger.cpp
DEV9/InternalServers/DHCP_Logger.cpp
DEV9/InternalServers/DHCP_Server.cpp
DEV9/InternalServers/DNS_Logger.cpp
@ -325,6 +326,7 @@ set(pcsx2DEV9Headers
DEV9/ATA/ATA.h
DEV9/ATA/HddCreate.h
DEV9/DEV9.h
DEV9/InternalServers/ARP_Logger.h
DEV9/InternalServers/DHCP_Logger.h
DEV9/InternalServers/DHCP_Server.h
DEV9/InternalServers/DNS_Logger.h

View File

@ -0,0 +1,92 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "ARP_Logger.h"
#include "DEV9/PacketReader/EthernetFrame.h"
#include "common/Console.h"
using namespace PacketReader;
using namespace PacketReader::ARP;
namespace InternalServers
{
void ARP_Logger::InspectRecv(Payload* payload)
{
ARP_Packet* arp = static_cast<ARP_Packet*>(payload);
LogPacket(arp);
}
void ARP_Logger::InspectSend(Payload* payload)
{
ARP_Packet* arp = static_cast<ARP_Packet*>(payload);
LogPacket(arp);
}
std::string ARP_Logger::ArrayToString(const std::unique_ptr<u8[]>& data, int length)
{
std::string str;
if (length != 0)
{
str.reserve(length * 4);
for (size_t i = 0; i < length; i++)
str += std::to_string(data[i]) + ":";
str.pop_back();
} //else leave string empty
return str;
}
const char* ARP_Logger::HardwareTypeToString(u8 op)
{
switch (op)
{
case 1:
return "Ethernet";
case 6:
return "IEEE 802";
default:
return "Unknown";
}
}
const char* ARP_Logger::ProtocolToString(u16 protocol)
{
switch (protocol)
{
case static_cast<u16>(EtherType::IPv4):
return "IPv4";
case static_cast<u16>(EtherType::ARP):
return "ARP";
default:
return "Unknown";
}
}
const char* ARP_Logger::OperationToString(u16 op)
{
switch (op)
{
case 1:
return "Request";
case 2:
return "Reply";
default:
return "Unknown";
}
}
void ARP_Logger::LogPacket(ARP_Packet* arp)
{
Console.WriteLn("DEV9: ARP: Hardware Type %s (%i)", HardwareTypeToString(arp->hardwareType), arp->hardwareType);
Console.WriteLn("DEV9: ARP: Protocol %s (%i)", ProtocolToString(arp->protocol), arp->protocol);
Console.WriteLn("DEV9: ARP: Operation %s (%i)", OperationToString(arp->op), arp->op);
Console.WriteLn("DEV9: ARP: Hardware Length %i", arp->hardwareAddressLength);
Console.WriteLn("DEV9: ARP: Protocol Length %i", arp->protocolAddressLength);
Console.WriteLn("DEV9: ARP: Sender Hardware Address %s", ArrayToString(arp->senderHardwareAddress, arp->hardwareAddressLength).c_str());
Console.WriteLn("DEV9: ARP: Sender Protocol Address %s", ArrayToString(arp->senderProtocolAddress, arp->protocolAddressLength).c_str());
Console.WriteLn("DEV9: ARP: Target Hardware Address %s", ArrayToString(arp->targetHardwareAddress, arp->hardwareAddressLength).c_str());
Console.WriteLn("DEV9: ARP: Target Protocol Address %s", ArrayToString(arp->targetProtocolAddress, arp->protocolAddressLength).c_str());
}
} // namespace InternalServers

View File

@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "DEV9/PacketReader/Payload.h"
#include "DEV9/PacketReader/ARP/ARP_Packet.h"
namespace InternalServers
{
class ARP_Logger
{
public:
ARP_Logger(){};
//Expects a ARP_payload
void InspectRecv(PacketReader::Payload* payload);
//Expects a ARP_payload
void InspectSend(PacketReader::Payload* payload);
private:
std::string ArrayToString(const std::unique_ptr<u8[]>& data, int length);
const char* HardwareTypeToString(u8 op); // Same as DHCP
const char* ProtocolToString(u16 protocol);
const char* OperationToString(u16 op);
void LogPacket(PacketReader::ARP::ARP_Packet* payload);
};
} // namespace InternalServers

View File

@ -137,6 +137,38 @@ namespace InternalServers
if (gateways.size() > 0)
gateway = gateways[0];
/*
* Some VPN adapters will present a subnet mask of 255.255.255.255 and omit setting a gateway.
* This is used for point-point links where the destination device handles routing out of the network.
* PS2 software, howver, expects a valid gateway for packets leaving the network.
* A possible hackfix was to set the gateway to the PS2 IP, however, some software rejects this.
* Thus the only solution is to expand the netmask and add a fake gateway using the other IP.
* This is a mostly PCAP exclusive issue, I've only seen such networks with VPN devices,
* which don't like being bridged, preventing TAP from being used with them.
* Sockets (currently) uses its own internal network, and thus would be unaffected.
*/
else if (netmask == IP_Address{{{255, 255, 255, 255}}})
{
// Expand the netmask to allow for a gateway
netmask = {{{255, 255, 255, 252}}};
// Need to ensure our IP isn't the broadcast IP
while (true)
{
// Shift is busted
const IP_Address bc = ps2IP | ~netmask;
if (ps2IP == bc)
netmask.integer = htonl(ntohl(netmask.integer) << 1);
else
break;
}
// Pick a free IP for our gateway
gateway = (ps2IP & netmask);
gateway.integer = htonl(ntohl(gateway.integer) + 1);
while (gateway == ps2IP)
gateway.integer = htonl(ntohl(gateway.integer) + 1);
}
}
#ifdef _WIN32
@ -325,7 +357,10 @@ namespace InternalServers
retPay->options.push_back(new DHCPopDnsName("PCSX2"));
break;
case 28:
retPay->options.push_back(new DHCPopBCIP(broadcastIP));
if (broadcastIP.integer != 0)
{
retPay->options.push_back(new DHCPopBCIP(broadcastIP));
}
break;
case 50:
retPay->options.push_back(new DHCPopREQIP(ps2IP));

View File

@ -24,8 +24,8 @@ namespace InternalServers
{
public:
PacketReader::IP::IP_Address ps2IP;
PacketReader::IP::IP_Address gateway;
PacketReader::IP::IP_Address broadcastIP;
PacketReader::IP::IP_Address gateway{};
PacketReader::IP::IP_Address broadcastIP{};
private:
std::function<void()> callback;

View File

@ -17,5 +17,30 @@ namespace PacketReader::IP
bool operator==(const IP_Address& other) const { return this->integer == other.integer; }
bool operator!=(const IP_Address& other) const { return this->integer != other.integer; }
IP_Address operator~() const
{
IP_Address ret;
ret.integer = ~this->integer;
return ret;
}
IP_Address operator&(const IP_Address& other) const
{
IP_Address ret;
ret.integer = this->integer & other.integer;
return ret;
}
IP_Address operator|(const IP_Address& other) const
{
IP_Address ret;
ret.integer = this->integer | other.integer;
return ret;
}
IP_Address operator^(const IP_Address& other) const
{
IP_Address ret;
ret.integer = this->integer ^ other.integer;
return ret;
}
};
} // namespace PacketReader::IP

View File

@ -100,7 +100,7 @@ bool load_pcap()
if (fp_##name == nullptr) \
{ \
FreeLibrary(hpcap); \
Console.Error("DEV9: %s not found", #name); \
Console.Error("DEV9: PCAP: %s not found", #name); \
hpcap = nullptr; \
return false; \
}

View File

@ -17,6 +17,7 @@
#include "sockets.h"
#include "PacketReader/EthernetFrame.h"
#include "PacketReader/ARP/ARP_Packet.h"
#include "PacketReader/IP/IP_Packet.h"
#include "PacketReader/IP/UDP/UDP_Packet.h"
@ -160,6 +161,7 @@ void TermNet()
}
using namespace PacketReader;
using namespace PacketReader::ARP;
using namespace PacketReader::IP;
using namespace PacketReader::IP::UDP;
@ -233,6 +235,13 @@ void NetAdapter::InspectSend(NetPacket* pkt)
}
}
}
if (frame.protocol == static_cast<u16>(EtherType::ARP))
{
Console.WriteLn("DEV9: ARP: Packet Sent");
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
ARP_Packet arppkt(payload->data, payload->GetLength());
arpLogger.InspectSend(&arppkt);
}
}
}
void NetAdapter::InspectRecv(NetPacket* pkt)
@ -265,6 +274,13 @@ void NetAdapter::InspectRecv(NetPacket* pkt)
}
}
}
if (frame.protocol == static_cast<u16>(EtherType::ARP))
{
Console.WriteLn("DEV9: ARP: Packet Received");
PayloadPtr* payload = static_cast<PayloadPtr*>(frame.GetPayload());
ARP_Packet arppkt(payload->data, payload->GetLength());
arpLogger.InspectRecv(&arppkt);
}
}
}

View File

@ -24,6 +24,7 @@
#include "PacketReader/MAC_Address.h"
#include "PacketReader/IP/IP_Address.h"
#include "InternalServers/ARP_Logger.h"
#include "InternalServers/DHCP_Logger.h"
#include "InternalServers/DHCP_Server.h"
#include "InternalServers/DNS_Logger.h"
@ -100,6 +101,7 @@ private:
bool dhcpOn = false;
protected:
InternalServers::ARP_Logger arpLogger;
InternalServers::DHCP_Logger dhcpLogger;
InternalServers::DHCP_Server dhcpServer = InternalServers::DHCP_Server([&] { InternalSignalReceived(); });
InternalServers::DNS_Logger dnsLogger;

View File

@ -17,8 +17,8 @@
#include "DEV9.h"
#include "AdapterUtils.h"
#include "net.h"
#include "PacketReader/EthernetFrame.h"
#include "PacketReader/EthernetFrameEditor.h"
#include "PacketReader/ARP/ARP_Packet.h"
#include "PacketReader/ARP/ARP_PacketEditor.h"
#ifndef PCAP_NETMASK_UNKNOWN
#define PCAP_NETMASK_UNKNOWN 0xffffffff
@ -52,7 +52,7 @@ PCAPAdapter::PCAPAdapter()
if (!InitPCAP(pcapAdapter, switched))
{
Console.Error("DEV9: Can't open Device '%s'", EmuConfig.DEV9.EthDevice.c_str());
Console.Error("DEV9: PCAP: Can't open Device '%s'", EmuConfig.DEV9.EthDevice.c_str());
return;
}
@ -63,33 +63,39 @@ PCAPAdapter::PCAPAdapter()
if (foundAdapter)
adMAC = AdapterUtils::GetAdapterMAC(&adapter);
else
Console.Error("DEV9: Failed to get adapter information");
Console.Error("DEV9: PCAP: Failed to get adapter information");
if (adMAC.has_value())
// DLT_RAW adapters may not have a MAC address
// Just use the default MAC in such case
// SetMACSwitchedFilter will also fail on such adapters
if (!ipOnly)
{
hostMAC = adMAC.value();
MAC_Address newMAC = ps2MAC;
if (adMAC.has_value())
{
hostMAC = adMAC.value();
MAC_Address newMAC = ps2MAC;
//Lets take the hosts last 2 bytes to make it unique on Xlink
newMAC.bytes[5] = hostMAC.bytes[4];
newMAC.bytes[4] = hostMAC.bytes[5];
//Lets take the hosts last 2 bytes to make it unique on Xlink
newMAC.bytes[5] = hostMAC.bytes[4];
newMAC.bytes[4] = hostMAC.bytes[5];
SetMACAddress(&newMAC);
}
else
{
Console.Error("DEV9: Failed to get MAC address for adapter");
pcap_close(hpcap);
hpcap = nullptr;
return;
}
SetMACAddress(&newMAC);
}
else
{
Console.Error("DEV9: PCAP: Failed to get MAC address for adapter");
pcap_close(hpcap);
hpcap = nullptr;
return;
}
if (switched && !SetMACSwitchedFilter(ps2MAC))
{
pcap_close(hpcap);
hpcap = nullptr;
Console.Error("DEV9: Can't open Device '%s'", EmuConfig.DEV9.EthDevice.c_str());
return;
if (switched && !SetMACSwitchedFilter(ps2MAC))
{
pcap_close(hpcap);
hpcap = nullptr;
Console.Error("DEV9: PCAP: Can't open Device '%s'", EmuConfig.DEV9.EthDevice.c_str());
return;
}
}
if (foundAdapter)
@ -118,6 +124,16 @@ bool PCAPAdapter::recv(NetPacket* pkt)
if (!blocking && NetAdapter::recv(pkt))
return true;
EthernetFrame* bFrame;
if (vRecBuffer.Dequeue(&bFrame))
{
bFrame->WritePacket(pkt);
InspectRecv(pkt);
delete bFrame;
return true;
}
pcap_pkthdr* header;
const u_char* pkt_data;
@ -125,33 +141,73 @@ bool PCAPAdapter::recv(NetPacket* pkt)
// This delays getting packets we need, so instead loop untill a valid packet, or no packet, is returned from pcap_next_ex.
while (pcap_next_ex(hpcap, &header, &pkt_data) > 0)
{
// 1518 is the largest Ethernet frame we can get using an MTU of 1500 (assuming no VLAN tagging).
// This includes the FCS, which should be trimmed (PS2 SDK dosn't allow extra space for this).
if (header->len > 1518)
if (!ipOnly)
{
Console.Error("DEV9: Dropped jumbo frame of size: %u", header->len);
continue;
}
pxAssert(header->len == header->caplen);
memcpy(pkt->buffer, pkt_data, header->len);
pkt->size = static_cast<int>(header->len);
if (!switched)
SetMACBridgedRecv(pkt);
if (VerifyPkt(pkt, header->len))
{
HandleFrameCheckSequence(pkt);
// FCS (if present) has been removed, apply correct limit
if (pkt->size > 1514)
// 1518 is the largest Ethernet frame we can get using an MTU of 1500 (assuming no VLAN tagging).
// This includes the FCS, which should be trimmed (PS2 SDK dosn't allow extra space for this).
if (header->len > 1518)
{
Console.Error("DEV9: Dropped jumbo frame of size: %u", pkt->size);
Console.Error("DEV9: PCAP: Dropped jumbo frame of size: %u", header->len);
continue;
}
pxAssert(header->len == header->caplen);
memcpy(pkt->buffer, pkt_data, header->len);
pkt->size = static_cast<int>(header->len);
if (!switched)
SetMACBridgedRecv(pkt);
if (VerifyPkt(pkt, header->len))
{
HandleFrameCheckSequence(pkt);
// FCS (if present) has been removed, apply correct limit
if (pkt->size > 1514)
{
Console.Error("DEV9: PCAP: Dropped jumbo frame of size: %u", pkt->size);
continue;
}
InspectRecv(pkt);
return true;
}
}
else
{
// MTU of 1500
if (header->len > 1500)
{
Console.Error("DEV9: PCAP: Dropped jumbo IP packet of size: %u", header->len);
continue;
}
// Ensure IPv4
u8 ver = (pkt_data[0] & 0xF0) >> 4;
if (ver != 4)
{
Console.Error("DEV9: PCAP: Dropped non IPv4 packet");
continue;
}
// Avoid pcap looping packets by checking IP
IP_Packet ipPkt(const_cast<u_char*>(pkt_data), header->len);
if (ipPkt.sourceIP == ps2IP)
{
continue;
}
pxAssert(header->len == header->caplen);
// Build EtherFrame using captured packet
PayloadPtr* pl = new PayloadPtr(const_cast<u_char*>(pkt_data), header->len);
EthernetFrame frame(pl);
frame.sourceMAC = internalMAC;
frame.destinationMAC = ps2MAC;
frame.protocol = static_cast<u16>(EtherType::IPv4);
frame.WritePacket(pkt);
InspectRecv(pkt);
return true;
}
@ -170,13 +226,71 @@ bool PCAPAdapter::send(NetPacket* pkt)
return true;
// TODO: loopback broadcast packets to host pc in switched mode.
if (!switched)
SetMACBridgedSend(pkt);
if (!ipOnly)
{
if (!switched)
SetMACBridgedSend(pkt);
if (pcap_sendpacket(hpcap, (u_char*)pkt->buffer, pkt->size))
return false;
if (pcap_sendpacket(hpcap, (u_char*)pkt->buffer, pkt->size))
return false;
else
return true;
}
else
return true;
{
EthernetFrameEditor frame(pkt);
if (frame.GetProtocol() == static_cast<u16>(EtherType::IPv4))
{
PayloadPtr* payload = frame.GetPayload();
IP_Packet pkt(payload->data, payload->GetLength());
if (pkt.sourceIP != IP_Address{{{0, 0, 0, 0}}})
{
ps2IP = pkt.sourceIP;
}
if (pcap_sendpacket(hpcap, payload->data, pkt.GetLength()))
return false;
else
return true;
}
if (frame.GetProtocol() == static_cast<u16>(EtherType::ARP))
{
// We will need to respond to ARP requests for all except the PS2 ip
// However, we won't know the PS2 ip yet unless our dhcpServer is used
PayloadPtr* payload = frame.GetPayload();
ARP_Packet arpPkt(payload->data, payload->GetLength());
if (arpPkt.protocol == static_cast<u16>(EtherType::IPv4))
{
/* This is untested */
if (arpPkt.op == 1) //ARP request
{
if (*(IP_Address*)arpPkt.targetProtocolAddress.get() != dhcpServer.ps2IP)
// it's trying to resolve the gateway's mac addr
{
Console.Error("DEV9: PCAP: ARP Request on DLT_RAW adapter, providing assumed response");
ARP_Packet* arpRet = new ARP_Packet(6, 4);
std::memcpy(arpRet->targetHardwareAddress.get(), arpPkt.senderHardwareAddress.get(), sizeof(MAC_Address));
std::memcpy(arpRet->senderHardwareAddress.get(), &internalMAC, sizeof(MAC_Address));
std::memcpy(arpRet->targetProtocolAddress.get(), arpPkt.senderProtocolAddress.get(), sizeof(IP_Address));
std::memcpy(arpRet->senderProtocolAddress.get(), arpPkt.targetProtocolAddress.get(), sizeof(IP_Address));
arpRet->op = 2,
arpRet->protocol = arpPkt.protocol;
arpRet->hardwareType = arpPkt.hardwareType;
EthernetFrame* retARP = new EthernetFrame(arpRet);
retARP->destinationMAC = ps2MAC;
retARP->sourceMAC = internalMAC;
retARP->protocol = static_cast<u16>(EtherType::ARP);
vRecBuffer.Enqueue(retARP);
}
}
}
return true;
}
return false;
}
}
void PCAPAdapter::reloadSettings()
@ -196,6 +310,20 @@ PCAPAdapter::~PCAPAdapter()
pcap_close(hpcap);
hpcap = nullptr;
}
//Clear out vRecBuffer
while (!vRecBuffer.IsQueueEmpty())
{
EthernetFrame* retPay;
if (!vRecBuffer.Dequeue(&retPay))
{
using namespace std::chrono_literals;
std::this_thread::sleep_for(1ms);
continue;
}
delete retPay;
}
}
std::vector<AdapterEntry> PCAPAdapter::GetAdapters()
@ -223,7 +351,7 @@ std::vector<AdapterEntry> PCAPAdapter::GetAdapters()
//guid
if (!std::string_view(d->name).starts_with(PCAPPREFIX))
{
Console.Error("PCAP: Unexpected Device: ", d->name);
Console.Error("DEV9: PCAP: Unexpected Device: ", d->name);
d = d->next;
continue;
}
@ -268,7 +396,7 @@ std::vector<AdapterEntry> PCAPAdapter::GetAdapters()
bool PCAPAdapter::InitPCAP(const std::string& adapter, bool promiscuous)
{
char errbuf[PCAP_ERRBUF_SIZE];
Console.WriteLn("DEV9: Opening adapter '%s'...", adapter.c_str());
Console.WriteLn("DEV9: PCAP: Opening adapter '%s'...", adapter.c_str());
// Open the adapter.
if ((hpcap = pcap_open_live(adapter.c_str(), // Name of the device.
@ -279,15 +407,15 @@ bool PCAPAdapter::InitPCAP(const std::string& adapter, bool promiscuous)
errbuf // Error buffer.
)) == nullptr)
{
Console.Error("DEV9: %s", errbuf);
Console.Error("DEV9: Unable to open the adapter. %s is not supported by pcap", adapter.c_str());
Console.Error("DEV9: PCAP: %s", errbuf);
Console.Error("DEV9: PCAP: Unable to open the adapter. %s is not supported by pcap", adapter.c_str());
return false;
}
if (pcap_setnonblock(hpcap, 1, errbuf) == -1)
{
Console.Error("DEV9: Error setting non-blocking: %s", pcap_geterr(hpcap));
Console.Error("DEV9: Continuing in blocking mode");
Console.Error("DEV9: PCAP: Error setting non-blocking: %s", pcap_geterr(hpcap));
Console.Error("DEV9: PCAP: Continuing in blocking mode");
blocking = true;
}
else
@ -297,20 +425,24 @@ bool PCAPAdapter::InitPCAP(const std::string& adapter, bool promiscuous)
const int dlt = pcap_datalink(hpcap);
const char* dlt_name = pcap_datalink_val_to_name(dlt);
Console.WriteLn("DEV9: Device uses DLT %d: %s", dlt, dlt_name);
Console.WriteLn("DEV9: PCAP: Device uses DLT %d: %s", dlt, dlt_name);
switch (dlt)
{
case DLT_EN10MB:
//case DLT_IEEE802_11:
ipOnly = false;
break;
case DLT_RAW:
ipOnly = true;
break;
default:
Console.Error("ERROR: Unsupported DataLink Type (%d): %s", dlt, dlt_name);
Console.Error("DEV9: PCAP: Error, unsupported data link type (%d): %s", dlt, dlt_name);
pcap_close(hpcap);
hpcap = nullptr;
return false;
}
Console.WriteLn("DEV9: Adapter Ok.");
Console.WriteLn("DEV9: PCAP: Adapter Ok.");
return true;
}
@ -324,13 +456,13 @@ bool PCAPAdapter::SetMACSwitchedFilter(MAC_Address mac)
if (pcap_compile(hpcap, &fp, filter, 1, PCAP_NETMASK_UNKNOWN) == -1)
{
Console.Error("DEV9: Error calling pcap_compile: %s", pcap_geterr(hpcap));
Console.Error("DEV9: PCAP: Error calling pcap_compile: %s", pcap_geterr(hpcap));
return false;
}
int setFilterRet;
if ((setFilterRet = pcap_setfilter(hpcap, &fp)) == -1)
Console.Error("DEV9: Error setting filter: %s", pcap_geterr(hpcap));
Console.Error("DEV9: PCAP: Error setting filter: %s", pcap_geterr(hpcap));
pcap_freecode(&fp);
return setFilterRet != -1;

View File

@ -5,6 +5,7 @@
#include "pcap.h"
#include "net.h"
#include "PacketReader/MAC_Address.h"
#include "PacketReader/EthernetFrame.h"
#ifdef _WIN32
bool load_pcap();
@ -18,6 +19,9 @@ private:
bool switched;
bool blocking;
bool ipOnly;
SimpleQueue<PacketReader::EthernetFrame*> vRecBuffer;
PacketReader::IP::IP_Address ps2IP{};
PacketReader::MAC_Address hostMAC;

View File

@ -241,6 +241,7 @@ void tx_process()
// if we actualy send something set TXEND
if (cnt != 0)
{
Console.WriteLn("DEV9: SMAP: Sent %d packets", cnt);
_DEV9irq(SMAP_INTR_TXEND, 100); //now ? or when the fifo is empty ? i guess now atm
}
else

View File

@ -170,6 +170,7 @@
<ClCompile Include="DEV9\ATA\HddCreate.cpp" />
<ClCompile Include="DEV9\DEV9.cpp" />
<ClCompile Include="DEV9\flash.cpp" />
<ClCompile Include="DEV9\InternalServers\ARP_Logger.cpp" />
<ClCompile Include="DEV9\InternalServers\DHCP_Logger.cpp" />
<ClCompile Include="DEV9\InternalServers\DHCP_Server.cpp" />
<ClCompile Include="DEV9\InternalServers\DNS_Logger.cpp" />
@ -607,6 +608,7 @@
<ClInclude Include="DEV9\ATA\ATA.h" />
<ClInclude Include="DEV9\ATA\HddCreate.h" />
<ClInclude Include="DEV9\DEV9.h" />
<ClInclude Include="DEV9\InternalServers\ARP_Logger.h" />
<ClInclude Include="DEV9\InternalServers\DHCP_Logger.h" />
<ClInclude Include="DEV9\InternalServers\DHCP_Server.h" />
<ClInclude Include="DEV9\InternalServers\DNS_Logger.h" />

View File

@ -872,6 +872,9 @@
<ClCompile Include="DEV9\flash.cpp">
<Filter>System\Ps2\DEV9</Filter>
</ClCompile>
<ClCompile Include="DEV9\InternalServers\ARP_Logger.cpp">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClCompile>
<ClCompile Include="DEV9\InternalServers\DHCP_Logger.cpp">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClCompile>
@ -1757,6 +1760,9 @@
<ClInclude Include="DEV9\DEV9.h">
<Filter>System\Ps2\DEV9</Filter>
</ClInclude>
<ClInclude Include="DEV9\InternalServers\ARP_Logger.h">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClInclude>
<ClInclude Include="DEV9\InternalServers\DHCP_Logger.h">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClInclude>