Put Udp in namespace and simplify symbol names
This commit is contained in:
parent
118f6b62c2
commit
aec510a47c
13 changed files with 292 additions and 299 deletions
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
|
|
116
src/net-tftp.cpp
116
src/net-tftp.cpp
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
102
src/net-udp.cpp
102
src/net-udp.cpp
|
@ -1,39 +1,71 @@
|
||||||
#include "net-udp.h"
|
#include "net-udp.h"
|
||||||
|
#include "net-dhcp.h"
|
||||||
|
#include "net-tftp.h"
|
||||||
|
|
||||||
UdpDatagramHeader::UdpDatagramHeader()
|
namespace Net::Udp
|
||||||
{}
|
|
||||||
|
|
||||||
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) const
|
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
Header::Header()
|
||||||
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)
|
Header::Header(
|
||||||
{
|
Port sourcePort,
|
||||||
UdpDatagramHeader self;
|
Port destinationPort,
|
||||||
self.sourcePort = buffer[0] << 8 | buffer[1];
|
uint16_t length
|
||||||
self.destinationPort = buffer[2] << 8 | buffer[3];
|
) :
|
||||||
self.length = buffer[4] << 8 | buffer[5];
|
sourcePort(sourcePort),
|
||||||
self.checksum = buffer[6] << 8 | buffer[7];
|
destinationPort(destinationPort),
|
||||||
return self;
|
length(length),
|
||||||
}
|
checksum(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t Header::Serialize(uint8_t* buffer) const
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
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;
|
||||||
|
buffer[i++] = checksum;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Header Header::Deserialize(const uint8_t* buffer)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|
|
@ -2,26 +2,45 @@
|
||||||
#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;
|
|
||||||
uint16_t length;
|
|
||||||
uint16_t checksum;
|
|
||||||
|
|
||||||
UdpDatagramHeader();
|
|
||||||
UdpDatagramHeader(uint16_t sourcePort, uint16_t destinationPort, uint16_t length);
|
|
||||||
|
|
||||||
static constexpr size_t SerializedLength()
|
|
||||||
{
|
{
|
||||||
return
|
DhcpServer = 67,
|
||||||
sizeof(sourcePort) +
|
DhcpClient = 68,
|
||||||
sizeof(destinationPort) +
|
Tftp = 69, // nice
|
||||||
sizeof(length) +
|
};
|
||||||
sizeof(checksum);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Serialize(uint8_t* buffer) const;
|
struct Header
|
||||||
static UdpDatagramHeader Deserialize(const uint8_t* buffer);
|
{
|
||||||
};
|
Port sourcePort;
|
||||||
|
Port destinationPort;
|
||||||
|
uint16_t length;
|
||||||
|
uint16_t checksum;
|
||||||
|
|
||||||
|
Header();
|
||||||
|
Header(Port sourcePort, Port destinationPort, uint16_t length);
|
||||||
|
|
||||||
|
static constexpr size_t SerializedLength()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
sizeof(sourcePort) +
|
||||||
|
sizeof(destinationPort) +
|
||||||
|
sizeof(length) +
|
||||||
|
sizeof(checksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Serialize(uint8_t* buffer) const;
|
||||||
|
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
|
||||||
|
|
51
src/net.cpp
51
src/net.cpp
|
@ -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;
|
|
||||||
|
|
26
src/net.h
26
src/net.h
|
@ -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;
|
|
||||||
|
|
Loading…
Reference in a new issue