Add buffer size checks to Net::Arp

This commit is contained in:
Sijmen 2020-12-29 13:28:48 +01:00
parent 4cd1682c4c
commit 9e41e71dfa
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
2 changed files with 94 additions and 81 deletions

View file

@ -4,24 +4,30 @@
#include "net-arp.h"
#include "net-ethernet.h"
#include "debug.h"
#include "types.h"
#include <uspi.h>
namespace Net::Arp
{
Packet::Packet()
{}
Packet::Packet() {}
Packet::Packet(uint16_t operation) :
Packet::Packet(const uint16_t operation) :
hardwareType(1), // Ethernet
protocolType(Ethernet::EtherType::Ipv4),
hardwareAddressLength(6),
protocolAddressLength(4),
operation(operation)
{}
size_t Packet::Serialize(uint8_t* buffer)
{
}
size_t Packet::Serialize(uint8_t* buffer, const size_t bufferSize)
{
if (bufferSize < SerializedLength())
{
return 0;
}
buffer[0] = hardwareType >> 8;
buffer[1] = hardwareType;
buffer[2] = static_cast<uint16_t>(protocolType) >> 8;
@ -49,33 +55,33 @@ namespace Net::Arp
}
// Static
Packet Packet::Deserialize(const uint8_t* buffer)
size_t Packet::Deserialize(const uint8_t* buffer, const size_t bufferSize)
{
Packet self;
if (bufferSize < SerializedLength())
{
return 0;
}
self.hardwareType = buffer[0] << 8 | buffer[1];
self.protocolType =
static_cast<Ethernet::EtherType>(buffer[2] << 8 | buffer[3]);
self.hardwareAddressLength = buffer[4];
self.protocolAddressLength = buffer[5];
self.operation = buffer[6] << 8 | buffer[7];
hardwareType = buffer[0] << 8 | buffer[1];
protocolType = static_cast<Ethernet::EtherType>(buffer[2] << 8 | buffer[3]);
hardwareAddressLength = buffer[4];
protocolAddressLength = buffer[5];
operation = buffer[6] << 8 | buffer[7];
memcpy(self.senderMac.data(), buffer + 8, 6);
self.senderIp =
buffer[14] << 24 | buffer[15] << 16 | buffer[16] << 8 | buffer[17];
memcpy(self.targetMac.data(), buffer + 18, 6);
self.targetIp =
buffer[24] << 24 | buffer[25] << 16 | buffer[26] << 8 | buffer[27];
memcpy(senderMac.data(), buffer + 8, 6);
senderIp = buffer[14] << 24 | buffer[15] << 16 | buffer[16] << 8 | buffer[17];
memcpy(targetMac.data(), buffer + 18, 6);
targetIp = buffer[24] << 24 | buffer[25] << 16 | buffer[26] << 8 | buffer[27];
return self;
return 28;
}
void SendPacket(
Operation operation,
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t targetIp,
uint32_t senderIp)
const Operation operation,
const Utils::MacAddress targetMac,
const Utils::MacAddress senderMac,
const uint32_t targetIp,
const uint32_t senderIp)
{
Packet arpPacket(operation);
arpPacket.targetMac = targetMac;
@ -83,16 +89,14 @@ namespace Net::Arp
arpPacket.targetIp = targetIp;
arpPacket.senderIp = senderIp;
Ethernet::Header ethernetHeader(
senderMac, targetMac, Ethernet::EtherType::Arp);
Ethernet::Header ethernetHeader(senderMac, targetMac, Ethernet::EtherType::Arp);
uint8_t buffer[USPI_FRAME_BUFFER_SIZE];
size_t size = 0;
size += ethernetHeader.Serialize(buffer + size, sizeof(buffer) - size);
size += arpPacket.Serialize(buffer + size);
size += arpPacket.Serialize(buffer + size, sizeof(buffer) - size);
const auto expectedSize =
ethernetHeader.SerializedLength() + arpPacket.SerializedLength();
const auto expectedSize = ethernetHeader.SerializedLength() + arpPacket.SerializedLength();
assert(size == expectedSize);
assert(size <= sizeof(buffer));
@ -100,56 +104,65 @@ namespace Net::Arp
}
void SendRequest(
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t targetIp,
uint32_t senderIp
) {
const Utils::MacAddress targetMac,
const Utils::MacAddress senderMac,
const uint32_t targetIp,
const uint32_t senderIp)
{
SendPacket(ARP_OPERATION_REQUEST, targetMac, senderMac, targetIp, senderIp);
}
void SendReply(
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t targetIp,
uint32_t senderIp
) {
const Utils::MacAddress targetMac,
const Utils::MacAddress senderMac,
const uint32_t targetIp,
const uint32_t senderIp)
{
SendPacket(ARP_OPERATION_REPLY, targetMac, senderMac, targetIp, senderIp);
}
void SendAnnouncement(Utils::MacAddress mac, uint32_t ip)
void SendAnnouncement(const Utils::MacAddress mac, const uint32_t ip)
{
SendReply(Utils::MacBroadcast, mac, ip, ip);
}
void HandlePacket(
const Ethernet::Header ethernetHeader, uint8_t* buffer
) {
const auto macAddress = Utils::GetMacAddress();
const auto arpPacket = Packet::Deserialize(buffer);
if (
arpPacket.hardwareType == 1 &&
arpPacket.protocolType == Ethernet::EtherType::Ipv4 &&
arpPacket.operation == ARP_OPERATION_REQUEST &&
arpPacket.targetIp == Utils::Ipv4Address)
const Ethernet::Header ethernetHeader, const uint8_t* buffer, const size_t bufferSize)
{
SendReply(
arpPacket.senderMac,
macAddress,
arpPacket.senderIp,
Utils::Ipv4Address
);
const auto macAddress = Utils::GetMacAddress();
Packet arpPacket;
size_t arpSize = arpPacket.Deserialize(buffer, bufferSize);
if (arpSize == 0 || arpSize != arpPacket.SerializedLength())
{
DEBUG_LOG(
"Dropped ARP packet (invalid buffer size %lu, expected %lu)\r\n",
bufferSize,
arpPacket.SerializedLength());
return;
}
else if (
arpPacket.hardwareType == 1 &&
arpPacket.protocolType == Ethernet::EtherType::Ipv4 &&
arpPacket.operation == ARP_OPERATION_REPLY &&
arpPacket.targetIp == Utils::Ipv4Address &&
arpPacket.targetMac == macAddress)
if (arpPacket.hardwareType != 1 || arpPacket.protocolType != Ethernet::EtherType::Ipv4 ||
arpPacket.targetIp != Utils::Ipv4Address)
{
// Might want to disable because of spamminess
DEBUG_LOG("Dropped ARP packet (invalid parameters)\r\n");
return;
}
switch (arpPacket.operation)
{
case ARP_OPERATION_REQUEST:
SendReply(arpPacket.senderMac, macAddress, arpPacket.senderIp, Utils::Ipv4Address);
break;
case ARP_OPERATION_REPLY:
ArpTable.insert(std::make_pair(arpPacket.senderIp, arpPacket.senderMac));
break;
default:
DEBUG_LOG("Dropped ARP packet (invalid operation %d)\r\n", arpPacket.operation);
break;
}
}

