Put Udp in namespace and simplify symbol names

This commit is contained in:
Sijmen 2020-12-28 13:25:56 +01:00
parent 118f6b62c2
commit aec510a47c
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
13 changed files with 292 additions and 299 deletions

View file

@ -376,7 +376,7 @@ void updateNetwork()
return; return;
} }
auto ethernetHeader = Net::Ethernet::EthernetFrameHeader::Deserialize(ipBuffer); auto ethernetHeader = Net::Ethernet::Header::Deserialize(ipBuffer);
const auto offset = ethernetHeader.SerializedLength(); const auto offset = ethernetHeader.SerializedLength();
static bool announcementSent = false; static bool announcementSent = false;

View file

@ -8,18 +8,18 @@
namespace Net::Arp namespace Net::Arp
{ {
Ipv4ArpPacket::Ipv4ArpPacket() Packet::Packet()
{} {}
Ipv4ArpPacket::Ipv4ArpPacket(uint16_t operation) : Packet::Packet(uint16_t operation) :
hardwareType(1), // Ethernet hardwareType(1), // Ethernet
protocolType(Net::Ethernet::ETHERTYPE_IPV4), protocolType(Ethernet::ETHERTYPE_IPV4),
hardwareAddressLength(6), hardwareAddressLength(6),
protocolAddressLength(4), protocolAddressLength(4),
operation(operation) operation(operation)
{} {}
size_t Ipv4ArpPacket::Serialize(uint8_t* buffer) size_t Packet::Serialize(uint8_t* buffer)
{ {
buffer[0] = hardwareType >> 8; buffer[0] = hardwareType >> 8;
buffer[1] = hardwareType; buffer[1] = hardwareType;
@ -48,9 +48,9 @@ namespace Net::Arp
} }
// Static // Static
Ipv4ArpPacket Ipv4ArpPacket::Deserialize(const uint8_t* buffer) Packet Packet::Deserialize(const uint8_t* buffer)
{ {
Ipv4ArpPacket self; Packet self;
self.hardwareType = buffer[0] << 8 | buffer[1]; self.hardwareType = buffer[0] << 8 | buffer[1];
self.protocolType = buffer[2] << 8 | buffer[3]; self.protocolType = buffer[2] << 8 | buffer[3];
@ -69,20 +69,20 @@ namespace Net::Arp
} }
void SendPacket( void SendPacket(
ArpOperation operation, Operation operation,
MacAddress targetMac, Utils::MacAddress targetMac,
MacAddress senderMac, Utils::MacAddress senderMac,
uint32_t targetIp, uint32_t targetIp,
uint32_t senderIp) uint32_t senderIp)
{ {
Ipv4ArpPacket arpPacket(operation); Packet arpPacket(operation);
arpPacket.targetMac = targetMac; arpPacket.targetMac = targetMac;
arpPacket.senderMac = senderMac; arpPacket.senderMac = senderMac;
arpPacket.targetIp = targetIp; arpPacket.targetIp = targetIp;
arpPacket.senderIp = senderIp; arpPacket.senderIp = senderIp;
Net::Ethernet::EthernetFrameHeader ethernetHeader( Ethernet::Header ethernetHeader(
senderMac, targetMac, Net::Ethernet::ETHERTYPE_ARP); senderMac, targetMac, Ethernet::ETHERTYPE_ARP);
uint8_t buffer[USPI_FRAME_BUFFER_SIZE]; uint8_t buffer[USPI_FRAME_BUFFER_SIZE];
size_t size = 0; size_t size = 0;
@ -92,8 +92,8 @@ namespace Net::Arp
} }
void SendRequest( void SendRequest(
MacAddress targetMac, Utils::MacAddress targetMac,
MacAddress senderMac, Utils::MacAddress senderMac,
uint32_t targetIp, uint32_t targetIp,
uint32_t senderIp uint32_t senderIp
) { ) {
@ -101,46 +101,46 @@ namespace Net::Arp
} }
void SendReply( void SendReply(
MacAddress targetMac, MacAddress senderMac, uint32_t targetIp, uint32_t senderIp) Utils::MacAddress targetMac, Utils::MacAddress senderMac, uint32_t targetIp, uint32_t senderIp)
{ {
SendPacket(ARP_OPERATION_REPLY, targetMac, senderMac, targetIp, senderIp); SendPacket(ARP_OPERATION_REPLY, targetMac, senderMac, targetIp, senderIp);
} }
void SendAnnouncement(MacAddress mac, uint32_t ip) void SendAnnouncement(Utils::MacAddress mac, uint32_t ip)
{ {
SendReply(Net::Utils::MacBroadcast, mac, ip, ip); SendReply(Utils::MacBroadcast, mac, ip, ip);
} }
void HandlePacket( void HandlePacket(
const Net::Ethernet::EthernetFrameHeader ethernetHeader, uint8_t* buffer const Ethernet::Header ethernetHeader, uint8_t* buffer
) { ) {
const auto macAddress = Net::Utils::GetMacAddress(); const auto macAddress = Utils::GetMacAddress();
const auto arpPacket = Ipv4ArpPacket::Deserialize(buffer); const auto arpPacket = Packet::Deserialize(buffer);
if ( if (
arpPacket.hardwareType == 1 && arpPacket.hardwareType == 1 &&
arpPacket.protocolType == Net::Ethernet::ETHERTYPE_IPV4 && arpPacket.protocolType == Ethernet::ETHERTYPE_IPV4 &&
arpPacket.operation == ARP_OPERATION_REQUEST && arpPacket.operation == ARP_OPERATION_REQUEST &&
arpPacket.targetIp == Net::Utils::Ipv4Address) arpPacket.targetIp == Utils::Ipv4Address)
{ {
SendReply( SendReply(
arpPacket.senderMac, arpPacket.senderMac,
macAddress, macAddress,
arpPacket.senderIp, arpPacket.senderIp,
Net::Utils::Ipv4Address Utils::Ipv4Address
); );
} }
else if ( else if (
arpPacket.hardwareType == 1 && arpPacket.hardwareType == 1 &&
arpPacket.protocolType == Net::Ethernet::ETHERTYPE_IPV4 && arpPacket.protocolType == Ethernet::ETHERTYPE_IPV4 &&
arpPacket.operation == ARP_OPERATION_REPLY && arpPacket.operation == ARP_OPERATION_REPLY &&
arpPacket.targetIp == Net::Utils::Ipv4Address && arpPacket.targetIp == Utils::Ipv4Address &&
arpPacket.targetMac == macAddress) arpPacket.targetMac == macAddress)
{ {
ArpTable.insert(std::make_pair(arpPacket.senderIp, arpPacket.senderMac)); ArpTable.insert(std::make_pair(arpPacket.senderIp, arpPacket.senderMac));
} }
} }
std::unordered_map<uint32_t, MacAddress> ArpTable; std::unordered_map<uint32_t, Utils::MacAddress> ArpTable;
}; // namespace Net::Arp }; // namespace Net::Arp

View file

@ -5,14 +5,12 @@
namespace Net::Arp namespace Net::Arp
{ {
using Net::Utils::MacAddress; enum Operation {
enum ArpOperation {
ARP_OPERATION_REQUEST = 1, ARP_OPERATION_REQUEST = 1,
ARP_OPERATION_REPLY = 2, ARP_OPERATION_REPLY = 2,
}; };
struct Ipv4ArpPacket struct Packet
{ {
uint16_t hardwareType; uint16_t hardwareType;
uint16_t protocolType; uint16_t protocolType;
@ -20,13 +18,13 @@ namespace Net::Arp
uint8_t protocolAddressLength; uint8_t protocolAddressLength;
uint16_t operation; uint16_t operation;
MacAddress senderMac; Utils::MacAddress senderMac;
uint32_t senderIp; uint32_t senderIp;
MacAddress targetMac; Utils::MacAddress targetMac;
uint32_t targetIp; uint32_t targetIp;
Ipv4ArpPacket(); Packet();
Ipv4ArpPacket(uint16_t operation); Packet(uint16_t operation);
constexpr size_t SerializedLength() const constexpr size_t SerializedLength() const
{ {
@ -44,34 +42,34 @@ namespace Net::Arp
size_t Serialize(uint8_t* buffer); size_t Serialize(uint8_t* buffer);
static Ipv4ArpPacket Deserialize(const uint8_t* buffer); static Packet Deserialize(const uint8_t* buffer);
}; };
void HandlePacket(Net::Ethernet::EthernetFrameHeader header, uint8_t* buffer); void HandlePacket(Ethernet::Header header, uint8_t* buffer);
void SendPacket( void SendPacket(
ArpOperation operation, Operation operation,
MacAddress targetMac, Utils::MacAddress targetMac,
MacAddress senderMac, Utils::MacAddress senderMac,
uint32_t senderIp, uint32_t senderIp,
uint32_t targetIp uint32_t targetIp
); );
void SendRequest( void SendRequest(
MacAddress targetMac, Utils::MacAddress targetMac,
MacAddress senderMac, Utils::MacAddress senderMac,
uint32_t senderIp, uint32_t senderIp,
uint32_t targetIp uint32_t targetIp
); );
void SendReply( void SendReply(
MacAddress targetMac, Utils::MacAddress targetMac,
MacAddress senderMac, Utils::MacAddress senderMac,
uint32_t senderIp, uint32_t senderIp,
uint32_t targetIp uint32_t targetIp
); );
void SendAnnouncement(MacAddress mac, uint32_t ip); void SendAnnouncement(Utils::MacAddress mac, uint32_t ip);
extern std::unordered_map<uint32_t, MacAddress> ArpTable; extern std::unordered_map<uint32_t, Utils::MacAddress> ArpTable;
}; // namespace Net::Arp }; // namespace Net::Arp

View file

@ -10,10 +10,10 @@
namespace Net::Dhcp namespace Net::Dhcp
{ {
DhcpHeader::DhcpHeader() Header::Header()
{} {}
DhcpHeader::DhcpHeader(Opcode opcode, uint32_t transactionId) : Header::Header(Opcode opcode, uint32_t transactionId) :
opcode(opcode), opcode(opcode),
hardwareAddressType(1), // Ethernet hardwareAddressType(1), // Ethernet
hops(0), hops(0),
@ -29,14 +29,14 @@ namespace Net::Dhcp
bootFile{0}, bootFile{0},
magicValue{99, 130, 83, 99} magicValue{99, 130, 83, 99}
{ {
const auto mac = Net::Utils::GetMacAddress(); const auto mac = Utils::GetMacAddress();
hardwareAddressLength = mac.size(); hardwareAddressLength = mac.size();
std::memcpy(clientHardwareAddress.data(), mac.data(), mac.size()); std::memcpy(clientHardwareAddress.data(), mac.data(), mac.size());
} }
size_t DhcpHeader::Serialize(uint8_t* buffer, const size_t size) const size_t Header::Serialize(uint8_t* buffer, const size_t size) const
{ {
if (size < DhcpHeader::SerializedLength()) { if (size < Header::SerializedLength()) {
return 0; return 0;
} }
@ -81,8 +81,8 @@ namespace Net::Dhcp
return i; return i;
} }
size_t DhcpHeader::Deserialize( size_t Header::Deserialize(
DhcpHeader& out, const uint8_t* buffer, const size_t size Header& out, const uint8_t* buffer, const size_t size
) { ) {
if (size < SerializedLength()) { if (size < SerializedLength()) {
return 0; return 0;
@ -121,25 +121,28 @@ namespace Net::Dhcp
static uint32_t transactionId; static uint32_t transactionId;
static std::vector<uint32_t> offeredIpAddresses; static std::vector<uint32_t> offeredIpAddresses;
static std::vector<uint32_t> serverIpAddresses; static std::vector<uint32_t> serverIpAddresses;
static std::vector<MacAddress> serverMacAddresses; static std::vector<Utils::MacAddress> serverMacAddresses;
static bool serverSelected; static bool serverSelected;
void sendRequest(uint32_t clientIpAddress, MacAddress serverMacAddress, uint32_t serverIpAddress) void sendRequest(
{ uint32_t clientIpAddress,
const DhcpHeader dhcpHeader(Opcode::BootRequest, transactionId); Utils::MacAddress serverMacAddress,
uint32_t serverIpAddress
) {
const Header dhcpHeader(Opcode::BootRequest, transactionId);
size_t udpLength = size_t udpLength =
dhcpHeader.SerializedLength() + UdpDatagramHeader::SerializedLength(); dhcpHeader.SerializedLength() + Udp::Header::SerializedLength();
const UdpDatagramHeader udpHeader( const Udp::Header udpHeader(
UDP_PORT_DHCP_CLIENT, UDP_PORT_DHCP_SERVER, udpLength); Udp::Port::DhcpClient, Udp::Port::DhcpServer, udpLength);
size_t ipv4Length = udpLength + Ipv4Header::SerializedLength(); size_t ipv4Length = udpLength + Ipv4Header::SerializedLength();
const Ipv4Header ipv4Header( const Ipv4Header ipv4Header(
IP_PROTO_UDP, clientIpAddress, serverIpAddress, ipv4Length); IP_PROTO_UDP, clientIpAddress, serverIpAddress, ipv4Length);
const Net::Ethernet::EthernetFrameHeader ethernetHeader( const Ethernet::Header ethernetHeader(
serverMacAddress, serverMacAddress,
Net::Utils::GetMacAddress(), Utils::GetMacAddress(),
Net::Ethernet::ETHERTYPE_IPV4 Ethernet::ETHERTYPE_IPV4
); );
uint8_t buffer[USPI_FRAME_BUFFER_SIZE]; uint8_t buffer[USPI_FRAME_BUFFER_SIZE];
@ -184,17 +187,17 @@ namespace Net::Dhcp
{ {
transactionId = std::rand(); transactionId = std::rand();
offeredIpAddresses.clear(); offeredIpAddresses.clear();
const DhcpHeader dhcpHeader(Opcode::BootRequest, transactionId); const Header dhcpHeader(Opcode::BootRequest, transactionId);
size_t udpLength = size_t udpLength =
dhcpHeader.SerializedLength() + UdpDatagramHeader::SerializedLength(); dhcpHeader.SerializedLength() + Udp::Header::SerializedLength();
const UdpDatagramHeader udpHeader( const Udp::Header udpHeader(
UDP_PORT_DHCP_CLIENT, UDP_PORT_DHCP_SERVER, udpLength); Udp::Port::DhcpClient, Udp::Port::DhcpServer, udpLength);
size_t ipv4Length = udpLength + Ipv4Header::SerializedLength(); size_t ipv4Length = udpLength + Ipv4Header::SerializedLength();
const Ipv4Header ipv4Header(IP_PROTO_UDP, 0, 0xFFFFFFFF, ipv4Length); const Ipv4Header ipv4Header(IP_PROTO_UDP, 0, 0xFFFFFFFF, ipv4Length);
const Net::Ethernet::EthernetFrameHeader ethernetHeader( const Ethernet::Header ethernetHeader(
Net::Utils::GetMacAddress(), Net::Ethernet::ETHERTYPE_IPV4); Utils::GetMacAddress(), Ethernet::ETHERTYPE_IPV4);
uint8_t buffer[USPI_FRAME_BUFFER_SIZE]; uint8_t buffer[USPI_FRAME_BUFFER_SIZE];
size_t size = 0; size_t size = 0;
@ -221,8 +224,8 @@ namespace Net::Dhcp
} }
static void handleOfferPacket( static void handleOfferPacket(
const Net::Ethernet::EthernetFrameHeader ethernetHeader, const Ethernet::Header ethernetHeader,
const DhcpHeader dhcpHeader const Header dhcpHeader
) { ) {
offeredIpAddresses.push_back(dhcpHeader.yourIpAddress); offeredIpAddresses.push_back(dhcpHeader.yourIpAddress);
serverIpAddresses.push_back(dhcpHeader.serverIpAddress); serverIpAddresses.push_back(dhcpHeader.serverIpAddress);
@ -230,10 +233,10 @@ namespace Net::Dhcp
} }
static void handleAckPacket( static void handleAckPacket(
const Net::Ethernet::EthernetFrameHeader ethernetHeader, const Ethernet::Header ethernetHeader,
const DhcpHeader dhcpHeader const Header dhcpHeader
) { ) {
Net::Utils::Ipv4Address = dhcpHeader.yourIpAddress; Utils::Ipv4Address = dhcpHeader.yourIpAddress;
// TODO Schedule handler for end of lease. // TODO Schedule handler for end of lease.
@ -245,12 +248,12 @@ namespace Net::Dhcp
} }
void HandlePacket( void HandlePacket(
const Net::Ethernet::EthernetFrameHeader& ethernetHeader, const Ethernet::Header& ethernetHeader,
const uint8_t* buffer, const uint8_t* buffer,
size_t size size_t size
) { ) {
auto dhcpHeader = DhcpHeader(); auto dhcpHeader = Header();
const auto dhcpSize = DhcpHeader::Deserialize(dhcpHeader, buffer, size); const auto dhcpSize = Header::Deserialize(dhcpHeader, buffer, size);
if (dhcpSize == 0) { if (dhcpSize == 0) {
// TODO log // TODO log
return; return;

View file

@ -10,7 +10,7 @@ namespace Net::Dhcp
BootReply = 2, BootReply = 2,
}; };
struct DhcpHeader struct Header
{ {
/// Message op code / message type. 1 = BOOTREQUEST, 2 = BOOTREPLY /// Message op code / message type. 1 = BOOTREQUEST, 2 = BOOTREPLY
Opcode opcode; Opcode opcode;
@ -60,8 +60,8 @@ namespace Net::Dhcp
/// Always 99, 130, 83, 99 /// Always 99, 130, 83, 99
std::array<uint8_t, 4> magicValue; std::array<uint8_t, 4> magicValue;
DhcpHeader(); Header();
DhcpHeader(Opcode opcode, uint32_t transactionId); Header(Opcode opcode, uint32_t transactionId);
constexpr static size_t SerializedLength() constexpr static size_t SerializedLength()
{ {
@ -85,12 +85,12 @@ namespace Net::Dhcp
size_t Serialize(uint8_t* buffer, const size_t size) const; size_t Serialize(uint8_t* buffer, const size_t size) const;
static size_t Deserialize( static size_t Deserialize(
DhcpHeader& out, const uint8_t* buffer, const size_t size); Header& out, const uint8_t* buffer, const size_t size);
}; };
void SendDiscover(); void SendDiscover();
void HandlePacket( void HandlePacket(
const Net::Ethernet::EthernetFrameHeader& ethernetHeader, const Ethernet::Header& ethernetHeader,
const uint8_t* buffer, const uint8_t* buffer,
size_t size size_t size
); );

View file

@ -2,24 +2,24 @@
#include "net-ethernet.h" #include "net-ethernet.h"
namespace Net::Ethernet { namespace Net::Ethernet {
EthernetFrameHeader::EthernetFrameHeader() Header::Header()
{} {}
EthernetFrameHeader::EthernetFrameHeader(std::uint16_t type) : Header::Header(uint16_t type) :
macDestination(Net::Utils::MacBroadcast), macDestination(Utils::MacBroadcast),
macSource{0, 0, 0, 0, 0, 0}, macSource{0, 0, 0, 0, 0, 0},
type(type) type(type)
{} {}
EthernetFrameHeader::EthernetFrameHeader( Header::Header(
MacAddress macSource, uint16_t type MacAddress macSource, uint16_t type
) : ) :
macDestination(Net::Utils::MacBroadcast), macDestination(Utils::MacBroadcast),
macSource(macSource), macSource(macSource),
type(type) type(type)
{} {}
EthernetFrameHeader::EthernetFrameHeader( Header::Header(
MacAddress macDestination, MacAddress macSource, uint16_t type MacAddress macDestination, MacAddress macSource, uint16_t type
) : ) :
macDestination(macDestination), macDestination(macDestination),
@ -27,9 +27,9 @@ namespace Net::Ethernet {
type(type) type(type)
{} {}
std::size_t EthernetFrameHeader::Serialize(uint8_t* buffer) const size_t Header::Serialize(uint8_t* buffer) const
{ {
std::size_t i = 0; size_t i = 0;
std::memcpy(buffer + i, macDestination.data(), macDestination.size()); std::memcpy(buffer + i, macDestination.data(), macDestination.size());
i += sizeof(macDestination); i += sizeof(macDestination);
@ -43,9 +43,9 @@ namespace Net::Ethernet {
return i; return i;
} }
EthernetFrameHeader EthernetFrameHeader::Deserialize(const uint8_t* buffer) Header Header::Deserialize(const uint8_t* buffer)
{ {
EthernetFrameHeader self; Header self;
std::memcpy(self.macDestination.data(), buffer + 0, self.macDestination.size()); std::memcpy(self.macDestination.data(), buffer + 0, self.macDestination.size());
std::memcpy(self.macSource.data(), buffer + 6, self.macSource.size()); std::memcpy(self.macSource.data(), buffer + 6, self.macSource.size());
self.type = buffer[12] << 8 | buffer[13]; self.type = buffer[12] << 8 | buffer[13];

View file

@ -2,33 +2,33 @@
#include <array> #include <array>
#include "net-utils.h" #include "net-utils.h"
using Net::Utils::MacAddress;
namespace Net::Ethernet namespace Net::Ethernet
{ {
using Utils::MacAddress;
enum EtherType enum EtherType
{ {
ETHERTYPE_IPV4 = 0x0800, ETHERTYPE_IPV4 = 0x0800,
ETHERTYPE_ARP = 0x0806, ETHERTYPE_ARP = 0x0806,
}; };
struct EthernetFrameHeader struct Header
{ {
MacAddress macDestination; MacAddress macDestination;
MacAddress macSource; MacAddress macSource;
std::uint16_t type; uint16_t type;
EthernetFrameHeader(); Header();
EthernetFrameHeader(std::uint16_t type); Header(uint16_t type);
EthernetFrameHeader(MacAddress macSource, uint16_t type); Header(MacAddress macSource, uint16_t type);
EthernetFrameHeader(MacAddress macDestination, MacAddress macSource, uint16_t type); Header(MacAddress macDestination, MacAddress macSource, uint16_t type);
constexpr static std::size_t SerializedLength() constexpr static 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; size_t Serialize(uint8_t* buffer) const;
static EthernetFrameHeader Deserialize(const uint8_t* buffer); static Header Deserialize(const uint8_t* buffer);
}; };
}; // namespace Net::Ethernet }; // namespace Net::Ethernet

View file

@ -18,15 +18,15 @@ namespace Net::Tftp
static bool shouldReboot = false; static bool shouldReboot = false;
static uint32_t currentBlockNumber = -1; static uint32_t currentBlockNumber = -1;
static std::unique_ptr<TftpPacket> handleTftpWriteRequest(const uint8_t* data) static std::unique_ptr<Packet> handleTftpWriteRequest(const uint8_t* data)
{ {
auto packet = TftpWriteReadRequestPacket::Deserialize(data); auto packet = WriteReadRequestPacket::Deserialize(data);
// TODO Implement netscii, maybe // TODO Implement netscii, maybe
if (packet.mode != "octet") if (packet.mode != "octet")
{ {
return std::unique_ptr<TftpErrorPacket>( return std::unique_ptr<ErrorPacket>(
new TftpErrorPacket(0, "please use mode octet") new ErrorPacket(0, "please use mode octet")
); );
} }
@ -53,19 +53,19 @@ namespace Net::Tftp
auto filename = packet.filename.substr(separator + 1); auto filename = packet.filename.substr(separator + 1);
const auto result = f_open(&outFile, filename.c_str(), FA_CREATE_ALWAYS | FA_WRITE); const auto result = f_open(&outFile, filename.c_str(), FA_CREATE_ALWAYS | FA_WRITE);
std::unique_ptr<TftpPacket> response; std::unique_ptr<Packet> response;
if (result != FR_OK) if (result != FR_OK)
{ {
response = std::unique_ptr<TftpErrorPacket>( response = std::unique_ptr<ErrorPacket>(
new TftpErrorPacket(0, "error opening target file") new ErrorPacket(0, "error opening target file")
); );
} }
else else
{ {
shouldReboot = shouldReboot =
packet.filename == "kernel.img" || packet.filename == "options.txt"; packet.filename == "kernel.img" || packet.filename == "options.txt";
response = std::unique_ptr<TftpAcknowledgementPacket>( response = std::unique_ptr<AcknowledgementPacket>(
new TftpAcknowledgementPacket(currentBlockNumber) new AcknowledgementPacket(currentBlockNumber)
); );
} }
@ -74,10 +74,10 @@ namespace Net::Tftp
return response; return response;
} }
static std::unique_ptr<TftpPacket> handleTftpData(const uint8_t* buffer, size_t size) static std::unique_ptr<Packet> handleTftpData(const uint8_t* buffer, size_t size)
{ {
TftpDataPacket packet; DataPacket packet;
const auto tftpSize = TftpDataPacket::Deserialize(packet, buffer, size); const auto tftpSize = DataPacket::Deserialize(packet, buffer, size);
if (size == 0) if (size == 0)
{ {
// TODO log // TODO log
@ -87,8 +87,8 @@ namespace Net::Tftp
if (packet.blockNumber != currentBlockNumber + 1) if (packet.blockNumber != currentBlockNumber + 1)
{ {
f_close(&outFile); f_close(&outFile);
return std::unique_ptr<TftpErrorPacket>( return std::unique_ptr<ErrorPacket>(
new TftpErrorPacket(0, "invalid block number") new ErrorPacket(0, "invalid block number")
); );
} }
currentBlockNumber = packet.blockNumber; currentBlockNumber = packet.blockNumber;
@ -100,7 +100,7 @@ namespace Net::Tftp
if (result != FR_OK || bytesWritten != packet.data.size()) if (result != FR_OK || bytesWritten != packet.data.size())
{ {
f_close(&outFile); f_close(&outFile);
return std::unique_ptr<TftpErrorPacket>(new TftpErrorPacket(0, "io error")); return std::unique_ptr<ErrorPacket>(new ErrorPacket(0, "io error"));
} }
if (packet.data.size() < TFTP_BLOCK_SIZE) if (packet.data.size() < TFTP_BLOCK_SIZE)
@ -109,19 +109,19 @@ namespace Net::Tftp
f_close(&outFile); f_close(&outFile);
} }
return std::unique_ptr<TftpAcknowledgementPacket>( return std::unique_ptr<AcknowledgementPacket>(
new TftpAcknowledgementPacket(currentBlockNumber) new AcknowledgementPacket(currentBlockNumber)
); );
} }
void HandlePacket( void HandlePacket(
const Net::Ethernet::EthernetFrameHeader ethernetReqHeader, const Ethernet::Header ethernetReqHeader,
const Ipv4Header ipv4ReqHeader, const Ipv4Header ipv4ReqHeader,
const UdpDatagramHeader udpReqHeader, const Udp::Header udpReqHeader,
const uint8_t* data const uint8_t* data
) { ) {
const auto opcode = static_cast<Opcode>(data[0] << 8 | data[1]); const auto opcode = static_cast<Opcode>(data[0] << 8 | data[1]);
std::unique_ptr<TftpPacket> response; std::unique_ptr<Packet> response;
bool last = false; bool last = false;
if (opcode == Opcode::WriteRequest) if (opcode == Opcode::WriteRequest)
@ -130,33 +130,33 @@ namespace Net::Tftp
} }
else if (opcode == Opcode::Data) else if (opcode == Opcode::Data)
{ {
const auto length = udpReqHeader.length - UdpDatagramHeader::SerializedLength(); const auto length = udpReqHeader.length - Udp::Header::SerializedLength();
response = handleTftpData(data, length); response = handleTftpData(data, length);
} }
else else
{ {
response = std::unique_ptr<TftpErrorPacket>( response = std::unique_ptr<ErrorPacket>(
new TftpErrorPacket(4, "not implemented yet") new ErrorPacket(4, "not implemented yet")
); );
} }
if (response != nullptr) if (response != nullptr)
{ {
UdpDatagramHeader udpRespHeader( Udp::Header udpRespHeader(
udpReqHeader.destinationPort, udpReqHeader.destinationPort,
udpReqHeader.sourcePort, udpReqHeader.sourcePort,
response->SerializedLength() + UdpDatagramHeader::SerializedLength() response->SerializedLength() + Udp::Header::SerializedLength()
); );
Ipv4Header ipv4RespHeader( Ipv4Header ipv4RespHeader(
IP_PROTO_UDP, IP_PROTO_UDP,
Net::Utils::Ipv4Address, Utils::Ipv4Address,
ipv4ReqHeader.sourceIp, ipv4ReqHeader.sourceIp,
udpRespHeader.length + Ipv4Header::SerializedLength() udpRespHeader.length + Ipv4Header::SerializedLength()
); );
Net::Ethernet::EthernetFrameHeader ethernetRespHeader( Ethernet::Header ethernetRespHeader(
Net::Arp::ArpTable[ipv4RespHeader.destinationIp], Arp::ArpTable[ipv4RespHeader.destinationIp],
Net::Utils::GetMacAddress(), Utils::GetMacAddress(),
Net::Ethernet::ETHERTYPE_IPV4 Ethernet::ETHERTYPE_IPV4
); );
size_t i = 0; size_t i = 0;
@ -177,18 +177,18 @@ namespace Net::Tftp
} }
// //
// TftpWriteReadRequestPacket // WriteReadRequestPacket
// //
TftpWriteReadRequestPacket::TftpWriteReadRequestPacket(const Opcode opcode) : WriteReadRequestPacket::WriteReadRequestPacket(const Opcode opcode) :
TftpPacket(opcode) Packet(opcode)
{} {}
size_t TftpWriteReadRequestPacket::SerializedLength() const size_t WriteReadRequestPacket::SerializedLength() const
{ {
return TftpPacket::SerializedLength() + filename.size() + 1 + mode.size() + 1; return Packet::SerializedLength() + filename.size() + 1 + mode.size() + 1;
} }
size_t TftpWriteReadRequestPacket::Serialize(uint8_t* buffer) const size_t WriteReadRequestPacket::Serialize(uint8_t* buffer) const
{ {
size_t i = 0; size_t i = 0;
buffer[i++] = static_cast<uint16_t>(opcode) >> 8; buffer[i++] = static_cast<uint16_t>(opcode) >> 8;
@ -203,12 +203,12 @@ namespace Net::Tftp
return i; return i;
} }
TftpWriteReadRequestPacket TftpWriteReadRequestPacket::Deserialize(const uint8_t* buffer) WriteReadRequestPacket WriteReadRequestPacket::Deserialize(const uint8_t* buffer)
{ {
size_t i = 0; size_t i = 0;
const auto opcode = static_cast<Opcode>(buffer[i] << 8 | buffer[i + 1]); const auto opcode = static_cast<Opcode>(buffer[i] << 8 | buffer[i + 1]);
TftpWriteReadRequestPacket self(opcode); WriteReadRequestPacket self(opcode);
i += 2; i += 2;
self.filename = reinterpret_cast<const char*>(buffer + i); self.filename = reinterpret_cast<const char*>(buffer + i);
@ -221,19 +221,19 @@ namespace Net::Tftp
} }
// //
// TftpErrorPacket // ErrorPacket
// //
TftpErrorPacket::TftpErrorPacket() : TftpPacket(Opcode::Error) {} ErrorPacket::ErrorPacket() : Packet(Opcode::Error) {}
TftpErrorPacket::TftpErrorPacket(uint16_t errorCode, std::string message) : ErrorPacket::ErrorPacket(uint16_t errorCode, std::string message) :
TftpPacket(Opcode::Error), errorCode(errorCode), message(message) Packet(Opcode::Error), errorCode(errorCode), message(message)
{} {}
size_t TftpErrorPacket::SerializedLength() const size_t ErrorPacket::SerializedLength() const
{ {
return TftpPacket::SerializedLength() + sizeof(errorCode) + message.size() + 1; return Packet::SerializedLength() + sizeof(errorCode) + message.size() + 1;
} }
size_t TftpErrorPacket::Serialize(uint8_t* buffer) const size_t ErrorPacket::Serialize(uint8_t* buffer) const
{ {
size_t i = 0; size_t i = 0;
buffer[i++] = static_cast<uint16_t>(opcode) >> 8; buffer[i++] = static_cast<uint16_t>(opcode) >> 8;
@ -248,22 +248,22 @@ namespace Net::Tftp
} }
// //
// TftpAcknowledgementPacket // AcknowledgementPacket
// //
TftpAcknowledgementPacket::TftpAcknowledgementPacket() : AcknowledgementPacket::AcknowledgementPacket() :
TftpPacket(Opcode::Acknowledgement) Packet(Opcode::Acknowledgement)
{} {}
TftpAcknowledgementPacket::TftpAcknowledgementPacket(uint16_t blockNumber) : AcknowledgementPacket::AcknowledgementPacket(uint16_t blockNumber) :
TftpPacket(Opcode::Acknowledgement), blockNumber(blockNumber) Packet(Opcode::Acknowledgement), blockNumber(blockNumber)
{} {}
size_t TftpAcknowledgementPacket::SerializedLength() const size_t AcknowledgementPacket::SerializedLength() const
{ {
return TftpPacket::SerializedLength() + sizeof(blockNumber); return Packet::SerializedLength() + sizeof(blockNumber);
} }
size_t TftpAcknowledgementPacket::Serialize(uint8_t* buffer) const size_t AcknowledgementPacket::Serialize(uint8_t* buffer) const
{ {
size_t i = 0; size_t i = 0;
buffer[i++] = static_cast<uint16_t>(opcode) >> 8; buffer[i++] = static_cast<uint16_t>(opcode) >> 8;
@ -274,12 +274,12 @@ namespace Net::Tftp
} }
// //
// TftpDataPacket // DataPacket
// //
TftpDataPacket::TftpDataPacket() : TftpPacket(Opcode::Data), blockNumber(0) DataPacket::DataPacket() : Packet(Opcode::Data), blockNumber(0)
{} {}
size_t TftpDataPacket::Serialize(uint8_t* buffer) const size_t DataPacket::Serialize(uint8_t* buffer) const
{ {
size_t i = 0; size_t i = 0;
buffer[i++] = static_cast<uint16_t>(opcode) >> 8; buffer[i++] = static_cast<uint16_t>(opcode) >> 8;
@ -293,8 +293,8 @@ namespace Net::Tftp
return i; return i;
} }
size_t TftpDataPacket::Deserialize( size_t DataPacket::Deserialize(
TftpDataPacket& out, const uint8_t* buffer, size_t size DataPacket& out, const uint8_t* buffer, size_t size
) { ) {
if (size < sizeof(opcode) + sizeof(blockNumber)) { if (size < sizeof(opcode) + sizeof(blockNumber)) {
return 0; return 0;

View file

@ -16,11 +16,11 @@ namespace Net::Tftp {
Error = 5, Error = 5,
}; };
struct TftpPacket struct Packet
{ {
Opcode opcode; Opcode opcode;
TftpPacket(Opcode opcode) : opcode(opcode) {} Packet(Opcode opcode) : opcode(opcode) {}
virtual size_t SerializedLength() const { virtual size_t SerializedLength() const {
return sizeof(opcode); return sizeof(opcode);
@ -29,53 +29,53 @@ namespace Net::Tftp {
virtual size_t Serialize(uint8_t* buffer) const = 0; virtual size_t Serialize(uint8_t* buffer) const = 0;
}; };
struct TftpWriteReadRequestPacket : public TftpPacket struct WriteReadRequestPacket : public Packet
{ {
std::string filename; std::string filename;
std::string mode; std::string mode;
TftpWriteReadRequestPacket(const Opcode opcode); WriteReadRequestPacket(const Opcode opcode);
size_t SerializedLength() const override; size_t SerializedLength() const override;
size_t Serialize(uint8_t* buffer) const override; size_t Serialize(uint8_t* buffer) const override;
static TftpWriteReadRequestPacket Deserialize(const uint8_t* buffer); static WriteReadRequestPacket Deserialize(const uint8_t* buffer);
}; };
struct TftpErrorPacket : public TftpPacket struct ErrorPacket : public Packet
{ {
uint16_t errorCode; uint16_t errorCode;
std::string message; std::string message;
TftpErrorPacket(); ErrorPacket();
TftpErrorPacket(uint16_t errorCode, std::string message); ErrorPacket(uint16_t errorCode, std::string message);
size_t SerializedLength() const override; size_t SerializedLength() const override;
size_t Serialize(uint8_t* buffer) const override; size_t Serialize(uint8_t* buffer) const override;
}; };
struct TftpAcknowledgementPacket : public TftpPacket struct AcknowledgementPacket : public Packet
{ {
uint16_t blockNumber; uint16_t blockNumber;
TftpAcknowledgementPacket(); AcknowledgementPacket();
TftpAcknowledgementPacket(uint16_t blockNumber); AcknowledgementPacket(uint16_t blockNumber);
size_t SerializedLength() const override; size_t SerializedLength() const override;
size_t Serialize(uint8_t* buffer) const override; size_t Serialize(uint8_t* buffer) const override;
}; };
struct TftpDataPacket : public TftpPacket struct DataPacket : public Packet
{ {
uint16_t blockNumber; uint16_t blockNumber;
std::vector<uint8_t> data; std::vector<uint8_t> data;
TftpDataPacket(); DataPacket();
size_t Serialize(uint8_t* buffer) const override; size_t Serialize(uint8_t* buffer) const override;
static size_t Deserialize( static size_t Deserialize(
TftpDataPacket& out, const uint8_t* buffer, size_t length); DataPacket& out, const uint8_t* buffer, size_t length);
}; };
void HandlePacket( void HandlePacket(
const Net::Ethernet::EthernetFrameHeader ethernetReqHeader, const Ethernet::Header ethernetReqHeader,
const Ipv4Header ipv4ReqHeader, const Ipv4Header ipv4ReqHeader,
const UdpDatagramHeader udpReqHeader, const Udp::Header udpReqHeader,
const uint8_t* buffer const uint8_t* buffer
); );
}; // namespace Net::Tftp }; // namespace Net::Tftp

View file

@ -1,11 +1,15 @@
#include "net-udp.h" #include "net-udp.h"
#include "net-dhcp.h"
#include "net-tftp.h"
UdpDatagramHeader::UdpDatagramHeader() namespace Net::Udp
{
Header::Header()
{} {}
UdpDatagramHeader::UdpDatagramHeader( Header::Header(
uint16_t sourcePort, Port sourcePort,
uint16_t destinationPort, Port destinationPort,
uint16_t length uint16_t length
) : ) :
sourcePort(sourcePort), sourcePort(sourcePort),
@ -14,13 +18,13 @@ UdpDatagramHeader::UdpDatagramHeader(
checksum(0) checksum(0)
{} {}
size_t UdpDatagramHeader::Serialize(uint8_t* buffer) const size_t Header::Serialize(uint8_t* buffer) const
{ {
size_t i = 0; size_t i = 0;
buffer[i++] = sourcePort >> 8; buffer[i++] = static_cast<uint16_t>(sourcePort) >> 8;
buffer[i++] = sourcePort; buffer[i++] = static_cast<uint16_t>(sourcePort);
buffer[i++] = destinationPort >> 8; buffer[i++] = static_cast<uint16_t>(destinationPort) >> 8;
buffer[i++] = destinationPort; buffer[i++] = static_cast<uint16_t>(destinationPort);
buffer[i++] = length >> 8; buffer[i++] = length >> 8;
buffer[i++] = length; buffer[i++] = length;
buffer[i++] = checksum >> 8; buffer[i++] = checksum >> 8;
@ -28,12 +32,40 @@ size_t UdpDatagramHeader::Serialize(uint8_t* buffer) const
return i; return i;
} }
UdpDatagramHeader UdpDatagramHeader::Deserialize(const uint8_t* buffer) Header Header::Deserialize(const uint8_t* buffer)
{ {
UdpDatagramHeader self; Header self;
self.sourcePort = buffer[0] << 8 | buffer[1]; self.sourcePort = static_cast<Port>(buffer[0] << 8 | buffer[1]);
self.destinationPort = buffer[2] << 8 | buffer[3]; self.destinationPort = static_cast<Port>(buffer[2] << 8 | buffer[3]);
self.length = buffer[4] << 8 | buffer[5]; self.length = buffer[4] << 8 | buffer[5];
self.checksum = buffer[6] << 8 | buffer[7]; self.checksum = buffer[6] << 8 | buffer[7];
return self; return self;
} }
void HandlePacket(
const Ethernet::Header ethernetHeader,
const Ipv4Header ipv4Header,
const uint8_t* buffer,
const size_t size
) {
const auto udpHeader = Header::Deserialize(buffer);
if (udpHeader.destinationPort == Port::DhcpClient)
{
Dhcp::HandlePacket(
ethernetHeader,
buffer + udpHeader.SerializedLength(),
size - udpHeader.SerializedLength()
);
}
else if (udpHeader.destinationPort == Port::Tftp)
{
Tftp::HandlePacket(
ethernetHeader,
ipv4Header,
udpHeader,
buffer + udpHeader.SerializedLength()
);
}
}
}; // namespace Net::Udp

View file

@ -2,16 +2,27 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include "net-ethernet.h"
#include "net-ipv4.h"
struct UdpDatagramHeader namespace Net::Udp
{ {
uint16_t sourcePort; enum class Port : uint16_t
uint16_t destinationPort; {
DhcpServer = 67,
DhcpClient = 68,
Tftp = 69, // nice
};
struct Header
{
Port sourcePort;
Port destinationPort;
uint16_t length; uint16_t length;
uint16_t checksum; uint16_t checksum;
UdpDatagramHeader(); Header();
UdpDatagramHeader(uint16_t sourcePort, uint16_t destinationPort, uint16_t length); Header(Port sourcePort, Port destinationPort, uint16_t length);
static constexpr size_t SerializedLength() static constexpr size_t SerializedLength()
{ {
@ -23,5 +34,13 @@ struct UdpDatagramHeader
} }
size_t Serialize(uint8_t* buffer) const; size_t Serialize(uint8_t* buffer) const;
static UdpDatagramHeader Deserialize(const uint8_t* buffer); static Header Deserialize(const uint8_t* buffer);
}; };
void HandlePacket(
const Ethernet::Header ethernetHeader,
const Ipv4Header ipv4Header,
const uint8_t* buffer,
const size_t size
);
}; // namespace Net::Udp

View file

@ -18,7 +18,7 @@
// IPv4 // IPv4
// //
void HandleIpv4Packet( void HandleIpv4Packet(
const Net::Ethernet::EthernetFrameHeader ethernetHeader, const Net::Ethernet::Header ethernetHeader,
const uint8_t* buffer, const uint8_t* buffer,
const size_t size const size_t size
) { ) {
@ -40,44 +40,15 @@ void HandleIpv4Packet(
} }
else if (ipv4Header.protocol == IP_PROTO_UDP) else if (ipv4Header.protocol == IP_PROTO_UDP)
{ {
HandleUdpDatagram(ethernetHeader, ipv4Header, buffer + offset, size - offset); Net::Udp::HandlePacket(
} ethernetHeader, ipv4Header, buffer + offset, size - offset);
}
//
// UDP
//
void HandleUdpDatagram(
const Net::Ethernet::EthernetFrameHeader ethernetHeader,
const Ipv4Header ipv4Header,
const uint8_t* buffer,
const size_t size
) {
const auto udpHeader = UdpDatagramHeader::Deserialize(buffer);
if (udpHeader.destinationPort == UDP_PORT_DHCP_CLIENT)
{
Net::Dhcp::HandlePacket(
ethernetHeader,
buffer + udpHeader.SerializedLength(),
size - udpHeader.SerializedLength()
);
}
else if (udpHeader.destinationPort == UDP_PORT_TFTP)
{
Net::Tftp::HandlePacket(
ethernetHeader,
ipv4Header,
udpHeader,
buffer + udpHeader.SerializedLength()
);
} }
} }
// //
// ICMP // ICMP
// //
void SendIcmpEchoRequest(MacAddress mac, uint32_t ip) void SendIcmpEchoRequest(Net::Utils::MacAddress mac, uint32_t ip)
{ {
IcmpPacketHeader icmpHeader(8, 0); IcmpPacketHeader icmpHeader(8, 0);
IcmpEchoHeader pingHeader(0, 0); IcmpEchoHeader pingHeader(0, 0);
@ -87,7 +58,7 @@ void SendIcmpEchoRequest(MacAddress mac, uint32_t ip)
Ipv4Header::SerializedLength(); Ipv4Header::SerializedLength();
Ipv4Header ipv4Header(1, Net::Utils::Ipv4Address, ip, ipv4TotalSize); Ipv4Header ipv4Header(1, Net::Utils::Ipv4Address, ip, ipv4TotalSize);
Net::Ethernet::EthernetFrameHeader ethernetHeader( Net::Ethernet::Header ethernetHeader(
mac, Net::Utils::GetMacAddress(), Net::Ethernet::ETHERTYPE_IPV4); mac, Net::Utils::GetMacAddress(), Net::Ethernet::ETHERTYPE_IPV4);
uint8_t buffer[USPI_FRAME_BUFFER_SIZE]; uint8_t buffer[USPI_FRAME_BUFFER_SIZE];
@ -106,7 +77,7 @@ void HandleIcmpFrame(const uint8_t* buffer)
// TODO Don't re-parse the upper layers // TODO Don't re-parse the upper layers
size_t requestSize = 0; size_t requestSize = 0;
const auto requestEthernetHeader = const auto requestEthernetHeader =
Net::Ethernet::EthernetFrameHeader::Deserialize(buffer + requestSize); Net::Ethernet::Header::Deserialize(buffer + requestSize);
requestSize += requestEthernetHeader.SerializedLength(); requestSize += requestEthernetHeader.SerializedLength();
const auto requestIpv4Header = Ipv4Header::Deserialize(buffer + requestSize); const auto requestIpv4Header = Ipv4Header::Deserialize(buffer + requestSize);
requestSize += requestIpv4Header.SerializedLength(); requestSize += requestIpv4Header.SerializedLength();
@ -126,7 +97,7 @@ void HandleIcmpFrame(const uint8_t* buffer)
requestIpv4Header.sourceIp, requestIpv4Header.sourceIp,
requestIpv4Header.totalLength requestIpv4Header.totalLength
); );
const Net::Ethernet::EthernetFrameHeader responseEthernetHeader( const Net::Ethernet::Header responseEthernetHeader(
requestEthernetHeader.macSource, requestEthernetHeader.macSource,
Net::Utils::GetMacAddress(), Net::Utils::GetMacAddress(),
Net::Ethernet::ETHERTYPE_IPV4 Net::Ethernet::ETHERTYPE_IPV4
@ -148,11 +119,3 @@ void HandleIcmpFrame(const uint8_t* buffer)
USPiSendFrame(bufferResp.data(), respSize); USPiSendFrame(bufferResp.data(), respSize);
} }
} }
//
// Helpers
//
bool FileUploaded = false;

View file

@ -10,27 +10,11 @@
#include "net-ipv4.h" #include "net-ipv4.h"
#include "net-utils.h" #include "net-utils.h"
enum UdpPort {
UDP_PORT_DHCP_SERVER = 67,
UDP_PORT_DHCP_CLIENT = 68,
UDP_PORT_TFTP = 69, // nice
};
// //
// IPv4 // IPv4
// //
void HandleIpv4Packet( void HandleIpv4Packet(
const Net::Ethernet::EthernetFrameHeader ethernetHeader, const Net::Ethernet::Header ethernetHeader,
const uint8_t* buffer,
const size_t size
);
//
// UDP
//
void HandleUdpDatagram(
const Net::Ethernet::EthernetFrameHeader ethernetHeader,
const Ipv4Header ipv4Header,
const uint8_t* buffer, const uint8_t* buffer,
const size_t size const size_t size
); );
@ -38,11 +22,5 @@ void HandleUdpDatagram(
// //
// ICMP // ICMP
// //
void SendIcmpEchoRequest(MacAddress mac, uint32_t ip); void SendIcmpEchoRequest(Net::Utils::MacAddress mac, uint32_t ip);
void HandleIcmpFrame(const uint8_t* buffer); void HandleIcmpFrame(const uint8_t* buffer);
//
// Helpers
//
extern bool FileUploaded;