DEV9: Add code for reading ARP, TCP & ICMP packets

This commit is contained in:
TheLastRar 2021-03-06 20:29:44 +00:00 committed by refractionpcsx2
parent db220001f6
commit 140d44d826
13 changed files with 996 additions and 0 deletions

View File

@ -356,6 +356,10 @@ set(pcsx2DEV9Sources
DEV9/InternalServers/DHCP_Server.cpp
DEV9/InternalServers/DNS_Logger.cpp
DEV9/InternalServers/DNS_Server.cpp
DEV9/PacketReader/ARP/ARP_Packet.cpp
DEV9/PacketReader/IP/ICMP/ICMP_Packet.cpp
DEV9/PacketReader/IP/TCP/TCP_Options.cpp
DEV9/PacketReader/IP/TCP/TCP_Packet.cpp
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.cpp
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.cpp
DEV9/PacketReader/IP/UDP/DNS/DNS_Classes.cpp
@ -381,6 +385,10 @@ set(pcsx2DEV9Headers
DEV9/InternalServers/DNS_Logger.h
DEV9/InternalServers/DNS_Server.h
DEV9/net.h
DEV9/PacketReader/ARP/ARP_Packet.h
DEV9/PacketReader/IP/ICMP/ICMP_Packet.h
DEV9/PacketReader/IP/TCP/TCP_Options.h
DEV9/PacketReader/IP/TCP/TCP_Packet.h
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Options.h
DEV9/PacketReader/IP/UDP/DHCP/DHCP_Packet.h
DEV9/PacketReader/IP/UDP/DNS/DNS_Classes.h

View File

@ -0,0 +1,98 @@
/* 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 "ARP_Packet.h"
#include "DEV9/PacketReader/NetLib.h"
namespace PacketReader::ARP
{
ARP_Packet::ARP_Packet(u8 hwAddrLen, u8 procAddrLen)
: hardwareAddressLength{hwAddrLen}
, protocolAddressLength{procAddrLen}
, senderHardwareAddress{std::make_unique<u8[]>(hwAddrLen)}
, senderProtocolAddress{std::make_unique<u8[]>(procAddrLen)}
, targetHardwareAddress{std::make_unique<u8[]>(hwAddrLen)}
, targetProtocolAddress{std::make_unique<u8[]>(procAddrLen)}
{
}
ARP_Packet::ARP_Packet(u8* buffer, int bufferSize)
{
int offset = 0;
NetLib::ReadUInt16(buffer, &offset, &hardwareType);
NetLib::ReadUInt16(buffer, &offset, &protocol);
//
NetLib::ReadByte08(buffer, &offset, &hardwareAddressLength);
NetLib::ReadByte08(buffer, &offset, &protocolAddressLength);
NetLib::ReadUInt16(buffer, &offset, &op);
//Allocate arrays
senderHardwareAddress = std::make_unique<u8[]>(hardwareAddressLength);
senderProtocolAddress = std::make_unique<u8[]>(protocolAddressLength);
targetHardwareAddress = std::make_unique<u8[]>(hardwareAddressLength);
targetProtocolAddress = std::make_unique<u8[]>(protocolAddressLength);
//Assume normal MAC/IP address lengths for logging
NetLib::ReadByteArray(buffer, &offset, hardwareAddressLength, senderHardwareAddress.get());
NetLib::ReadByteArray(buffer, &offset, protocolAddressLength, senderProtocolAddress.get());
NetLib::ReadByteArray(buffer, &offset, hardwareAddressLength, targetHardwareAddress.get());
NetLib::ReadByteArray(buffer, &offset, protocolAddressLength, targetProtocolAddress.get());
}
ARP_Packet::ARP_Packet(const ARP_Packet& original)
: hardwareType{original.hardwareType}
, protocol{original.protocol}
, hardwareAddressLength{original.hardwareAddressLength}
, protocolAddressLength{original.protocolAddressLength}
, op{original.protocol}
, senderHardwareAddress{std::make_unique<u8[]>(original.hardwareAddressLength)}
, senderProtocolAddress{std::make_unique<u8[]>(original.protocolAddressLength)}
, targetHardwareAddress{std::make_unique<u8[]>(original.hardwareAddressLength)}
, targetProtocolAddress{std::make_unique<u8[]>(original.protocolAddressLength)}
{
memcpy(senderHardwareAddress.get(), original.senderHardwareAddress.get(), hardwareAddressLength);
memcpy(senderProtocolAddress.get(), original.senderProtocolAddress.get(), protocolAddressLength);
memcpy(targetHardwareAddress.get(), original.targetHardwareAddress.get(), hardwareAddressLength);
memcpy(targetProtocolAddress.get(), original.targetProtocolAddress.get(), protocolAddressLength);
}
int ARP_Packet::GetLength()
{
return 8 + 2 * hardwareAddressLength + 2 * protocolAddressLength;
}
void ARP_Packet::WriteBytes(u8* buffer, int* offset)
{
NetLib::WriteUInt16(buffer, offset, hardwareType);
NetLib::WriteUInt16(buffer, offset, protocol);
NetLib::WriteByte08(buffer, offset, hardwareAddressLength);
NetLib::WriteByte08(buffer, offset, protocolAddressLength);
NetLib::WriteUInt16(buffer, offset, op);
NetLib::WriteByteArray(buffer, offset, hardwareAddressLength, senderHardwareAddress.get());
NetLib::WriteByteArray(buffer, offset, protocolAddressLength, senderProtocolAddress.get());
NetLib::WriteByteArray(buffer, offset, hardwareAddressLength, targetHardwareAddress.get());
NetLib::WriteByteArray(buffer, offset, protocolAddressLength, targetProtocolAddress.get());
}
ARP_Packet* ARP_Packet::Clone() const
{
return new ARP_Packet(*this);
}
} // namespace PacketReader::ARP

View File

@ -0,0 +1,44 @@
/* 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 <vector>
#include "DEV9/PacketReader/Payload.h"
namespace PacketReader::ARP
{
class ARP_Packet : public Payload
{
public:
u16 hardwareType;
u16 protocol;
u8 hardwareAddressLength = 6;
u8 protocolAddressLength = 4;
u16 op;
std::unique_ptr<u8[]> senderHardwareAddress;
std::unique_ptr<u8[]> senderProtocolAddress;
std::unique_ptr<u8[]> targetHardwareAddress;
std::unique_ptr<u8[]> targetProtocolAddress;
ARP_Packet(u8 hwAddrLen, u8 procAddrLen);
ARP_Packet(u8* buffer, int bufferSize);
ARP_Packet(const ARP_Packet&);
virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset);
virtual ARP_Packet* Clone() const;
};
} // namespace PacketReader::ARP

View File

@ -0,0 +1,124 @@
/* 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 "ICMP_Packet.h"
#include "DEV9/PacketReader/NetLib.h"
namespace PacketReader::IP::ICMP
{
ICMP_Packet::ICMP_Packet(Payload* data)
: payload{data}
{
}
ICMP_Packet::ICMP_Packet(u8* buffer, int bufferSize)
{
int offset = 0;
//Bits 0-31
NetLib::ReadByte08(buffer, &offset, &type);
NetLib::ReadByte08(buffer, &offset, &code);
NetLib::ReadUInt16(buffer, &offset, &checksum);
//Bits 32-63
NetLib::ReadByteArray(buffer, &offset, 4, headerData);
//Bits 64+
payload = std::make_unique<PayloadPtr>(&buffer[offset], bufferSize - offset);
//AllDone
}
ICMP_Packet::ICMP_Packet(const ICMP_Packet& original)
: type{original.type}
, code{original.code}
, checksum{original.checksum}
, payload{original.payload->Clone()}
{
memcpy(headerData, original.headerData, 4);
}
Payload* ICMP_Packet::GetPayload()
{
return payload.get();
}
int ICMP_Packet::GetLength()
{
return headerLength + payload->GetLength();
}
void ICMP_Packet::WriteBytes(u8* buffer, int* offset)
{
NetLib::WriteByte08(buffer, offset, type);
NetLib::WriteByte08(buffer, offset, code);
NetLib::WriteUInt16(buffer, offset, checksum);
NetLib::WriteByteArray(buffer, offset, 4, headerData);
payload->WriteBytes(buffer, offset);
}
ICMP_Packet* ICMP_Packet::Clone() const
{
return new ICMP_Packet(*this);
}
u8 ICMP_Packet::GetProtocol()
{
return (u8)protocol;
}
void ICMP_Packet::CalculateChecksum(IP_Address srcIP, IP_Address dstIP)
{
int pHeaderLen = headerLength + payload->GetLength();
if ((pHeaderLen & 1) != 0)
{
pHeaderLen += 1;
}
u8* segment = new u8[pHeaderLen];
int counter = 0;
checksum = 0;
WriteBytes(segment, &counter);
//Zero alignment byte
if (counter != pHeaderLen)
NetLib::WriteByte08(segment, &counter, 0);
checksum = IP_Packet::InternetChecksum(segment, pHeaderLen);
delete[] segment;
}
bool ICMP_Packet::VerifyChecksum(IP_Address srcIP, IP_Address dstIP)
{
int pHeaderLen = headerLength + payload->GetLength();
if ((pHeaderLen & 1) != 0)
{
pHeaderLen += 1;
}
u8* segment = new u8[pHeaderLen];
int counter = 0;
WriteBytes(segment, &counter);
//Zero alignment byte
if (counter != pHeaderLen)
NetLib::WriteByte08(segment, &counter, 0);
u16 csumCal = IP_Packet::InternetChecksum(segment, pHeaderLen);
delete[] segment;
return (csumCal == 0);
}
} // namespace PacketReader::IP::ICMP

View File

@ -0,0 +1,56 @@
/* 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 "DEV9/PacketReader/IP/IP_Packet.h"
namespace PacketReader::IP::ICMP
{
class ICMP_Packet : public IP_Payload
{
public:
u8 type;
u8 code;
private:
u16 checksum;
public:
u8 headerData[4];
private:
const static int headerLength = 8;
const static IP_Type protocol = IP_Type::ICMP;
std::unique_ptr<Payload> payload;
public:
//Takes ownership of payload
ICMP_Packet(Payload* data);
ICMP_Packet(u8* buffer, int bufferSize);
ICMP_Packet(const ICMP_Packet&);
Payload* GetPayload();
virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset);
virtual ICMP_Packet* Clone() const;
virtual u8 GetProtocol();
virtual bool VerifyChecksum(IP_Address srcIP, IP_Address dstIP);
virtual void CalculateChecksum(IP_Address srcIP, IP_Address dstIP);
};
} // namespace PacketReader::IP::ICMP

View File

@ -0,0 +1,76 @@
/* 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 "TCP_Options.h"
#include "DEV9/PacketReader/NetLib.h"
namespace PacketReader::IP::TCP
{
TCPopMSS::TCPopMSS(u16 mss)
: maxSegmentSize{mss}
{
}
TCPopMSS::TCPopMSS(u8* data, int offset)
{
offset += 2;
NetLib::ReadUInt16(data, &offset, &maxSegmentSize);
}
void TCPopMSS::WriteBytes(u8* buffer, int* offset)
{
NetLib::WriteByte08(buffer, offset, GetCode());
NetLib::WriteByte08(buffer, offset, GetLength());
NetLib::WriteUInt16(buffer, offset, maxSegmentSize);
}
TCPopWS::TCPopWS(u8 ws)
: windowScale{ws}
{
}
TCPopWS::TCPopWS(u8* data, int offset)
{
offset += 2;
NetLib::ReadByte08(data, &offset, &windowScale);
}
void TCPopWS::WriteBytes(u8* buffer, int* offset)
{
NetLib::WriteByte08(buffer, offset, GetCode());
NetLib::WriteByte08(buffer, offset, GetLength());
NetLib::WriteByte08(buffer, offset, windowScale);
}
TCPopTS::TCPopTS(u32 senderTS, u32 echoTS)
: senderTimeStamp{senderTS}
, echoTimeStamp{echoTS}
{
}
TCPopTS::TCPopTS(u8* data, int offset)
{
offset += 2;
NetLib::ReadUInt32(data, &offset, &senderTimeStamp);
NetLib::ReadUInt32(data, &offset, &echoTimeStamp);
}
void TCPopTS::WriteBytes(u8* buffer, int* offset)
{
NetLib::WriteByte08(buffer, offset, GetCode());
NetLib::WriteByte08(buffer, offset, GetLength());
NetLib::WriteUInt32(buffer, offset, senderTimeStamp);
NetLib::WriteUInt32(buffer, offset, echoTimeStamp);
}
} // namespace PacketReader::IP::TCP

View File

@ -0,0 +1,96 @@
/* 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 "DEV9/PacketReader/IP/IP_Options.h"
namespace PacketReader::IP::TCP
{
class TCPopNOP : public BaseOption
{
virtual u8 GetLength() { return 1; }
virtual u8 GetCode() { return 1; }
virtual void WriteBytes(u8* buffer, int* offset)
{
buffer[*offset] = GetCode();
(*offset)++;
}
virtual TCPopNOP* Clone() const
{
return new TCPopNOP(*this);
}
};
class TCPopMSS : public BaseOption
{
public:
u16 maxSegmentSize;
TCPopMSS(u16 mss);
TCPopMSS(u8* data, int offset); //Offset will include Kind and Len
virtual u8 GetLength() { return 4; }
virtual u8 GetCode() { return 2; }
virtual void WriteBytes(u8* buffer, int* offset);
virtual TCPopMSS* Clone() const
{
return new TCPopMSS(*this);
}
};
class TCPopWS : public BaseOption
{
public:
u8 windowScale;
TCPopWS(u8 ws);
TCPopWS(u8* data, int offset); //Offset will include Kind and Len
virtual u8 GetLength() { return 3; }
virtual u8 GetCode() { return 3; }
virtual void WriteBytes(u8* buffer, int* offset);
virtual TCPopWS* Clone() const
{
return new TCPopWS(*this);
}
};
class TCPopTS : public BaseOption
{
public:
u32 senderTimeStamp;
u32 echoTimeStamp;
TCPopTS(u32 senderTS, u32 echoTS);
TCPopTS(u8* data, int offset); //Offset will include Kind and Len
virtual u8 GetLength() { return 10; }
virtual u8 GetCode() { return 8; }
virtual void WriteBytes(u8* buffer, int* offset);
virtual TCPopTS* Clone() const
{
return new TCPopTS(*this);
}
};
} // namespace PacketReader::IP::TCP

View File

@ -0,0 +1,313 @@
/* 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 "TCP_Packet.h"
#include "DEV9/PacketReader/NetLib.h"
namespace PacketReader::IP::TCP
{
//Need flags
bool TCP_Packet::GetNS()
{
return (dataOffsetAndNS_Flag & 1);
}
void TCP_Packet::SetNS(bool value)
{
dataOffsetAndNS_Flag = (dataOffsetAndNS_Flag & ~0x1) | (value & 0x1);
}
bool TCP_Packet::GetCWR()
{
return (flags & (1 << 7));
}
void TCP_Packet::SetCWR(bool value)
{
flags = (flags & ~(0x1 << 7)) | ((value & 0x1) << 7);
}
bool TCP_Packet::GetECE()
{
return (flags & (1 << 6));
}
void TCP_Packet::SetECE(bool value)
{
flags = (flags & ~(0x1 << 6)) | ((value & 0x1) << 6);
}
bool TCP_Packet::GetURG()
{
return (flags & (1 << 5));
}
void TCP_Packet::SetURG(bool value)
{
flags = (flags & ~(0x1 << 5)) | ((value & 0x1) << 5);
}
bool TCP_Packet::GetACK()
{
return (flags & (1 << 4));
}
void TCP_Packet::SetACK(bool value)
{
flags = (flags & ~(0x1 << 4)) | ((value & 0x1) << 4);
}
bool TCP_Packet::GetPSH()
{
return (flags & (1 << 3));
}
void TCP_Packet::SetPSH(bool value)
{
flags = (flags & ~(0x1 << 3)) | ((value & 0x1) << 3);
}
bool TCP_Packet::GetRST()
{
return (flags & (1 << 2));
}
void TCP_Packet::SetRST(bool value)
{
flags = (flags & ~(0x1 << 2)) | ((value & 0x1) << 2);
}
bool TCP_Packet::GetSYN()
{
return (flags & (1 << 1));
}
void TCP_Packet::SetSYN(bool value)
{
flags = (flags & ~(0x1 << 1)) | ((value & 0x1) << 1);
}
bool TCP_Packet::GetFIN()
{
return (flags & 1);
}
void TCP_Packet::SetFIN(bool value)
{
flags = (flags & ~0x1) | (value & 0x1);
}
TCP_Packet::TCP_Packet(Payload* data)
: headerLength{20}
, payload{data}
{
}
TCP_Packet::TCP_Packet(u8* buffer, int bufferSize)
{
int offset = 0;
//Bits 0-31
NetLib::ReadUInt16(buffer, &offset, &sourcePort);
NetLib::ReadUInt16(buffer, &offset, &destinationPort);
//Bits 32-63
NetLib::ReadUInt32(buffer, &offset, &sequenceNumber);
//Bits 64-95
NetLib::ReadUInt32(buffer, &offset, &acknowledgementNumber);
//Bits 96-127
NetLib::ReadByte08(buffer, &offset, &dataOffsetAndNS_Flag);
headerLength = (dataOffsetAndNS_Flag >> 4) << 2;
NetLib::ReadByte08(buffer, &offset, &flags);
NetLib::ReadUInt16(buffer, &offset, &windowSize);
//Bits 127-159
NetLib::ReadUInt16(buffer, &offset, &checksum);
NetLib::ReadUInt16(buffer, &offset, &urgentPointer);
//Bits 160+
if (headerLength > 20) //TCP options
{
bool opReadFin = false;
do
{
u8 opKind = buffer[offset];
u8 opLen = buffer[offset + 1];
switch (opKind)
{
case 0:
opReadFin = true;
break;
case 1:
options.push_back(new TCPopNOP());
offset += 1;
continue;
case 2:
options.push_back(new TCPopMSS(buffer, offset));
break;
case 3:
options.push_back(new TCPopWS(buffer, offset));
break;
case 8:
options.push_back(new TCPopTS(buffer, offset));
break;
default:
Console.Error("Got Unknown TCP Option %d with len %d", opKind, opLen);
options.push_back(new IPopUnk(buffer, offset));
break;
}
offset += opLen;
if (offset == headerLength)
opReadFin = true;
} while (opReadFin == false);
}
offset = headerLength;
payload = std::make_unique<PayloadPtr>(&buffer[offset], bufferSize - offset);
//AllDone
}
TCP_Packet::TCP_Packet(const TCP_Packet& original)
: sourcePort{original.sourcePort}
, destinationPort{original.destinationPort}
, sequenceNumber{original.sequenceNumber}
, acknowledgementNumber{original.acknowledgementNumber}
, dataOffsetAndNS_Flag{original.dataOffsetAndNS_Flag}
, headerLength{original.headerLength}
, flags{original.flags}
, windowSize{original.windowSize}
, checksum{original.checksum}
, urgentPointer{original.urgentPointer}
, payload{original.payload->Clone()}
{
//Clone options
options.reserve(original.options.size());
for (size_t i = 0; i < options.size(); i++)
options.push_back(original.options[i]->Clone());
}
Payload* TCP_Packet::GetPayload()
{
return payload.get();
}
int TCP_Packet::GetLength()
{
ReComputeHeaderLen();
return headerLength + payload->GetLength();
}
void TCP_Packet::WriteBytes(u8* buffer, int* offset)
{
int startOff = *offset;
NetLib::WriteUInt16(buffer, offset, sourcePort);
NetLib::WriteUInt16(buffer, offset, destinationPort);
NetLib::WriteUInt32(buffer, offset, sequenceNumber);
NetLib::WriteUInt32(buffer, offset, acknowledgementNumber);
NetLib::WriteByte08(buffer, offset, dataOffsetAndNS_Flag);
NetLib::WriteByte08(buffer, offset, flags);
NetLib::WriteUInt16(buffer, offset, windowSize);
NetLib::WriteUInt16(buffer, offset, checksum);
NetLib::WriteUInt16(buffer, offset, urgentPointer);
//options
for (size_t i = 0; i < options.size(); i++)
options[i]->WriteBytes(buffer, offset);
//Zero alignment bytes
if (*offset != startOff + headerLength)
memset(&buffer[*offset], 0, startOff + headerLength - *offset);
*offset = startOff + headerLength;
payload->WriteBytes(buffer, offset);
}
TCP_Packet* TCP_Packet::Clone() const
{
return new TCP_Packet(*this);
}
u8 TCP_Packet::GetProtocol()
{
return (u8)protocol;
}
void TCP_Packet::ReComputeHeaderLen()
{
int opOffset = 20;
for (size_t i = 0; i < options.size(); i++)
opOffset += options[i]->GetLength();
opOffset += opOffset % 4; //needs to be a whole number of 32bits
headerLength = opOffset;
//Also write into dataOffsetAndNS_Flag
u8 ns = dataOffsetAndNS_Flag & 1;
dataOffsetAndNS_Flag = (headerLength >> 2) << 4;
dataOffsetAndNS_Flag |= ns;
}
void TCP_Packet::CalculateChecksum(IP_Address srcIP, IP_Address dstIP)
{
ReComputeHeaderLen();
int pHeaderLen = (12) + headerLength + payload->GetLength();
if ((pHeaderLen & 1) != 0)
pHeaderLen += 1;
u8* headerSegment = new u8[pHeaderLen];
int counter = 0;
NetLib::WriteByteArray(headerSegment, &counter, 4, (u8*)&srcIP);
NetLib::WriteByteArray(headerSegment, &counter, 4, (u8*)&dstIP);
NetLib::WriteByte08(headerSegment, &counter, 0);
NetLib::WriteByte08(headerSegment, &counter, (u8)protocol);
NetLib::WriteUInt16(headerSegment, &counter, GetLength());
//Pseudo Header added
//Rest of data is normal Header+data (with zerored checksum feild)
checksum = 0;
WriteBytes(headerSegment, &counter);
//Zero alignment byte
if (counter != pHeaderLen)
NetLib::WriteByte08(headerSegment, &counter, 0);
checksum = IP_Packet::InternetChecksum(headerSegment, pHeaderLen);
delete[] headerSegment;
}
bool TCP_Packet::VerifyChecksum(IP_Address srcIP, IP_Address dstIP)
{
ReComputeHeaderLen();
int pHeaderLen = (12) + headerLength + payload->GetLength();
if ((pHeaderLen & 1) != 0)
pHeaderLen += 1;
u8* headerSegment = new u8[pHeaderLen];
int counter = 0;
NetLib::WriteByteArray(headerSegment, &counter, 4, (u8*)&srcIP);
NetLib::WriteByteArray(headerSegment, &counter, 4, (u8*)&dstIP);
NetLib::WriteByte08(headerSegment, &counter, 0);
NetLib::WriteByte08(headerSegment, &counter, (u8)protocol);
NetLib::WriteUInt16(headerSegment, &counter, GetLength());
//Pseudo Header added
//Rest of data is normal Header+data
WriteBytes(headerSegment, &counter);
//Zero alignment byte
if (counter != pHeaderLen)
NetLib::WriteByte08(headerSegment, &counter, 0);
u16 csumCal = IP_Packet::InternetChecksum(headerSegment, pHeaderLen);
delete[] headerSegment;
return (csumCal == 0);
}
} // namespace PacketReader::IP::TCP

View File

@ -0,0 +1,99 @@
/* 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 "TCP_Options.h"
#include "DEV9/PacketReader/IP/IP_Packet.h"
namespace PacketReader::IP::TCP
{
class TCP_Packet : public IP_Payload
{
public:
u16 sourcePort;
u16 destinationPort;
u32 sequenceNumber;
u32 acknowledgementNumber;
private:
u8 dataOffsetAndNS_Flag = 0;
int headerLength; //Can have varying Header Len
u8 flags = 0;
public:
u16 windowSize;
private:
u16 checksum;
u16 urgentPointer = 0;
public:
std::vector<BaseOption*> options;
private:
const static IP_Type protocol = IP_Type::TCP;
std::unique_ptr<Payload> payload;
public:
//Flags
bool GetNS();
void SetNS(bool value);
bool GetCWR();
void SetCWR(bool value);
bool GetECE();
void SetECE(bool value);
bool GetURG();
void SetURG(bool value);
bool GetACK();
void SetACK(bool value);
bool GetPSH();
void SetPSH(bool value);
bool GetRST();
void SetRST(bool value);
bool GetSYN();
void SetSYN(bool value);
bool GetFIN();
void SetFIN(bool value);
//Takes ownership of payload
TCP_Packet(Payload* data);
TCP_Packet(u8* buffer, int bufferSize);
TCP_Packet(const TCP_Packet&);
Payload* GetPayload();
virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset);
virtual TCP_Packet* Clone() const;
virtual u8 GetProtocol();
virtual bool VerifyChecksum(IP_Address srcIP, IP_Address dstIP);
virtual void CalculateChecksum(IP_Address srcIP, IP_Address dstIP);
private:
void ReComputeHeaderLen();
};
} // namespace PacketReader::IP::TCP

View File

@ -293,7 +293,11 @@
<ClCompile Include="DEV9\InternalServers\DHCP_Server.cpp" />
<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\EthernetFrame.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Options.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Packet.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\DNS\DNS_Classes.cpp" />
@ -739,7 +743,11 @@
<ClInclude Include="DEV9\InternalServers\DNS_Logger.h" />
<ClInclude Include="DEV9\InternalServers\DNS_Server.h" />
<ClInclude Include="DEV9\net.h" />
<ClInclude Include="DEV9\PacketReader\ARP\ARP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\EthernetFrame.h" />
<ClInclude Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Options.h" />
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.h" />
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\IP\UDP\DNS\DNS_Classes.h" />

View File

@ -184,9 +184,18 @@
<Filter Include="System\Ps2\DEV9\PacketReader">
<UniqueIdentifier>{57c4be94-9a2c-469b-9b02-b3b324857fc5}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\ARP">
<UniqueIdentifier>{12c15e0b-4647-4ce2-9bc4-89e6e9e8f531}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP">
<UniqueIdentifier>{a0723e13-c839-464d-8cfa-6c440ae03537}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP\ICMP">
<UniqueIdentifier>{928400ad-4db4-44ca-9a6d-c65e489c8ea0}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP\TCP">
<UniqueIdentifier>{7c01f24d-2141-4054-b3f9-1d9c67ae7ad6}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP\UDP">
<UniqueIdentifier>{db2fc75d-6552-4991-9155-885abd8796e4}</UniqueIdentifier>
</Filter>
@ -1223,6 +1232,18 @@
<ClCompile Include="DEV9\InternalServers\DNS_Server.cpp">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\ARP\ARP_Packet.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>
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Options.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Packet.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\UDP\DHCP</Filter>
</ClCompile>
@ -2290,6 +2311,18 @@
<ClInclude Include="DEV9\net.h">
<Filter>System\Ps2\DEV9</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\ARP\ARP_Packet.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>
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Options.h">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Packet.h">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.h">
<Filter>System\Ps2\DEV9\PacketReader\IP\UDP\DHCP</Filter>
</ClInclude>

View File

@ -156,7 +156,11 @@
<ClCompile Include="DEV9\InternalServers\DHCP_Server.cpp" />
<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\EthernetFrame.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Options.cpp" />
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Packet.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\DNS\DNS_Classes.cpp" />
@ -456,7 +460,11 @@
<ClInclude Include="DEV9\InternalServers\DNS_Logger.h" />
<ClInclude Include="DEV9\InternalServers\DNS_Server.h" />
<ClInclude Include="DEV9\net.h" />
<ClInclude Include="DEV9\PacketReader\ARP\ARP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\EthernetFrame.h" />
<ClInclude Include="DEV9\PacketReader\IP\ICMP\ICMP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Options.h" />
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.h" />
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Packet.h" />
<ClInclude Include="DEV9\PacketReader\IP\UDP\DNS\DNS_Classes.h" />

View File

@ -142,9 +142,18 @@
<Filter Include="System\Ps2\DEV9\PacketReader">
<UniqueIdentifier>{57c4be94-9a2c-469b-9b02-b3b324857fc5}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\ARP">
<UniqueIdentifier>{12c15e0b-4647-4ce2-9bc4-89e6e9e8f531}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP">
<UniqueIdentifier>{a0723e13-c839-464d-8cfa-6c440ae03537}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP\ICMP">
<UniqueIdentifier>{928400ad-4db4-44ca-9a6d-c65e489c8ea0}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP\TCP">
<UniqueIdentifier>{7c01f24d-2141-4054-b3f9-1d9c67ae7ad6}</UniqueIdentifier>
</Filter>
<Filter Include="System\Ps2\DEV9\PacketReader\IP\UDP">
<UniqueIdentifier>{db2fc75d-6552-4991-9155-885abd8796e4}</UniqueIdentifier>
</Filter>
@ -878,6 +887,18 @@
<ClCompile Include="DEV9\InternalServers\DNS_Server.cpp">
<Filter>System\Ps2\DEV9\InternalServers</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\ARP\ARP_Packet.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>
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Options.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\IP\TCP\TCP_Packet.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClCompile>
<ClCompile Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.cpp">
<Filter>System\Ps2\DEV9\PacketReader\IP\UDP\DHCP</Filter>
</ClCompile>
@ -1619,6 +1640,18 @@
<ClInclude Include="DEV9\net.h">
<Filter>System\Ps2\DEV9</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\ARP\ARP_Packet.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>
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Options.h">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\IP\TCP\TCP_Packet.h">
<Filter>System\Ps2\DEV9\PacketReader\IP\TCP</Filter>
</ClInclude>
<ClInclude Include="DEV9\PacketReader\IP\UDP\DHCP\DHCP_Options.h">
<Filter>System\Ps2\DEV9\PacketReader\IP\UDP\DHCP</Filter>
</ClInclude>