View file

@ -25,7 +25,7 @@ namespace Net::Arp
uint32_t targetIp;
Packet();
Packet(uint16_t operation);
Packet(const uint16_t operation);
constexpr size_t SerializedLength() const
{
@ -41,36 +41,36 @@ namespace Net::Arp
sizeof(targetIp);
}
size_t Serialize(uint8_t* buffer);
static Packet Deserialize(const uint8_t* buffer);
size_t Serialize(uint8_t* buffer, const size_t bufferSize);
size_t Deserialize(const uint8_t* buffer, const size_t bufferSize);
};
void HandlePacket(Ethernet::Header header, uint8_t* buffer);
void HandlePacket(
const Ethernet::Header header, const uint8_t* buffer, const size_t bufferSize);
void SendPacket(
Operation operation,
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t senderIp,
uint32_t targetIp
const Operation operation,
const Utils::MacAddress targetMac,
const Utils::MacAddress senderMac,
const uint32_t senderIp,
const uint32_t targetIp
);
void SendRequest(
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t senderIp,
uint32_t targetIp
const Utils::MacAddress targetMac,
const Utils::MacAddress senderMac,
const uint32_t senderIp,
const uint32_t targetIp
);
void SendReply(
Utils::MacAddress targetMac,
Utils::MacAddress senderMac,
uint32_t senderIp,
uint32_t targetIp
const Utils::MacAddress targetMac,
const Utils::MacAddress senderMac,
const uint32_t senderIp,
const uint32_t targetIp
);
void SendAnnouncement(Utils::MacAddress mac, uint32_t ip);
void SendAnnouncement(const Utils::MacAddress mac, const uint32_t ip);
extern std::unordered_map<uint32_t, Utils::MacAddress> ArpTable;
} // namespace Net::Arp