DEV9: Add cloning of packets

This commit is contained in:
TheLastRar 2021-09-10 01:10:58 +01:00 committed by refractionpcsx2
parent 5ac9b5576a
commit db220001f6
12 changed files with 241 additions and 1 deletions

View File

@ -23,7 +23,7 @@ namespace PacketReader::IP
virtual u8 GetLength() = 0; virtual u8 GetLength() = 0;
virtual u8 GetCode() = 0; virtual u8 GetCode() = 0;
virtual void WriteBytes(u8* buffer, int* offset) = 0; virtual void WriteBytes(u8* buffer, int* offset) = 0;
virtual BaseOption* Clone() const = 0;
virtual ~BaseOption() {} virtual ~BaseOption() {}
}; };
@ -33,6 +33,7 @@ namespace PacketReader::IP
bool IsCopyOnFragment(); bool IsCopyOnFragment();
u8 GetClass(); //0 = control, 2 = debugging and measurement u8 GetClass(); //0 = control, 2 = debugging and measurement
u8 GetNumber(); u8 GetNumber();
virtual IPOption* Clone() const = 0;
}; };
class IPopUnk : public IPOption class IPopUnk : public IPOption
@ -48,6 +49,11 @@ namespace PacketReader::IP
virtual u8 GetCode() { return code; } virtual u8 GetCode() { return code; }
void WriteBytes(u8* buffer, int* offset); void WriteBytes(u8* buffer, int* offset);
virtual IPopUnk* Clone() const
{
return new IPopUnk(*this);
}
}; };
class IPopNOP : public IPOption class IPopNOP : public IPOption
@ -61,6 +67,11 @@ namespace PacketReader::IP
buffer[*offset] = GetCode(); buffer[*offset] = GetCode();
(*offset)++; (*offset)++;
} }
virtual IPopNOP* Clone() const
{
return new IPopNOP(*this);
}
}; };
class IPopRouterAlert : public IPOption class IPopRouterAlert : public IPOption
@ -76,5 +87,10 @@ namespace PacketReader::IP
virtual u8 GetCode() { return 148; } virtual u8 GetCode() { return 148; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual IPopRouterAlert* Clone() const
{
return new IPopRouterAlert(*this);
}
}; };
} // namespace PacketReader::IP } // namespace PacketReader::IP

View File

