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;
}
auto ethernetHeader = Net::Ethernet::EthernetFrameHeader::Deserialize(ipBuffer);
auto ethernetHeader = Net::Ethernet::Header::Deserialize(ipBuffer);
const auto offset = ethernetHeader.SerializedLength();
static bool announcementSent = false;

View file

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

View file

@ -5,14 +5,12 @@
namespace Net::Arp
{
using Net::Utils::MacAddress;
enum ArpOperation {
enum Operation {
ARP_OPERATION_REQUEST = 1,
ARP_OPERATION_REPLY = 2,
};
struct Ipv4ArpPacket
struct Packet
{
uint16_t hardwareType;
uint16_t protocolType;
@ -20,13 +18,13 @@ namespace Net::Arp
uint8_t protocolAddressLength;
uint16_t operation;
MacAddress senderMac;
Utils::MacAddress senderMac;
uint32_t senderIp;
MacAddress targetMac;
Utils::MacAddress targetMac;
uint32_t targetIp;
Ipv4ArpPacket();
Ipv4ArpPacket(uint16_t operation);
Packet();
Packet(uint16_t operation);
constexpr size_t SerializedLength() const
{
@ -44,34 +42,34 @@ namespace Net::Arp
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(
ArpOperation operation,
MacAddress targetMac,
MacAddress senderMac,
Operation operation,
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t senderIp,
uint32_t targetIp
);
void SendRequest(
MacAddress targetMac,
MacAddress senderMac,
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t senderIp,
uint32_t targetIp
);
void SendReply(
MacAddress targetMac,
MacAddress senderMac,
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t senderIp,
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

View file

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

View file

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

View file

@ -2,24 +2,24 @@
#include "net-ethernet.h"
namespace Net::Ethernet {
EthernetFrameHeader::EthernetFrameHeader()
Header::Header()
{}
EthernetFrameHeader::EthernetFrameHeader(std::uint16_t type) :
macDestination(Net::Utils::MacBroadcast),
Header::Header(uint16_t type) :
macDestination(Utils::MacBroadcast),
macSource{0, 0, 0, 0, 0, 0},
type(type)
{}
EthernetFrameHeader::EthernetFrameHeader(
Header::Header(
MacAddress macSource, uint16_t type
) :
macDestination(Net::Utils::MacBroadcast),
macDestination(Utils::MacBroadcast),
macSource(macSource),
type(type)
{}
EthernetFrameHeader::EthernetFrameHeader(
Header::Header(
MacAddress macDestination, MacAddress macSource, uint16_t type
) :
macDestination(macDestination),
@ -27,9 +27,9 @@ namespace Net::Ethernet {
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());
i += sizeof(macDestination);
@ -43,9 +43,9 @@ namespace Net::Ethernet {
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.macSource.data(), buffer + 6, self.macSource.size());
self.type = buffer[12] << 8 | buffer[13];

View file

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

View file

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

View file

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

View file

@ -1,11 +1,15 @@
#include "net-udp.h"
#include "net-dhcp.h"
#include "net-tftp.h"
UdpDatagramHeader::UdpDatagramHeader()
namespace Net::Udp
{
Header::Header()
{}
UdpDatagramHeader::UdpDatagramHeader(
uint16_t sourcePort,
uint16_t destinationPort,
Header::Header(
Port sourcePort,
Port destinationPort,
uint16_t length
) :
sourcePort(sourcePort),
@ -14,13 +18,13 @@ UdpDatagramHeader::UdpDatagramHeader(
checksum(0)
{}
size_t UdpDatagramHeader::Serialize(uint8_t* buffer) const
size_t Header::Serialize(uint8_t* buffer) const
{
size_t i = 0;
buffer[i++] = sourcePort >> 8;
buffer[i++] = sourcePort;
buffer[i++] = destinationPort >> 8;
buffer[i++] = destinationPort;
buffer[i++] = static_cast<uint16_t>(sourcePort) >> 8;
buffer[i++] = static_cast<uint16_t>(sourcePort);
buffer[i++] = static_cast<uint16_t>(destinationPort) >> 8;
buffer[i++] = static_cast<uint16_t>(destinationPort);
buffer[i++] = length >> 8;
buffer[i++] = length;
buffer[i++] = checksum >> 8;
@ -28,12 +32,40 @@ size_t UdpDatagramHeader::Serialize(uint8_t* buffer) const
return i;
}
UdpDatagramHeader UdpDatagramHeader::Deserialize(const uint8_t* buffer)
Header Header::Deserialize(const uint8_t* buffer)
{
UdpDatagramHeader self;
self.sourcePort = buffer[0] << 8 | buffer[1];
self.destinationPort = buffer[2] << 8 | buffer[3];
Header self;
self.sourcePort = static_cast<Port>(buffer[0] << 8 | buffer[1]);
self.destinationPort = static_cast<Port>(buffer[2] << 8 | buffer[3]);
self.length = buffer[4] << 8 | buffer[5];
self.checksum = buffer[6] << 8 | buffer[7];
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 <string>
#include <cstdint>
#include "net-ethernet.h"
#include "net-ipv4.h"
struct UdpDatagramHeader
namespace Net::Udp
{
uint16_t sourcePort;
uint16_t destinationPort;
enum class Port : uint16_t
{
DhcpServer = 67,
DhcpClient = 68,
Tftp = 69, // nice
};
struct Header
{
Port sourcePort;
Port destinationPort;
uint16_t length;
uint16_t checksum;
UdpDatagramHeader();
UdpDatagramHeader(uint16_t sourcePort, uint16_t destinationPort, uint16_t length);
Header();
Header(Port sourcePort, Port destinationPort, uint16_t length);
static constexpr size_t SerializedLength()
{
@ -23,5 +34,13 @@ struct UdpDatagramHeader
}
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
//
void HandleIpv4Packet(
const Net::Ethernet::EthernetFrameHeader ethernetHeader,
const Net::Ethernet::Header ethernetHeader,
const uint8_t* buffer,
const size_t size
) {
@ -40,44 +40,15 @@ void HandleIpv4Packet(
}
else if (ipv4Header.protocol == IP_PROTO_UDP)
{
HandleUdpDatagram(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()
);
Net::Udp::HandlePacket(
ethernetHeader, ipv4Header, buffer + offset, size - offset);
}
}
//
// ICMP
//
void SendIcmpEchoRequest(MacAddress mac, uint32_t ip)
void SendIcmpEchoRequest(Net::Utils::MacAddress mac, uint32_t ip)
{
IcmpPacketHeader icmpHeader(8, 0);
IcmpEchoHeader pingHeader(0, 0);
@ -87,7 +58,7 @@ void SendIcmpEchoRequest(MacAddress mac, uint32_t ip)
Ipv4Header::SerializedLength();
Ipv4Header ipv4Header(1, Net::Utils::Ipv4Address, ip, ipv4TotalSize);
Net::Ethernet::EthernetFrameHeader ethernetHeader(
Net::Ethernet::Header ethernetHeader(
mac, Net::Utils::GetMacAddress(), Net::Ethernet::ETHERTYPE_IPV4);
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
size_t requestSize = 0;
const auto requestEthernetHeader =
Net::Ethernet::EthernetFrameHeader::Deserialize(buffer + requestSize);
Net::Ethernet::Header::Deserialize(buffer + requestSize);
requestSize += requestEthernetHeader.SerializedLength();
const auto requestIpv4Header = Ipv4Header::Deserialize(buffer + requestSize);
requestSize += requestIpv4Header.SerializedLength();
@ -126,7 +97,7 @@ void HandleIcmpFrame(const uint8_t* buffer)
requestIpv4Header.sourceIp,
requestIpv4Header.totalLength
);
const Net::Ethernet::EthernetFrameHeader responseEthernetHeader(
const Net::Ethernet::Header responseEthernetHeader(
requestEthernetHeader.macSource,
Net::Utils::GetMacAddress(),
Net::Ethernet::ETHERTYPE_IPV4
@ -148,11 +119,3 @@ void HandleIcmpFrame(const uint8_t* buffer)
USPiSendFrame(bufferResp.data(), respSize);
}
}
//
// Helpers
//
bool FileUploaded = false;

View file

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