Kernel: Implement barebones arp table

This commit is contained in:
2024-02-03 01:26:06 +02:00
parent e1ffbb710b
commit a0138955cd
7 changed files with 76 additions and 11 deletions

View File

@@ -0,0 +1,27 @@
#include <kernel/Networking/ARPTable.h>
namespace Kernel
{
static constexpr BAN::IPv4Address s_broadcast_ipv4 { 0xFFFFFFFF };
static constexpr BAN::MACAddress s_broadcast_mac {{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }};
BAN::ErrorOr<BAN::UniqPtr<ARPTable>> ARPTable::create()
{
return TRY(BAN::UniqPtr<ARPTable>::create());
}
ARPTable::ARPTable()
{
}
BAN::ErrorOr<BAN::MACAddress> ARPTable::get_mac_from_ipv4(BAN::IPv4Address ipv4_address)
{
if (ipv4_address == s_broadcast_ipv4)
return s_broadcast_mac;
dprintln("No MAC for IPv4 {}", ipv4_address);
return BAN::Error::from_errno(ENOTSUP);
}
}

View File

@@ -19,6 +19,7 @@ namespace Kernel
if (manager_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM);
auto manager = BAN::UniqPtr<NetworkManager>::adopt(manager_ptr);
manager->m_arp_table = TRY(ARPTable::create());
TRY(manager->TmpFileSystem::initialize(0777, 0, 0));
s_instance = BAN::move(manager);
return {};

View File

@@ -58,16 +58,12 @@ namespace Kernel
auto* destination = reinterpret_cast<const sockaddr_in*>(arguments->dest_addr);
auto message = BAN::ConstByteSpan((const uint8_t*)arguments->message, arguments->length);
if (destination->sin_port == PORT_NONE)
uint16_t dst_port = destination->sin_port;
if (dst_port == PORT_NONE)
return BAN::Error::from_errno(EINVAL);
if (destination->sin_addr.s_addr != 0xFFFFFFFF)
{
dprintln("Only broadcast ip supported");
return BAN::Error::from_errno(EINVAL);
}
static BAN::MACAddress dest_mac {{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }};
auto dst_addr = BAN::IPv4Address(destination->sin_addr.s_addr);
auto dst_mac = TRY(NetworkManager::get().arp_table().get_mac_from_ipv4(dst_addr));
const size_t interface_header_offset = 0;
const size_t interface_header_size = m_interface->interface_header_size();
@@ -87,9 +83,9 @@ namespace Kernel
BAN::ByteSpan packet_bytespan { full_packet.span() };
memcpy(full_packet.data() + payload_offset, message.data(), payload_size);
add_protocol_header(packet_bytespan.slice(protocol_header_offset), m_port, destination->sin_port);
add_ipv4_header(packet_bytespan.slice(ipv4_header_offset), m_interface->get_ipv4_address(), destination->sin_addr.s_addr, protocol());
m_interface->add_interface_header(packet_bytespan.slice(interface_header_offset), dest_mac);
add_protocol_header(packet_bytespan.slice(protocol_header_offset), m_port, dst_port);
add_ipv4_header(packet_bytespan.slice(ipv4_header_offset), m_interface->get_ipv4_address(), dst_addr, protocol());
m_interface->add_interface_header(packet_bytespan.slice(interface_header_offset), dst_mac);
TRY(m_interface->send_raw_bytes(packet_bytespan));
return arguments->length;