@ -146,6 +146,25 @@ namespace PacketReader::IP
payload = std::make_unique<IP_PayloadPtr>(&buffer[offset], length - offset, protocol); payload = std::make_unique<IP_PayloadPtr>(&buffer[offset], length - offset, protocol);
} }
IP_Packet::IP_Packet(const IP_Packet& original)
: headerLength{original.headerLength}
, dscp{original.dscp}
, id{original.id}
, fragmentFlags1{original.fragmentFlags1}
, fragmentFlags2{original.fragmentFlags2}
, timeToLive{original.timeToLive}
, protocol{original.protocol}
, checksum{original.checksum}
, sourceIP{original.sourceIP}
, destinationIP{original.destinationIP}
, 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());
}
IP_Payload* IP_Packet::GetPayload() IP_Payload* IP_Packet::GetPayload()
{ {
return payload.get(); return payload.get();
@ -191,6 +210,11 @@ namespace PacketReader::IP
payload->WriteBytes(buffer, offset); payload->WriteBytes(buffer, offset);
} }
IP_Packet* IP_Packet::Clone() const
{
return new IP_Packet(*this);
}
void IP_Packet::ReComputeHeaderLen() void IP_Packet::ReComputeHeaderLen()
{ {
int opOffset = 20; int opOffset = 20;

View File

@ -63,6 +63,8 @@ namespace PacketReader::IP
std::unique_ptr<IP_Payload> payload; std::unique_ptr<IP_Payload> payload;
public: public:
int GetHeaderLength();
//DSCP/TOS Flags //DSCP/TOS Flags
/* Upper 3 Bits /* Upper 3 Bits
@ -122,11 +124,13 @@ namespace PacketReader::IP
//Takes ownership of payload //Takes ownership of payload
IP_Packet(IP_Payload* data); IP_Packet(IP_Payload* data);
IP_Packet(u8* buffer, int bufferSize, bool fromICMP = false); IP_Packet(u8* buffer, int bufferSize, bool fromICMP = false);
IP_Packet(const IP_Packet&);
IP_Payload* GetPayload(); IP_Payload* GetPayload();
virtual int GetLength(); virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual IP_Packet* Clone() const;
bool VerifyChecksum(); bool VerifyChecksum();
static u16 InternetChecksum(u8* buffer, int length); static u16 InternetChecksum(u8* buffer, int length);

View File

@ -25,6 +25,7 @@ namespace PacketReader::IP
virtual u8 GetProtocol() = 0; virtual u8 GetProtocol() = 0;
virtual bool VerifyChecksum(IP_Address srcIP, IP_Address dstIP) { return false; } virtual bool VerifyChecksum(IP_Address srcIP, IP_Address dstIP) { return false; }
virtual void CalculateChecksum(IP_Address srcIP, IP_Address dstIP) {} virtual void CalculateChecksum(IP_Address srcIP, IP_Address dstIP) {}
virtual IP_Payload* Clone() const = 0;
virtual ~IP_Payload() {} virtual ~IP_Payload() {}
}; };
@ -46,6 +47,17 @@ namespace PacketReader::IP
if (len != 0) if (len != 0)
data = std::make_unique<u8[]>(len); data = std::make_unique<u8[]>(len);
} }
IP_PayloadData(const IP_PayloadData& original)
{
protocol = original.protocol;
length = original.length;
if (length != 0)
{
data = std::make_unique<u8[]>(length);
memcpy(data.get(), original.data.get(), length);
}
}
virtual int GetLength() virtual int GetLength()
{ {
return length; return length;
@ -62,6 +74,10 @@ namespace PacketReader::IP
{ {
return protocol; return protocol;
} }
virtual IP_PayloadData* Clone() const
{
return new IP_PayloadData(*this);
}
}; };
//Pointer to bytes not owned by class //Pointer to bytes not owned by class
@ -81,6 +97,7 @@ namespace PacketReader::IP
length = len; length = len;
protocol = prot; protocol = prot;
} }
IP_PayloadPtr(const IP_PayloadPtr&) = delete;
virtual int GetLength() virtual int GetLength()
{ {
return length; return length;
@ -95,6 +112,12 @@ namespace PacketReader::IP
memcpy(buffer, data, length); memcpy(buffer, data, length);
*offset += length; *offset += length;
} }
virtual IP_Payload* Clone() const
{
IP_PayloadData* ret = new IP_PayloadData(length, protocol);
memcpy(ret->data.get(), data, length);
return ret;
}
virtual u8 GetProtocol() virtual u8 GetProtocol()
{ {
return protocol; return protocol;

View File

@ -34,6 +34,11 @@ namespace PacketReader::IP::UDP::DHCP
buffer[*offset] = GetCode(); buffer[*offset] = GetCode();
(*offset)++; (*offset)++;
} }
virtual DHCPopNOP* Clone() const
{
return new DHCPopNOP(*this);
}
}; };
class DHCPopSubnet : public BaseOption class DHCPopSubnet : public BaseOption
@ -48,6 +53,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 1; } virtual u8 GetCode() { return 1; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopSubnet* Clone() const
{
return new DHCPopSubnet(*this);
}
}; };
class DHCPopRouter : public BaseOption //can be longer then 1 address class DHCPopRouter : public BaseOption //can be longer then 1 address
@ -61,6 +71,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 3; } virtual u8 GetCode() { return 3; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopRouter* Clone() const
{
return new DHCPopRouter(*this);
}
}; };
class DHCPopDNS : public BaseOption //can be longer then 1 address class DHCPopDNS : public BaseOption //can be longer then 1 address
@ -74,6 +89,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 6; } virtual u8 GetCode() { return 6; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopDNS* Clone() const
{
return new DHCPopDNS(*this);
}
}; };
class DHCPopHostName : public BaseOption class DHCPopHostName : public BaseOption
@ -89,6 +109,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 12; } virtual u8 GetCode() { return 12; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopHostName* Clone() const
{
return new DHCPopHostName(*this);
}
}; };
class DHCPopDnsName : public BaseOption class DHCPopDnsName : public BaseOption
@ -104,6 +129,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 15; } virtual u8 GetCode() { return 15; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopDnsName* Clone() const
{
return new DHCPopDnsName(*this);
}
}; };
class DHCPopBCIP : public BaseOption //The IP to send broadcasts to class DHCPopBCIP : public BaseOption //The IP to send broadcasts to
@ -118,6 +148,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 28; } virtual u8 GetCode() { return 28; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopBCIP* Clone() const
{
return new DHCPopBCIP(*this);
}
}; };
//What even sent this? //What even sent this?
@ -146,6 +181,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 46; } virtual u8 GetCode() { return 46; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopNBIOSType* Clone() const
{
return new DHCPopNBIOSType(*this);
}
}; };
class DHCPopREQIP : public BaseOption //The IP to send broadcasts to class DHCPopREQIP : public BaseOption //The IP to send broadcasts to
@ -160,6 +200,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 50; } virtual u8 GetCode() { return 50; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopREQIP* Clone() const
{
return new DHCPopREQIP(*this);
}
}; };
class DHCPopIPLT : public BaseOption class DHCPopIPLT : public BaseOption
@ -174,6 +219,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 51; } virtual u8 GetCode() { return 51; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopIPLT* Clone() const
{
return new DHCPopIPLT(*this);
}
}; };
class DHCPopMSG : public BaseOption class DHCPopMSG : public BaseOption
@ -187,6 +237,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 53; } virtual u8 GetCode() { return 53; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopMSG* Clone() const
{
return new DHCPopMSG(*this);
}
}; };
class DHCPopSERVIP : public BaseOption //DHCP server ip class DHCPopSERVIP : public BaseOption //DHCP server ip
@ -201,6 +256,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 54; } virtual u8 GetCode() { return 54; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopSERVIP* Clone() const
{
return new DHCPopSERVIP(*this);
}
}; };
class DHCPopREQLIST : public BaseOption class DHCPopREQLIST : public BaseOption
@ -215,6 +275,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 55; } virtual u8 GetCode() { return 55; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopREQLIST* Clone() const
{
return new DHCPopREQLIST(*this);
}
}; };
class DHCPopMSGStr : public BaseOption class DHCPopMSGStr : public BaseOption
@ -230,6 +295,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 56; } virtual u8 GetCode() { return 56; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopMSGStr* Clone() const
{
return new DHCPopMSGStr(*this);
}
}; };
class DHCPopMMSGS : public BaseOption class DHCPopMMSGS : public BaseOption
@ -244,6 +314,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 57; } virtual u8 GetCode() { return 57; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopMMSGS* Clone() const
{
return new DHCPopMMSGS(*this);
}
}; };
class DHCPopT1 : public BaseOption class DHCPopT1 : public BaseOption
@ -258,6 +333,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 58; } virtual u8 GetCode() { return 58; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopT1* Clone() const
{
return new DHCPopT1(*this);
}
}; };
class DHCPopT2 : public BaseOption class DHCPopT2 : public BaseOption
@ -272,6 +352,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 59; } virtual u8 GetCode() { return 59; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopT2* Clone() const
{
return new DHCPopT2(*this);
}
}; };
class DHCPopClassID : public BaseOption class DHCPopClassID : public BaseOption
@ -287,6 +372,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 60; } virtual u8 GetCode() { return 60; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopClassID* Clone() const
{
return new DHCPopClassID(*this);
}
}; };
class DHCPopClientID final : public BaseOption class DHCPopClientID final : public BaseOption
@ -301,6 +391,11 @@ namespace PacketReader::IP::UDP::DHCP
virtual u8 GetCode() { return 61; } virtual u8 GetCode() { return 61; }
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCPopClientID* Clone() const
{
return new DHCPopClientID(*this);
}
}; };
class DHCPopEND : public BaseOption class DHCPopEND : public BaseOption
@ -316,5 +411,10 @@ namespace PacketReader::IP::UDP::DHCP
buffer[*offset] = GetCode(); buffer[*offset] = GetCode();
(*offset)++; (*offset)++;
} }
virtual DHCPopEND* Clone() const
{
return new DHCPopEND(*this);
}
}; };
} // namespace PacketReader::IP::UDP::DHCP } // namespace PacketReader::IP::UDP::DHCP

View File

@ -151,6 +151,30 @@ namespace PacketReader::IP::UDP::DHCP
} }
} while (opReadFin == false); } while (opReadFin == false);
} }
DHCP_Packet::DHCP_Packet(const DHCP_Packet& original)
: op{original.op}
, hardwareType(original.hardwareType)
, hardwareAddressLength{original.hardwareAddressLength}
, hops{original.hops}
, transactionID{original.transactionID}
, seconds{original.seconds}
, flags{original.flags}
, clientIP{original.clientIP}
, yourIP{original.yourIP}
, serverIP{original.serverIP}
, gatewayIP{original.gatewayIP}
, magicCookie(original.magicCookie)
, maxLength{original.maxLength}
{
memcpy(clientHardwareAddress, original.clientHardwareAddress, 16);
//Assume BOOTP unused
//Clone options
options.reserve(original.options.size());
for (size_t i = 0; i < options.size(); i++)
options.push_back(original.options[i]->Clone());
}
int DHCP_Packet::GetLength() int DHCP_Packet::GetLength()
{ {
@ -215,6 +239,11 @@ namespace PacketReader::IP::UDP::DHCP
*offset = start + GetLength(); *offset = start + GetLength();
} }
DHCP_Packet* DHCP_Packet::Clone() const
{
return new DHCP_Packet(*this);
}
DHCP_Packet::~DHCP_Packet() DHCP_Packet::~DHCP_Packet()
{ {
for (size_t i = 0; i < options.size(); i++) for (size_t i = 0; i < options.size(); i++)

View File

@ -46,9 +46,11 @@ namespace PacketReader::IP::UDP::DHCP
DHCP_Packet() {} DHCP_Packet() {}
DHCP_Packet(u8* buffer, int bufferSize); DHCP_Packet(u8* buffer, int bufferSize);
DHCP_Packet(const DHCP_Packet&);
virtual int GetLength(); virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DHCP_Packet* Clone() const;
virtual ~DHCP_Packet(); virtual ~DHCP_Packet();
}; };

View File

@ -191,4 +191,9 @@ namespace PacketReader::IP::UDP::DNS
for (size_t i = 0; i < additional.size(); i++) for (size_t i = 0; i < additional.size(); i++)
additional[i].WriteBytes(buffer, offset); additional[i].WriteBytes(buffer, offset);
} }
DNS_Packet* DNS_Packet::Clone() const
{
return new DNS_Packet(*this);
}
} // namespace PacketReader::IP::UDP::DNS } // namespace PacketReader::IP::UDP::DNS

View File

@ -77,5 +77,6 @@ namespace PacketReader::IP::UDP::DNS
virtual int GetLength(); virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual DNS_Packet* Clone() const;
}; };
} // namespace PacketReader::IP::UDP::DNS } // namespace PacketReader::IP::UDP::DNS

View File

@ -46,6 +46,13 @@ namespace PacketReader::IP::UDP
payload = std::make_unique<PayloadPtr>(&buffer[offset], length - offset); payload = std::make_unique<PayloadPtr>(&buffer[offset], length - offset);
//AllDone //AllDone
} }
UDP_Packet::UDP_Packet(const UDP_Packet& original)
: sourcePort{original.sourcePort}
, destinationPort{original.destinationPort}
, checksum{original.destinationPort}
, payload{original.payload->Clone()}
{
}
Payload* UDP_Packet::GetPayload() Payload* UDP_Packet::GetPayload()
{ {
@ -67,6 +74,11 @@ namespace PacketReader::IP::UDP
payload->WriteBytes(buffer, offset); payload->WriteBytes(buffer, offset);
} }
UDP_Packet* UDP_Packet::Clone() const
{
return new UDP_Packet(*this);
}
u8 UDP_Packet::GetProtocol() u8 UDP_Packet::GetProtocol()
{ {
return (u8)protocol; return (u8)protocol;

View File

@ -37,11 +37,13 @@ namespace PacketReader::IP::UDP
//Takes ownership of payload //Takes ownership of payload
UDP_Packet(Payload* data); UDP_Packet(Payload* data);
UDP_Packet(u8* buffer, int bufferSize); UDP_Packet(u8* buffer, int bufferSize);
UDP_Packet(const UDP_Packet&);
Payload* GetPayload(); Payload* GetPayload();
virtual int GetLength(); virtual int GetLength();
virtual void WriteBytes(u8* buffer, int* offset); virtual void WriteBytes(u8* buffer, int* offset);
virtual UDP_Packet* Clone() const;
virtual u8 GetProtocol(); virtual u8 GetProtocol();

View File

@ -22,6 +22,7 @@ namespace PacketReader
public: public:
virtual int GetLength() = 0; virtual int GetLength() = 0;
virtual void WriteBytes(u8* buffer, int* offset) = 0; virtual void WriteBytes(u8* buffer, int* offset) = 0;
virtual Payload* Clone() const = 0;
virtual ~Payload() {} virtual ~Payload() {}
}; };
@ -42,6 +43,16 @@ namespace PacketReader
if (len != 0) if (len != 0)
data = std::make_unique<u8[]>(len); data = std::make_unique<u8[]>(len);
} }
PayloadData(const PayloadData& original)
{
length = original.length;
if (length != 0)
{
data = std::make_unique<u8[]>(length);
memcpy(data.get(), original.data.get(), length);
}
}
virtual int GetLength() virtual int GetLength()
{ {
return length; return length;
@ -54,6 +65,10 @@ namespace PacketReader
memcpy(&buffer[*offset], data.get(), length); memcpy(&buffer[*offset], data.get(), length);
*offset += length; *offset += length;
} }
virtual PayloadData* Clone() const
{
return new PayloadData(*this);
}
}; };
//Pointer to bytes not owned by class //Pointer to bytes not owned by class
@ -71,6 +86,7 @@ namespace PacketReader
data = ptr; data = ptr;
length = len; length = len;
} }
PayloadPtr(const PayloadPtr&) = delete;
virtual int GetLength() virtual int GetLength()
{ {
return length; return length;
@ -85,5 +101,11 @@ namespace PacketReader
memcpy(&buffer[*offset], data, length); memcpy(&buffer[*offset], data, length);
*offset += length; *offset += length;
} }
virtual Payload* Clone() const
{
PayloadData* ret = new PayloadData(length);
memcpy(ret->data.get(), data, length);
return ret;
}
}; };
} // namespace PacketReader } // namespace PacketReader