Move network method definitions to .cpp files
This commit is contained in:
parent
74a92bc9d5
commit
f9f282a595
13 changed files with 430 additions and 330 deletions
2
Makefile
2
Makefile
|
@ -4,7 +4,7 @@ OBJS = armc-start.o armc-cstartup.o armc-cstubs.o armc-cppstubs.o \
|
||||||
Drive.o Pi1541.o DiskImage.o iec_bus.o iec_commands.o m6502.o m6522.o \
|
Drive.o Pi1541.o DiskImage.o iec_bus.o iec_commands.o m6502.o m6522.o \
|
||||||
gcr.o prot.o lz.o emmc.o diskio.o options.o Screen.o SSD1306.o ScreenLCD.o \
|
gcr.o prot.o lz.o emmc.o diskio.o options.o Screen.o SSD1306.o ScreenLCD.o \
|
||||||
Timer.o FileBrowser.o DiskCaddy.o ROMs.o InputMappings.o xga_font_data.o m8520.o wd177x.o Pi1581.o SpinLock.o \
|
Timer.o FileBrowser.o DiskCaddy.o ROMs.o InputMappings.o xga_font_data.o m8520.o wd177x.o Pi1581.o SpinLock.o \
|
||||||
net.o net-tftp.o
|
net.o net-tftp.o net-arp.o net-ethernet.o net-icmp.o net-ipv4.o net-udp.o
|
||||||
|
|
||||||
SRCDIR = src
|
SRCDIR = src
|
||||||
OBJS := $(addprefix $(SRCDIR)/, $(OBJS))
|
OBJS := $(addprefix $(SRCDIR)/, $(OBJS))
|
||||||
|
|
61
src/net-arp.cpp
Normal file
61
src/net-arp.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#include "net-arp.h"
|
||||||
|
|
||||||
|
Ipv4ArpPacket::Ipv4ArpPacket()
|
||||||
|
{}
|
||||||
|
|
||||||
|
Ipv4ArpPacket::Ipv4ArpPacket(std::uint16_t operation) :
|
||||||
|
hardwareType(1), // Ethernet
|
||||||
|
protocolType(ETHERTYPE_IPV4), // IPv4
|
||||||
|
hardwareAddressLength(6),
|
||||||
|
protocolAddressLength(4),
|
||||||
|
operation(operation)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::size_t Ipv4ArpPacket::Serialize(std::uint8_t* buffer)
|
||||||
|
{
|
||||||
|
buffer[0] = hardwareType >> 8;
|
||||||
|
buffer[1] = hardwareType;
|
||||||
|
buffer[2] = protocolType >> 8;
|
||||||
|
buffer[3] = protocolType;
|
||||||
|
buffer[4] = hardwareAddressLength;
|
||||||
|
buffer[5] = protocolAddressLength;
|
||||||
|
buffer[6] = operation >> 8;
|
||||||
|
buffer[7] = operation;
|
||||||
|
|
||||||
|
memcpy(buffer + 8, senderMac.data(), 6);
|
||||||
|
|
||||||
|
buffer[14] = senderIp >> 24;
|
||||||
|
buffer[15] = senderIp >> 16;
|
||||||
|
buffer[16] = senderIp >> 8;
|
||||||
|
buffer[17] = senderIp;
|
||||||
|
|
||||||
|
memcpy(buffer + 18, targetMac.data(), 6);
|
||||||
|
|
||||||
|
buffer[24] = targetIp >> 24;
|
||||||
|
buffer[25] = targetIp >> 16;
|
||||||
|
buffer[26] = targetIp >> 8;
|
||||||
|
buffer[27] = targetIp;
|
||||||
|
|
||||||
|
return 28;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static
|
||||||
|
Ipv4ArpPacket Ipv4ArpPacket::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
Ipv4ArpPacket self;
|
||||||
|
|
||||||
|
self.hardwareType = buffer[0] << 8 | buffer[1];
|
||||||
|
self.protocolType = buffer[2] << 8 | buffer[3];
|
||||||
|
self.hardwareAddressLength = buffer[4];
|
||||||
|
self.protocolAddressLength = buffer[5];
|
||||||
|
self.operation = buffer[6] << 8 | buffer[7];
|
||||||
|
|
||||||
|
memcpy(self.senderMac.data(), buffer + 8, 6);
|
||||||
|
self.senderIp =
|
||||||
|
buffer[14] << 24 | buffer[15] << 16 | buffer[16] << 8 | buffer[17];
|
||||||
|
memcpy(self.targetMac.data(), buffer + 18, 6);
|
||||||
|
self.targetIp =
|
||||||
|
buffer[24] << 24 | buffer[25] << 16 | buffer[26] << 8 | buffer[27];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
|
@ -14,15 +14,8 @@ struct Ipv4ArpPacket
|
||||||
MacAddress targetMac;
|
MacAddress targetMac;
|
||||||
std::uint32_t targetIp;
|
std::uint32_t targetIp;
|
||||||
|
|
||||||
Ipv4ArpPacket() {}
|
Ipv4ArpPacket();
|
||||||
|
Ipv4ArpPacket(std::uint16_t operation);
|
||||||
Ipv4ArpPacket(std::uint16_t operation) :
|
|
||||||
hardwareType(1), // Ethernet
|
|
||||||
protocolType(ETHERTYPE_IPV4), // IPv4
|
|
||||||
hardwareAddressLength(6),
|
|
||||||
protocolAddressLength(4),
|
|
||||||
operation(operation)
|
|
||||||
{}
|
|
||||||
|
|
||||||
constexpr std::size_t SerializedLength() const
|
constexpr std::size_t SerializedLength() const
|
||||||
{
|
{
|
||||||
|
@ -38,51 +31,7 @@ struct Ipv4ArpPacket
|
||||||
sizeof(targetIp);
|
sizeof(targetIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t Serialize(std::uint8_t* buffer)
|
std::size_t Serialize(std::uint8_t* buffer);
|
||||||
{
|
|
||||||
buffer[0] = hardwareType >> 8;
|
|
||||||
buffer[1] = hardwareType;
|
|
||||||
buffer[2] = protocolType >> 8;
|
|
||||||
buffer[3] = protocolType;
|
|
||||||
buffer[4] = hardwareAddressLength;
|
|
||||||
buffer[5] = protocolAddressLength;
|
|
||||||
buffer[6] = operation >> 8;
|
|
||||||
buffer[7] = operation;
|
|
||||||
|
|
||||||
memcpy(buffer + 8, senderMac.data(), 6);
|
static Ipv4ArpPacket Deserialize(const uint8_t* buffer);
|
||||||
|
|
||||||
buffer[14] = senderIp >> 24;
|
|
||||||
buffer[15] = senderIp >> 16;
|
|
||||||
buffer[16] = senderIp >> 8;
|
|
||||||
buffer[17] = senderIp;
|
|
||||||
|
|
||||||
memcpy(buffer + 18, targetMac.data(), 6);
|
|
||||||
|
|
||||||
buffer[24] = targetIp >> 24;
|
|
||||||
buffer[25] = targetIp >> 16;
|
|
||||||
buffer[26] = targetIp >> 8;
|
|
||||||
buffer[27] = targetIp;
|
|
||||||
|
|
||||||
return 28;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Ipv4ArpPacket Deserialize(const uint8_t* buffer)
|
|
||||||
{
|
|
||||||
Ipv4ArpPacket self;
|
|
||||||
|
|
||||||
self.hardwareType = buffer[0] << 8 | buffer[1];
|
|
||||||
self.protocolType = buffer[2] << 8 | buffer[3];
|
|
||||||
self.hardwareAddressLength = buffer[4];
|
|
||||||
self.protocolAddressLength = buffer[5];
|
|
||||||
self.operation = buffer[6] << 8 | buffer[7];
|
|
||||||
|
|
||||||
memcpy(self.senderMac.data(), buffer + 8, 6);
|
|
||||||
self.senderIp =
|
|
||||||
buffer[14] << 24 | buffer[15] << 16 | buffer[16] << 8 | buffer[17];
|
|
||||||
memcpy(self.targetMac.data(), buffer + 18, 6);
|
|
||||||
self.targetIp =
|
|
||||||
buffer[24] << 24 | buffer[25] << 16 | buffer[26] << 8 | buffer[27];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
40
src/net-ethernet.cpp
Normal file
40
src/net-ethernet.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include "net-ethernet.h"
|
||||||
|
|
||||||
|
EthernetFrameHeader::EthernetFrameHeader()
|
||||||
|
{}
|
||||||
|
|
||||||
|
EthernetFrameHeader::EthernetFrameHeader(std::uint16_t type) :
|
||||||
|
macDestination{255, 255, 255, 255, 255, 255},
|
||||||
|
macSource{0, 0, 0, 0, 0, 0},
|
||||||
|
type(type)
|
||||||
|
{}
|
||||||
|
|
||||||
|
EthernetFrameHeader::EthernetFrameHeader(
|
||||||
|
MacAddress macDestination, MacAddress macSource, uint16_t type
|
||||||
|
) : macDestination(macDestination), macSource(macSource), type(type)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::size_t EthernetFrameHeader::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
std::size_t i = 0;
|
||||||
|
|
||||||
|
std::memcpy(buffer + i, macDestination.data(), macDestination.size());
|
||||||
|
i += sizeof(macDestination);
|
||||||
|
|
||||||
|
std::memcpy(buffer + i, macSource.data(), macSource.size());
|
||||||
|
i += sizeof(macSource);
|
||||||
|
|
||||||
|
buffer[i++] = type >> 8;
|
||||||
|
buffer[i++] = type;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
EthernetFrameHeader EthernetFrameHeader::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
EthernetFrameHeader self;
|
||||||
|
std::memcpy(self.macDestination.data(), buffer + 0, self.macDestination.size());
|
||||||
|
std::memcpy(self.macSource.data(), buffer + 6, self.macSource.size());
|
||||||
|
self.type = buffer[12] << 8 | buffer[13];
|
||||||
|
return self;
|
||||||
|
}
|
|
@ -7,45 +7,15 @@ struct EthernetFrameHeader
|
||||||
MacAddress macSource;
|
MacAddress macSource;
|
||||||
std::uint16_t type;
|
std::uint16_t type;
|
||||||
|
|
||||||
EthernetFrameHeader() {}
|
EthernetFrameHeader();
|
||||||
|
EthernetFrameHeader(std::uint16_t type);
|
||||||
EthernetFrameHeader(std::uint16_t type) :
|
EthernetFrameHeader(MacAddress macDestination, MacAddress macSource, uint16_t type);
|
||||||
macDestination{255, 255, 255, 255, 255, 255},
|
|
||||||
macSource{0, 0, 0, 0, 0, 0},
|
|
||||||
type(type)
|
|
||||||
{}
|
|
||||||
|
|
||||||
EthernetFrameHeader(MacAddress macDestination, MacAddress macSource, uint16_t type) :
|
|
||||||
macDestination(macDestination), macSource(macSource), type(type)
|
|
||||||
{}
|
|
||||||
|
|
||||||
constexpr static std::size_t SerializedLength()
|
constexpr static std::size_t SerializedLength()
|
||||||
{
|
{
|
||||||
return sizeof(macDestination) + sizeof(macSource) + sizeof(type);
|
return sizeof(macDestination) + sizeof(macSource) + sizeof(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t Serialize(uint8_t* buffer) const
|
std::size_t Serialize(uint8_t* buffer) const;
|
||||||
{
|
static EthernetFrameHeader Deserialize(const uint8_t* buffer);
|
||||||
std::size_t i = 0;
|
|
||||||
|
|
||||||
std::memcpy(buffer + i, macDestination.data(), macDestination.size());
|
|
||||||
i += sizeof(macDestination);
|
|
||||||
|
|
||||||
std::memcpy(buffer + i, macSource.data(), macSource.size());
|
|
||||||
i += sizeof(macSource);
|
|
||||||
|
|
||||||
buffer[i++] = type >> 8;
|
|
||||||
buffer[i++] = type;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EthernetFrameHeader Deserialize(const uint8_t* buffer)
|
|
||||||
{
|
|
||||||
EthernetFrameHeader self;
|
|
||||||
std::memcpy(self.macDestination.data(), buffer + 0, self.macDestination.size());
|
|
||||||
std::memcpy(self.macSource.data(), buffer + 6, self.macSource.size());
|
|
||||||
self.type = buffer[12] << 8 | buffer[13];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
54
src/net-icmp.cpp
Normal file
54
src/net-icmp.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "net-icmp.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// IcmpPacketHeader
|
||||||
|
//
|
||||||
|
IcmpPacketHeader::IcmpPacketHeader() {}
|
||||||
|
|
||||||
|
IcmpPacketHeader::IcmpPacketHeader(std::uint8_t type, std::uint8_t code) :
|
||||||
|
type(type), code(code), checksum(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::size_t IcmpPacketHeader::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
buffer[i++] = type;
|
||||||
|
buffer[i++] = code;
|
||||||
|
buffer[i++] = checksum;
|
||||||
|
buffer[i++] = checksum >> 8;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
IcmpPacketHeader IcmpPacketHeader::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
IcmpPacketHeader self;
|
||||||
|
self.type = buffer[0];
|
||||||
|
self.code = buffer[1];
|
||||||
|
self.checksum = buffer[2] << 8 | buffer[3];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// IcmpEchoHeader
|
||||||
|
//
|
||||||
|
IcmpEchoHeader::IcmpEchoHeader() : IcmpEchoHeader(0, 0) {}
|
||||||
|
IcmpEchoHeader::IcmpEchoHeader(uint16_t identifier, uint16_t sequenceNumber) :
|
||||||
|
identifier(identifier), sequenceNumber(sequenceNumber) {}
|
||||||
|
|
||||||
|
size_t IcmpEchoHeader::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
buffer[i++] = identifier >> 8;
|
||||||
|
buffer[i++] = identifier;
|
||||||
|
buffer[i++] = sequenceNumber >> 8;
|
||||||
|
buffer[i++] = sequenceNumber;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
IcmpEchoHeader IcmpEchoHeader::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
IcmpEchoHeader self;
|
||||||
|
self.identifier = buffer[0] << 8 | buffer[1];
|
||||||
|
self.sequenceNumber = buffer[2] << 8 | buffer[3];
|
||||||
|
return self;
|
||||||
|
}
|
|
@ -13,35 +13,16 @@ struct IcmpPacketHeader
|
||||||
std::uint8_t code;
|
std::uint8_t code;
|
||||||
std::uint16_t checksum;
|
std::uint16_t checksum;
|
||||||
|
|
||||||
IcmpPacketHeader() {}
|
IcmpPacketHeader();
|
||||||
|
IcmpPacketHeader(std::uint8_t type, std::uint8_t code);
|
||||||
IcmpPacketHeader(std::uint8_t type, std::uint8_t code) :
|
|
||||||
type(type), code(code), checksum(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
constexpr static std::size_t SerializedLength()
|
constexpr static std::size_t SerializedLength()
|
||||||
{
|
{
|
||||||
return sizeof(type) + sizeof(code) + sizeof(checksum);
|
return sizeof(type) + sizeof(code) + sizeof(checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t Serialize(uint8_t* buffer) const
|
std::size_t Serialize(uint8_t* buffer) const;
|
||||||
{
|
static IcmpPacketHeader Deserialize(const uint8_t* buffer);
|
||||||
size_t i = 0;
|
|
||||||
buffer[i++] = type;
|
|
||||||
buffer[i++] = code;
|
|
||||||
buffer[i++] = checksum;
|
|
||||||
buffer[i++] = checksum >> 8;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static IcmpPacketHeader Deserialize(const uint8_t* buffer)
|
|
||||||
{
|
|
||||||
IcmpPacketHeader self;
|
|
||||||
self.type = buffer[0];
|
|
||||||
self.code = buffer[1];
|
|
||||||
self.checksum = buffer[2] << 8 | buffer[3];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IcmpEchoHeader
|
struct IcmpEchoHeader
|
||||||
|
@ -49,30 +30,14 @@ struct IcmpEchoHeader
|
||||||
uint16_t identifier;
|
uint16_t identifier;
|
||||||
uint16_t sequenceNumber;
|
uint16_t sequenceNumber;
|
||||||
|
|
||||||
IcmpEchoHeader() : IcmpEchoHeader(0, 0) {}
|
IcmpEchoHeader();
|
||||||
IcmpEchoHeader(uint16_t identifier, uint16_t sequenceNumber) :
|
IcmpEchoHeader(uint16_t identifier, uint16_t sequenceNumber);
|
||||||
identifier(identifier), sequenceNumber(sequenceNumber) {}
|
|
||||||
|
|
||||||
constexpr static size_t SerializedLength()
|
constexpr static size_t SerializedLength()
|
||||||
{
|
{
|
||||||
return sizeof(identifier) + sizeof(sequenceNumber);
|
return sizeof(identifier) + sizeof(sequenceNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Serialize(uint8_t* buffer)
|
size_t Serialize(uint8_t* buffer) const;
|
||||||
{
|
static IcmpEchoHeader Deserialize(const uint8_t* buffer);
|
||||||
size_t i = 0;
|
|
||||||
buffer[i++] = identifier >> 8;
|
|
||||||
buffer[i++] = identifier;
|
|
||||||
buffer[i++] = sequenceNumber >> 8;
|
|
||||||
buffer[i++] = sequenceNumber;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static IcmpEchoHeader Deserialize(const uint8_t* buffer)
|
|
||||||
{
|
|
||||||
IcmpEchoHeader self;
|
|
||||||
self.identifier = buffer[0] << 8 | buffer[1];
|
|
||||||
self.sequenceNumber = buffer[2] << 8 | buffer[3];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
82
src/net-ipv4.cpp
Normal file
82
src/net-ipv4.cpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#include "net-ipv4.h"
|
||||||
|
|
||||||
|
Ipv4Header::Ipv4Header() {}
|
||||||
|
|
||||||
|
Ipv4Header::Ipv4Header(
|
||||||
|
uint8_t protocol, uint32_t sourceIp, uint32_t destinationIp, uint16_t totalLength
|
||||||
|
) :
|
||||||
|
version(4),
|
||||||
|
ihl(5),
|
||||||
|
dscp(0),
|
||||||
|
ecn(0),
|
||||||
|
totalLength(totalLength),
|
||||||
|
identification(0),
|
||||||
|
flags(0),
|
||||||
|
fragmentOffset(0),
|
||||||
|
ttl(64),
|
||||||
|
protocol(protocol),
|
||||||
|
headerChecksum(0),
|
||||||
|
sourceIp(sourceIp),
|
||||||
|
destinationIp(destinationIp)
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t Ipv4Header::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
buffer[i++] = version << 4 | ihl;
|
||||||
|
buffer[i++] = dscp << 2 | ecn;
|
||||||
|
buffer[i++] = totalLength >> 8;
|
||||||
|
buffer[i++] = totalLength;
|
||||||
|
buffer[i++] = identification >> 8;
|
||||||
|
buffer[i++] = identification;
|
||||||
|
buffer[i++] = (flags << 13 | fragmentOffset) >> 8;
|
||||||
|
buffer[i++] = flags << 13 | fragmentOffset;
|
||||||
|
buffer[i++] = ttl;
|
||||||
|
buffer[i++] = protocol;
|
||||||
|
|
||||||
|
// Zero the checksum before calculating it
|
||||||
|
buffer[i++] = 0;
|
||||||
|
buffer[i++] = 0 >> 8;
|
||||||
|
|
||||||
|
buffer[i++] = sourceIp >> 24;
|
||||||
|
buffer[i++] = sourceIp >> 16;
|
||||||
|
buffer[i++] = sourceIp >> 8;
|
||||||
|
buffer[i++] = sourceIp;
|
||||||
|
buffer[i++] = destinationIp >> 24;
|
||||||
|
buffer[i++] = destinationIp >> 16;
|
||||||
|
buffer[i++] = destinationIp >> 8;
|
||||||
|
buffer[i++] = destinationIp;
|
||||||
|
|
||||||
|
uint16_t checksum = InternetChecksum(buffer, i);
|
||||||
|
buffer[10] = checksum;
|
||||||
|
buffer[11] = checksum >> 8;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ipv4Header Ipv4Header::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
Ipv4Header self;
|
||||||
|
self.version = buffer[0] >> 4;
|
||||||
|
self.ihl = buffer[0] & 0x0F;
|
||||||
|
|
||||||
|
self.dscp = buffer[1] >> 2;
|
||||||
|
self.ecn = buffer[1] & 0x03;
|
||||||
|
|
||||||
|
self.totalLength = buffer[2] << 8 | buffer[3];
|
||||||
|
self.identification = buffer[4] << 8 | buffer[5];
|
||||||
|
|
||||||
|
self.flags = buffer[6] >> 5;
|
||||||
|
self.fragmentOffset = (buffer[6] & 0x1F) << 8 | buffer[7];
|
||||||
|
|
||||||
|
self.ttl = buffer[8];
|
||||||
|
self.protocol = buffer[9];
|
||||||
|
self.headerChecksum = buffer[10] << 8 | buffer[11];
|
||||||
|
|
||||||
|
self.sourceIp = buffer[12] << 24 | buffer[13] << 16 | buffer[14] << 8 | buffer[15];
|
||||||
|
self.destinationIp =
|
||||||
|
buffer[16] << 24 | buffer[17] << 16 | buffer[18] << 8 | buffer[19];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
|
@ -24,26 +24,13 @@ struct Ipv4Header
|
||||||
uint32_t sourceIp;
|
uint32_t sourceIp;
|
||||||
uint32_t destinationIp;
|
uint32_t destinationIp;
|
||||||
|
|
||||||
Ipv4Header() {}
|
Ipv4Header();
|
||||||
|
|
||||||
Ipv4Header(
|
Ipv4Header(
|
||||||
uint8_t protocol, uint32_t sourceIp, uint32_t destinationIp, uint16_t totalLength
|
uint8_t protocol,
|
||||||
) :
|
uint32_t sourceIp,
|
||||||
version(4),
|
uint32_t destinationIp,
|
||||||
ihl(5),
|
uint16_t totalLength
|
||||||
dscp(0),
|
);
|
||||||
ecn(0),
|
|
||||||
totalLength(totalLength),
|
|
||||||
identification(0),
|
|
||||||
flags(0),
|
|
||||||
fragmentOffset(0),
|
|
||||||
ttl(64),
|
|
||||||
protocol(protocol),
|
|
||||||
headerChecksum(0),
|
|
||||||
sourceIp(sourceIp),
|
|
||||||
destinationIp(destinationIp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr size_t SerializedLength()
|
static constexpr size_t SerializedLength()
|
||||||
{
|
{
|
||||||
|
@ -51,63 +38,6 @@ struct Ipv4Header
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Serialize(uint8_t* buffer) const
|
size_t Serialize(uint8_t* buffer) const;
|
||||||
{
|
static Ipv4Header Deserialize(const uint8_t* buffer);
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
buffer[i++] = version << 4 | ihl;
|
|
||||||
buffer[i++] = dscp << 2 | ecn;
|
|
||||||
buffer[i++] = totalLength >> 8;
|
|
||||||
buffer[i++] = totalLength;
|
|
||||||
buffer[i++] = identification >> 8;
|
|
||||||
buffer[i++] = identification;
|
|
||||||
buffer[i++] = (flags << 13 | fragmentOffset) >> 8;
|
|
||||||
buffer[i++] = flags << 13 | fragmentOffset;
|
|
||||||
buffer[i++] = ttl;
|
|
||||||
buffer[i++] = protocol;
|
|
||||||
|
|
||||||
// Zero the checksum before calculating it
|
|
||||||
buffer[i++] = 0;
|
|
||||||
buffer[i++] = 0 >> 8;
|
|
||||||
|
|
||||||
buffer[i++] = sourceIp >> 24;
|
|
||||||
buffer[i++] = sourceIp >> 16;
|
|
||||||
buffer[i++] = sourceIp >> 8;
|
|
||||||
buffer[i++] = sourceIp;
|
|
||||||
buffer[i++] = destinationIp >> 24;
|
|
||||||
buffer[i++] = destinationIp >> 16;
|
|
||||||
buffer[i++] = destinationIp >> 8;
|
|
||||||
buffer[i++] = destinationIp;
|
|
||||||
|
|
||||||
uint16_t checksum = InternetChecksum(buffer, i);
|
|
||||||
buffer[10] = checksum;
|
|
||||||
buffer[11] = checksum >> 8;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Ipv4Header Deserialize(const uint8_t* buffer)
|
|
||||||
{
|
|
||||||
Ipv4Header self;
|
|
||||||
self.version = buffer[0] >> 4;
|
|
||||||
self.ihl = buffer[0] & 0x0F;
|
|
||||||
|
|
||||||
self.dscp = buffer[1] >> 2;
|
|
||||||
self.ecn = buffer[1] & 0x03;
|
|
||||||
|
|
||||||
self.totalLength = buffer[2] << 8 | buffer[3];
|
|
||||||
self.identification = buffer[4] << 8 | buffer[5];
|
|
||||||
|
|
||||||
self.flags = buffer[6] >> 5;
|
|
||||||
self.fragmentOffset = (buffer[6] & 0x1F) << 8 | buffer[7];
|
|
||||||
|
|
||||||
self.ttl = buffer[8];
|
|
||||||
self.protocol = buffer[9];
|
|
||||||
self.headerChecksum = buffer[10] << 8 | buffer[11];
|
|
||||||
|
|
||||||
self.sourceIp = buffer[12] << 24 | buffer[13] << 16 | buffer[14] << 8 | buffer[15];
|
|
||||||
self.destinationIp = buffer[16] << 24 | buffer[17] << 16 | buffer[18] << 8 | buffer[19];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
110
src/net-tftp.cpp
110
src/net-tftp.cpp
|
@ -166,3 +166,113 @@ void HandleTftpDatagram(
|
||||||
Reboot_Pi();
|
Reboot_Pi();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TftpWriteReadRequestPacket
|
||||||
|
//
|
||||||
|
TftpWriteReadRequestPacket::TftpWriteReadRequestPacket(uint16_t opcode) :
|
||||||
|
TftpPacket(opcode)
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t TftpWriteReadRequestPacket::SerializedLength() const
|
||||||
|
{
|
||||||
|
return TftpPacket::SerializedLength() + filename.size() + 1 + mode.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t TftpWriteReadRequestPacket::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
buffer[i++] = opcode >> 8;
|
||||||
|
buffer[i++] = opcode;
|
||||||
|
|
||||||
|
i += filename.copy(reinterpret_cast<char*>(buffer + i), filename.size());
|
||||||
|
buffer[i++] = 0;
|
||||||
|
|
||||||
|
i += mode.copy(reinterpret_cast<char*>(buffer + i), mode.size());
|
||||||
|
buffer[i++] = 0;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
TftpWriteReadRequestPacket TftpWriteReadRequestPacket::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
TftpWriteReadRequestPacket self(buffer[i] << 8 | buffer[i + 1]);
|
||||||
|
i += 2;
|
||||||
|
|
||||||
|
self.filename = reinterpret_cast<const char*>(buffer + i);
|
||||||
|
i += self.filename.size() + 1;
|
||||||
|
|
||||||
|
self.mode = reinterpret_cast<const char*>(buffer + i);
|
||||||
|
i += self.mode.size() + 1;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TftpErrorPacket
|
||||||
|
//
|
||||||
|
TftpErrorPacket::TftpErrorPacket() : TftpPacket(TFTP_OP_ERROR) {}
|
||||||
|
TftpErrorPacket::TftpErrorPacket(uint16_t errorCode, std::string message) :
|
||||||
|
TftpPacket(TFTP_OP_ERROR), errorCode(errorCode), message(message)
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t TftpErrorPacket::SerializedLength() const
|
||||||
|
{
|
||||||
|
return TftpPacket::SerializedLength() + sizeof(errorCode) + message.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t TftpErrorPacket::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
buffer[i++] = opcode >> 8;
|
||||||
|
buffer[i++] = opcode;
|
||||||
|
buffer[i++] = errorCode >> 8;
|
||||||
|
buffer[i++] = errorCode;
|
||||||
|
|
||||||
|
i += message.copy(reinterpret_cast<char*>(buffer + i), message.size());
|
||||||
|
buffer[i++] = 0;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TftpAcknowledgementPacket
|
||||||
|
//
|
||||||
|
TftpAcknowledgementPacket::TftpAcknowledgementPacket() :
|
||||||
|
TftpPacket(TFTP_OP_ACKNOWLEDGEMENT)
|
||||||
|
{}
|
||||||
|
|
||||||
|
TftpAcknowledgementPacket::TftpAcknowledgementPacket(uint16_t blockNumber) :
|
||||||
|
TftpPacket(TFTP_OP_ACKNOWLEDGEMENT), blockNumber(blockNumber)
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t TftpAcknowledgementPacket::SerializedLength() const
|
||||||
|
{
|
||||||
|
return TftpPacket::SerializedLength() + sizeof(blockNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t TftpAcknowledgementPacket::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
buffer[i++] = opcode >> 8;
|
||||||
|
buffer[i++] = opcode;
|
||||||
|
buffer[i++] = blockNumber >> 8;
|
||||||
|
buffer[i++] = blockNumber;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TftpDataPacket
|
||||||
|
//
|
||||||
|
TftpDataPacket::TftpDataPacket() : opcode(TFTP_OP_DATA) {}
|
||||||
|
|
||||||
|
TftpDataPacket TftpDataPacket::Deserialize(const uint8_t* buffer, size_t length)
|
||||||
|
{
|
||||||
|
TftpDataPacket self;
|
||||||
|
self.opcode = buffer[0] << 8 | buffer[1];
|
||||||
|
self.blockNumber = buffer[2] << 8 | buffer[3];
|
||||||
|
self.data = std::vector<uint8_t>(buffer + 4, buffer + length);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
101
src/net-tftp.h
101
src/net-tftp.h
|
@ -30,40 +30,10 @@ struct TftpWriteReadRequestPacket : public TftpPacket
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string mode;
|
std::string mode;
|
||||||
|
|
||||||
TftpWriteReadRequestPacket(uint16_t opcode) : TftpPacket(opcode) {}
|
TftpWriteReadRequestPacket(uint16_t opcode);
|
||||||
|
size_t SerializedLength() const override;
|
||||||
size_t SerializedLength() const override {
|
size_t Serialize(uint8_t* buffer) const override;
|
||||||
return TftpPacket::SerializedLength() + filename.size() + 1 + mode.size() + 1;
|
static TftpWriteReadRequestPacket Deserialize(const uint8_t* buffer);
|
||||||
}
|
|
||||||
|
|
||||||
size_t Serialize(uint8_t* buffer) const override {
|
|
||||||
size_t i = 0;
|
|
||||||
buffer[i++] = opcode >> 8;
|
|
||||||
buffer[i++] = opcode;
|
|
||||||
|
|
||||||
i += filename.copy(reinterpret_cast<char*>(buffer + i), filename.size());
|
|
||||||
buffer[i++] = 0;
|
|
||||||
|
|
||||||
i += mode.copy(reinterpret_cast<char*>(buffer + i), mode.size());
|
|
||||||
buffer[i++] = 0;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static TftpWriteReadRequestPacket Deserialize(const uint8_t* buffer) {
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
TftpWriteReadRequestPacket self(buffer[i] << 8 | buffer[i + 1]);
|
|
||||||
i += 2;
|
|
||||||
|
|
||||||
self.filename = reinterpret_cast<const char*>(buffer + i);
|
|
||||||
i += self.filename.size() + 1;
|
|
||||||
|
|
||||||
self.mode = reinterpret_cast<const char*>(buffer + i);
|
|
||||||
i += self.mode.size() + 1;
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TftpErrorPacket : public TftpPacket
|
struct TftpErrorPacket : public TftpPacket
|
||||||
|
@ -71,55 +41,20 @@ struct TftpErrorPacket : public TftpPacket
|
||||||
uint16_t errorCode;
|
uint16_t errorCode;
|
||||||
std::string message;
|
std::string message;
|
||||||
|
|
||||||
TftpErrorPacket() : TftpPacket(TFTP_OP_ERROR) {}
|
TftpErrorPacket();
|
||||||
TftpErrorPacket(uint16_t errorCode, std::string message) :
|
TftpErrorPacket(uint16_t errorCode, std::string message);
|
||||||
TftpPacket(TFTP_OP_ERROR), errorCode(errorCode), message(message)
|
size_t SerializedLength() const override;
|
||||||
{}
|
size_t Serialize(uint8_t* buffer) const override;
|
||||||
|
|
||||||
size_t SerializedLength() const override
|
|
||||||
{
|
|
||||||
return TftpPacket::SerializedLength() + sizeof(errorCode) + message.size() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Serialize(uint8_t* buffer) const
|
|
||||||
{
|
|
||||||
size_t i = 0;
|
|
||||||
buffer[i++] = opcode >> 8;
|
|
||||||
buffer[i++] = opcode;
|
|
||||||
buffer[i++] = errorCode >> 8;
|
|
||||||
buffer[i++] = errorCode;
|
|
||||||
|
|
||||||
i += message.copy(reinterpret_cast<char*>(buffer + i), message.size());
|
|
||||||
buffer[i++] = 0;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TftpAcknowledgementPacket : public TftpPacket
|
struct TftpAcknowledgementPacket : public TftpPacket
|
||||||
{
|
{
|
||||||
uint16_t blockNumber;
|
uint16_t blockNumber;
|
||||||
|
|
||||||
TftpAcknowledgementPacket() : TftpPacket(TFTP_OP_ACKNOWLEDGEMENT) {}
|
TftpAcknowledgementPacket();
|
||||||
|
TftpAcknowledgementPacket(uint16_t blockNumber);
|
||||||
TftpAcknowledgementPacket(uint16_t blockNumber) :
|
size_t SerializedLength() const override;
|
||||||
TftpPacket(TFTP_OP_ACKNOWLEDGEMENT), blockNumber(blockNumber)
|
size_t Serialize(uint8_t* buffer) const override;
|
||||||
{}
|
|
||||||
|
|
||||||
size_t SerializedLength() const override
|
|
||||||
{
|
|
||||||
return TftpPacket::SerializedLength() + sizeof(blockNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Serialize(uint8_t* buffer) const override
|
|
||||||
{
|
|
||||||
size_t i = 0;
|
|
||||||
buffer[i++] = opcode >> 8;
|
|
||||||
buffer[i++] = opcode;
|
|
||||||
buffer[i++] = blockNumber >> 8;
|
|
||||||
buffer[i++] = blockNumber;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TftpDataPacket
|
struct TftpDataPacket
|
||||||
|
@ -128,14 +63,6 @@ struct TftpDataPacket
|
||||||
uint16_t blockNumber;
|
uint16_t blockNumber;
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
|
|
||||||
TftpDataPacket() : opcode(TFTP_OP_DATA) {}
|
TftpDataPacket();
|
||||||
|
static TftpDataPacket Deserialize(const uint8_t* buffer, size_t length);
|
||||||
static TftpDataPacket Deserialize(const uint8_t* buffer, size_t length)
|
|
||||||
{
|
|
||||||
TftpDataPacket self;
|
|
||||||
self.opcode = buffer[0] << 8 | buffer[1];
|
|
||||||
self.blockNumber = buffer[2] << 8 | buffer[3];
|
|
||||||
self.data = std::vector<uint8_t>(buffer + 4, buffer + length);
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
39
src/net-udp.cpp
Normal file
39
src/net-udp.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "net-udp.h"
|
||||||
|
|
||||||
|
UdpDatagramHeader::UdpDatagramHeader()
|
||||||
|
{}
|
||||||
|
|
||||||
|
UdpDatagramHeader::UdpDatagramHeader(
|
||||||
|
uint16_t sourcePort,
|
||||||
|
uint16_t destinationPort,
|
||||||
|
uint16_t length
|
||||||
|
) :
|
||||||
|
sourcePort(sourcePort),
|
||||||
|
destinationPort(destinationPort),
|
||||||
|
length(length),
|
||||||
|
checksum(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t UdpDatagramHeader::Serialize(uint8_t* buffer)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
buffer[i++] = sourcePort >> 8;
|
||||||
|
buffer[i++] = sourcePort;
|
||||||
|
buffer[i++] = destinationPort >> 8;
|
||||||
|
buffer[i++] = destinationPort;
|
||||||
|
buffer[i++] = length >> 8;
|
||||||
|
buffer[i++] = length;
|
||||||
|
buffer[i++] = checksum >> 8;
|
||||||
|
buffer[i++] = checksum;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
UdpDatagramHeader UdpDatagramHeader::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
UdpDatagramHeader self;
|
||||||
|
self.sourcePort = buffer[0] << 8 | buffer[1];
|
||||||
|
self.destinationPort = buffer[2] << 8 | buffer[3];
|
||||||
|
self.length = buffer[4] << 8 | buffer[5];
|
||||||
|
self.checksum = buffer[6] << 8 | buffer[7];
|
||||||
|
return self;
|
||||||
|
}
|
|
@ -10,14 +10,8 @@ struct UdpDatagramHeader
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
uint16_t checksum;
|
uint16_t checksum;
|
||||||
|
|
||||||
UdpDatagramHeader() {}
|
UdpDatagramHeader();
|
||||||
|
UdpDatagramHeader(uint16_t sourcePort, uint16_t destinationPort, uint16_t length);
|
||||||
UdpDatagramHeader(uint16_t sourcePort, uint16_t destinationPort, uint16_t length) :
|
|
||||||
sourcePort(sourcePort),
|
|
||||||
destinationPort(destinationPort),
|
|
||||||
length(length),
|
|
||||||
checksum(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
static constexpr size_t SerializedLength()
|
static constexpr size_t SerializedLength()
|
||||||
{
|
{
|
||||||
|
@ -28,27 +22,6 @@ struct UdpDatagramHeader
|
||||||
sizeof(checksum);
|
sizeof(checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Serialize(uint8_t* buffer)
|
size_t Serialize(uint8_t* buffer);
|
||||||
{
|
static UdpDatagramHeader Deserialize(const uint8_t* buffer);
|
||||||
size_t i = 0;
|
|
||||||
buffer[i++] = sourcePort >> 8;
|
|
||||||
buffer[i++] = sourcePort;
|
|
||||||
buffer[i++] = destinationPort >> 8;
|
|
||||||
buffer[i++] = destinationPort;
|
|
||||||
buffer[i++] = length >> 8;
|
|
||||||
buffer[i++] = length;
|
|
||||||
buffer[i++] = checksum >> 8;
|
|
||||||
buffer[i++] = checksum;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static UdpDatagramHeader Deserialize(const uint8_t* buffer)
|
|
||||||
{
|
|
||||||
UdpDatagramHeader self;
|
|
||||||
self.sourcePort = buffer[0] << 8 | buffer[1];
|
|
||||||
self.destinationPort = buffer[2] << 8 | buffer[3];
|
|
||||||
self.length = buffer[4] << 8 | buffer[5];
|
|
||||||
self.checksum = buffer[6] << 8 | buffer[7];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue