DEV9: Add classes for editing packets and make PCAP use them

This commit is contained in:
TheLastRar 2023-01-15 21:18:13 +00:00 committed by refractionpcsx2
parent 3028998a43
commit dc9f61e70a
9 changed files with 278 additions and 172 deletions

View File

@ -329,6 +329,7 @@ set(pcsx2DEV9Sources
DEV9/InternalServers/DNS_Logger.cpp
DEV9/InternalServers/DNS_Server.cpp
DEV9/PacketReader/ARP/ARP_Packet.cpp
DEV9/PacketReader/ARP/ARP_PacketEditor.cpp
DEV9/PacketReader/IP/ICMP/ICMP_Packet.cpp
DEV9/PacketReader/IP/TCP/TCP_Options.cpp
DEV9/PacketReader/IP/TCP/TCP_Packet.cpp
@ -340,6 +341,7 @@ set(pcsx2DEV9Sources
DEV9/PacketReader/IP/IP_Options.cpp
DEV9/PacketReader/IP/IP_Packet.cpp
DEV9/PacketReader/EthernetFrame.cpp
DEV9/PacketReader/EthernetFrameEditor.cpp
DEV9/Sessions/BaseSession.cpp
DEV9/Sessions/ICMP_Session/ICMP_Session.cpp
DEV9/Sessions/TCP_Session/TCP_Session.cpp
@ -366,6 +368,7 @@ set(pcsx2DEV9Headers
DEV9/InternalServers/DNS_Server.h
DEV9/net.h
DEV9/PacketReader/ARP/ARP_Packet.h
DEV9/PacketReader/ARP/ARP_PacketEditor.h
DEV9/PacketReader/IP/ICMP/ICMP_Packet.h
DEV9/PacketReader/IP/TCP/TCP_Options.h
DEV9/PacketReader/IP/TCP/TCP_Packet.h
@ -380,6 +383,7 @@ set(pcsx2DEV9Headers
DEV9/PacketReader/IP/IP_Packet.h
DEV9/PacketReader/IP/IP_Payload.h
DEV9/PacketReader/EthernetFrame.h
DEV9/PacketReader/EthernetFrameEditor.h
DEV9/PacketReader/MAC_Address.h
DEV9/PacketReader/NetLib.h
DEV9/PacketReader/Payload.h

View File

@ -0,0 +1,79 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 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 "ARP_PacketEditor.h"
#ifdef _WIN32
#include "winsock.h"
#else
#include <arpa/inet.h>
#endif
namespace PacketReader::ARP
{
ARP_PacketEditor::ARP_PacketEditor(PayloadPtr* pkt)
: basePkt{pkt}
{
}
u16 ARP_PacketEditor::GetHardwareType()
{
return ntohs(*(u16*)&basePkt->data[0]);
}
u16 ARP_PacketEditor::GetProtocol()
{
return ntohs(*(u16*)&basePkt->data[2]);
}
u8 ARP_PacketEditor::GetHardwareAddressLength()
{
return basePkt->data[4];
}
u8 ARP_PacketEditor::GetProtocolAddressLength()
{
return basePkt->data[5];
}
u16 ARP_PacketEditor::GetOp()
{
return ntohs(*(u16*)&basePkt->data[6]);
}
u8* ARP_PacketEditor::SenderHardwareAddress()
{
return &basePkt->data[8];
}
u8* ARP_PacketEditor::SenderProtocolAddress()
{
int offset = 8 + GetHardwareAddressLength();
return &basePkt->data[offset];
}
u8* ARP_PacketEditor::TargetHardwareAddress()
{
int offset = 8 + GetHardwareAddressLength() + GetProtocolAddressLength();
return &basePkt->data[offset];
}
u8* ARP_PacketEditor::TargetProtocolAddress()
{
int offset = 8 + 2 * GetHardwareAddressLength() + GetProtocolAddressLength();
return &basePkt->data[offset];
}
} // namespace PacketReader::ARP

View File

@ -0,0 +1,42 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 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 "DEV9/PacketReader/Payload.h"
namespace PacketReader::ARP
{
class ARP_PacketEditor
{
private:
PayloadPtr* basePkt;
public:
ARP_PacketEditor(PayloadPtr* pkt);
u16 GetHardwareType();
u16 GetProtocol();
u8 GetHardwareAddressLength();
u8 GetProtocolAddressLength();
u16 GetOp();
u8* SenderHardwareAddress();
u8* SenderProtocolAddress();
u8* TargetHardwareAddress();
u8* TargetProtocolAddress();
};
} // namespace PacketReader::ARP

View File

@ -0,0 +1,66 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 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 "EthernetFrameEditor.h"
#ifdef _WIN32
#include "winsock.h"
#else
#include <arpa/inet.h>
#endif
namespace PacketReader
{
EthernetFrameEditor::EthernetFrameEditor(NetPacket* pkt)
: basePkt{pkt}
{
headerLength = 14; //(6+6+2)
//Note: we don't have to worry about the Ethernet Frame CRC as it is not included in the packet
//Note: We don't support tagged frames
payload = std::make_unique<PayloadPtr>((u8*)&basePkt->buffer[14], pkt->size - headerLength);
}
MAC_Address EthernetFrameEditor::GetDestinationMAC()
{
return *(MAC_Address*)&basePkt->buffer[0];
}
void EthernetFrameEditor::SetDestinationMAC(MAC_Address value)
{
*(MAC_Address*)&basePkt->buffer[0] = value;
}
MAC_Address EthernetFrameEditor::GetSourceMAC()
{
return *(MAC_Address*)&basePkt->buffer[6];
}
void EthernetFrameEditor::SetSourceMAC(MAC_Address value)
{
*(MAC_Address*)&basePkt->buffer[6] = value;
}
u16 EthernetFrameEditor::GetProtocol()
{
return ntohs(*(u16*)&basePkt->buffer[12]);
}
PayloadPtr* EthernetFrameEditor::GetPayload()
{
return payload.get();
}
} // namespace PacketReader

View File

@ -0,0 +1,45 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2023 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 "DEV9/net.h"
#include "MAC_Address.h"
#include "Payload.h"
namespace PacketReader
{
class EthernetFrameEditor
{
public:
int headerLength = 14;
//Length
private:
NetPacket* basePkt;
std::unique_ptr<PayloadPtr> payload;
public:
EthernetFrameEditor(NetPacket* pkt);
MAC_Address GetDestinationMAC();
void SetDestinationMAC(MAC_Address value);
MAC_Address GetSourceMAC();
void SetSourceMAC(MAC_Address value);
u16 GetProtocol();
PayloadPtr* GetPayload();
};
} // namespace PacketReader

View File

@ -30,6 +30,9 @@
#include "DEV9.h"
#include "AdapterUtils.h"
#include "net.h"
#include "PacketReader/EthernetFrame.h"
#include "PacketReader/EthernetFrameEditor.h"
#include "PacketReader/ARP/ARP_PacketEditor.h"
#ifndef PCAP_NETMASK_UNKNOWN
#define PCAP_NETMASK_UNKNOWN 0xffffffff
#endif
@ -39,6 +42,7 @@
#endif
using namespace PacketReader;
using namespace PacketReader::ARP;
using namespace PacketReader::IP;
#ifdef _WIN32
@ -157,6 +161,7 @@ bool PCAPAdapter::recv(NetPacket* pkt)
pxAssert(header->len == header->caplen);
memcpy(pkt->buffer, pkt_data, header->len);
pkt->size = (int)header->len;
if (!switched)
SetMACBridgedRecv(pkt);
@ -376,43 +381,41 @@ bool PCAPAdapter::SetMACSwitchedFilter(MAC_Address mac)
void PCAPAdapter::SetMACBridgedRecv(NetPacket* pkt)
{
ethernet_header* eth = (ethernet_header*)pkt->buffer;
if (eth->protocol == 0x0008) // IP
EthernetFrameEditor frame(pkt);
if (frame.GetProtocol() == (u16)EtherType::IPv4) // IP
{
// Compare DEST IP in IP with the PS2's IP, if they match, change DEST MAC to ps2MAC.
const ip_header* iph = ((ip_header*)(pkt->buffer + sizeof(ethernet_header)));
if (*(IP_Address*)&iph->dst == ps2IP)
eth->dst = *(mac_address*)&ps2MAC;
PayloadPtr* payload = frame.GetPayload();
IP_Packet ippkt(payload->data, payload->GetLength());
if (ippkt.destinationIP == ps2IP)
frame.SetDestinationMAC(ps2MAC);
}
if (eth->protocol == 0x0608) // ARP
if (frame.GetProtocol() == (u16)EtherType::ARP) // ARP
{
// Compare DEST IP in ARP with the PS2's IP, if they match, DEST MAC to ps2MAC on both ARP and ETH Packet headers.
arp_packet* aph = ((arp_packet*)(pkt->buffer + sizeof(ethernet_header)));
if (*(IP_Address*)&aph->p_dst == ps2IP)
ARP_PacketEditor arpPkt(frame.GetPayload());
if (*(IP_Address*)arpPkt.TargetProtocolAddress() == ps2IP)
{
eth->dst = *(mac_address*)&ps2MAC;
((arp_packet*)(pkt->buffer + sizeof(ethernet_header)))->h_dst = *(mac_address*)&ps2MAC;
frame.SetDestinationMAC(ps2MAC);
*(MAC_Address*)arpPkt.TargetHardwareAddress() = ps2MAC;
}
}
}
void PCAPAdapter::SetMACBridgedSend(NetPacket* pkt)
{
ethernet_header* eth = (ethernet_header*)pkt->buffer;
if (eth->protocol == 0x0008) // IP
EthernetFrameEditor frame(pkt);
if (frame.GetProtocol() == (u16)EtherType::IPv4) // IP
{
const ip_address ps2_ip = ((ip_header*)((u8*)pkt->buffer + sizeof(ethernet_header)))->src;
ps2IP = *(IP_Address*)&ps2_ip;
PayloadPtr* payload = frame.GetPayload();
IP_Packet ippkt(payload->data, payload->GetLength());
ps2IP = ippkt.sourceIP;
}
if (eth->protocol == 0x0608) // ARP
if (frame.GetProtocol() == (u16)EtherType::ARP) // ARP
{
const ip_address ps2_ip = ((arp_packet*)((u8*)pkt->buffer + sizeof(ethernet_header)))->p_src;
ps2IP = *(IP_Address*)&ps2_ip;
((arp_packet*)(pkt->buffer + sizeof(ethernet_header)))->h_src = *(mac_address*)&hostMAC;
ARP_PacketEditor arpPkt(frame.GetPayload());
ps2IP = *(IP_Address*)arpPkt.SenderProtocolAddress();
*(MAC_Address*)arpPkt.SenderHardwareAddress() = hostMAC;
}
eth->src = *(mac_address*)&hostMAC;
frame.SetSourceMAC(hostMAC);
}

View File

@ -18,160 +18,11 @@
#include "net.h"
#include "PacketReader/MAC_Address.h"
#ifdef __cplusplus
extern "C" {
#endif
//#ifndef _WIN32
#pragma pack(push, 1)
typedef struct _ip_address
{
u_char bytes[4];
} ip_address;
typedef struct _mac_address
{
u_char bytes[6];
} mac_address;
typedef struct _ethernet_header
{
mac_address dst;
mac_address src;
u_short protocol;
} ethernet_header;
typedef struct _arp_packet
{
u_short hw_type;
u_short protocol;
u_char h_addr_len;
u_char p_addr_len;
u_short operation;
mac_address h_src;
ip_address p_src;
mac_address h_dst;
ip_address p_dst;
} arp_packet;
typedef struct _ip_header
{
u_char ver_hlen; /* version << 4 | header length >> 2 */
u_char type; /* type of service */
u_short len; /* total length */
u_short id; /* identification */
u_short offset; /* fragment offset field */
u_char ttl; /* time to live */
u_char proto; /* protocol */
u_short hdr_csum; /* checksum */
ip_address src; /* source and dest address */
ip_address dst;
} ip_header;
/* Internet Control Message Protocol Constants and Packet Format */
/* ic_type field */
#define ICT_ECHORP 0 /* Echo reply */
#define ICT_DESTUR 3 /* Destination unreachable */
#define ICT_SRCQ 4 /* Source quench */
#define ICT_REDIRECT 5 /* Redirect message type */
#define ICT_ECHORQ 8 /* Echo request */
#define ICT_TIMEX 11 /* Time exceeded */
#define ICT_PARAMP 12 /* Parameter Problem */
#define ICT_TIMERQ 13 /* Timestamp request */
#define ICT_TIMERP 14 /* Timestamp reply */
#define ICT_INFORQ 15 /* Information request */
#define ICT_INFORP 16 /* Information reply */
#define ICT_MASKRQ 17 /* Mask request */
#define ICT_MASKRP 18 /* Mask reply */
/* ic_code field */
#define ICC_NETUR 0 /* dest unreachable, net unreachable */
#define ICC_HOSTUR 1 /* dest unreachable, host unreachable */
#define ICC_PROTOUR 2 /* dest unreachable, proto unreachable */
#define ICC_PORTUR 3 /* dest unreachable, port unreachable */
#define ICC_FNADF 4 /* dest unr, frag needed & don't frag */
#define ICC_SRCRT 5 /* dest unreachable, src route failed */
#define ICC_NETRD 0 /* redirect: net */
#define ICC_HOSTRD 1 /* redirect: host */
#define IC_TOSNRD 2 /* redirect: type of service, net */
#define IC_TOSHRD 3 /* redirect: type of service, host */
#define ICC_TIMEX 0 /* time exceeded, ttl */
#define ICC_FTIMEX 1 /* time exceeded, frag */
#define IC_HLEN 8 /* octets */
#define IC_PADLEN 3 /* pad length (octets) */
#define IC_RDTTL 300 /* ttl for redirect routes */
/* ICMP packet format (following the IP header) */
typedef struct _icmp_header
{ /* ICMP packet */
char type; /* type of message (ICT_* above)*/
char code; /* code (ICC_* above) */
short csum; /* checksum of ICMP header+data */
union
{
struct
{
int ic1_id : 16; /* echo type, a message id */
int ic1_seq : 16; /* echo type, a seq. number */
} ic1;
ip_address ic2_gw; /* for redirect, gateway */
struct
{
char ic3_ptr; /* pointer, for ICT_PARAMP */
char ic3_pad[IC_PADLEN];
} ic3;
int ic4_mbz; /* must be zero */
} icu;
} icmp_header;
/*typedef struct _udp_header {
u16 src_port;
u16 dst_port;
u16 len;
u16 csum;
} udp_header;*/
typedef struct _full_arp_packet
{
ethernet_header header;
arp_packet arp;
} full_arp_packet;
#pragma pack(pop)
#define ARP_REQUEST 0x0100 //values are big-endian
#define mac_compare(a, b) (memcmp(&(a), &(b), 6))
#define ip_compare(a, b) (memcmp(&(a), &(b), 4))
//#endif
/*
int pcap_io_init(char *adapter);
int pcap_io_send(void* packet, int plen);
int pcap_io_recv(void* packet, int max_len);
void pcap_io_close();
int pcap_io_get_dev_num();
char* pcap_io_get_dev_desc(int num);
char* pcap_io_get_dev_name(int num);
*/
#ifdef _WIN32
bool load_pcap();
void unload_pcap();
#endif
#ifdef __cplusplus
}
#endif
class PCAPAdapter : public NetAdapter
{
private:

View File

@ -166,6 +166,8 @@
<ClCompile Include="DEV9\InternalServers\DNS_Logger.cpp" />
<ClCompile Include="DEV9\InternalServers\DNS_Server.cpp" />
<ClCompile Include="DEV9\PacketReader\ARP\ARP_Packet.cpp" />
<ClCompile Include="DEV9\PacketReader\ARP\ARP_PacketEditor.cpp" />
<ClCompile Include="DEV9\PacketReader\EthernetFrameEditor.cpp" />
<ClCompile Include="DEV9\PacketReader\EthernetFrame.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Options.cpp" />
@ -510,6 +512,8 @@
<ClInclude Include="DEV9\InternalServers\DNS_Server.h" />
<ClInclude Include="DEV9\net.h" />
<ClInclude Include="DEV9\PacketReader\ARP\ARP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\ARP\ARP_PacketEditor.h" />
<ClInclude Include="DEV9\PacketReader\EthernetFrameEditor.h" />
<ClInclude Include="DEV9\PacketReader\EthernetFrame.h" />
<ClInclude Include="DEV9\PacketReader\MAC_Address.h" />
<ClInclude Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.h" />

View File

@ -908,6 +908,9 @@
<ClCompile Include="DEV9\PacketReader\ARP\ARP_Packet.cpp">
<Filter>System\Ps2\DEV9\PacketReader\ARP</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\ARP\ARP_PacketEditor.cpp">
<Filter>System\Ps2\DEV9\PacketReader\ARP</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\ICMP</Filter>
</ClCompile>
@ -941,6 +944,9 @@
<ClCompile Include="DEV9\PacketReader\EthernetFrame.cpp">
<Filter>System\Ps2\DEV9\PacketReader</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\EthernetFrameEditor.cpp">
<Filter>System\Ps2\DEV9\PacketReader</Filter>
</ClCompile>
<ClCompile Include="DEV9\pcap_io.cpp">
<Filter>System\Ps2\DEV9</Filter>
</ClCompile>
@ -1780,6 +1786,9 @@
<ClInclude Include="DEV9\PacketReader\ARP\ARP_Packet.h">
<Filter>System\Ps2\DEV9\PacketReader\ARP</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\ARP\ARP_PacketEditor.h">
<Filter>System\Ps2\DEV9\PacketReader\ARP</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.h">
<Filter>System\Ps2\DEV9\PacketReader\IP\ICMP</Filter>
</ClInclude>
@ -1822,6 +1831,9 @@
<ClInclude Include="DEV9\PacketReader\EthernetFrame.h">
<Filter>System\Ps2\DEV9\PacketReader</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\EthernetFrameEditor.h">
<Filter>System\Ps2\DEV9\PacketReader</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\MAC_Address.h">
<Filter>System\Ps2\DEV9\PacketReader</Filter>
</ClInclude>