Kernel: Implement barebones arp table
This commit is contained in:
parent
e1ffbb710b
commit
a0138955cd
|
@ -49,6 +49,7 @@ set(KERNEL_SOURCES
|
|||
kernel/Memory/MemoryRegion.cpp
|
||||
kernel/Memory/PhysicalRange.cpp
|
||||
kernel/Memory/VirtualRange.cpp
|
||||
kernel/Networking/ARPTable.cpp
|
||||
kernel/Networking/E1000/E1000.cpp
|
||||
kernel/Networking/E1000/E1000E.cpp
|
||||
kernel/Networking/IPv4.cpp
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/HashMap.h>
|
||||
#include <BAN/IPv4.h>
|
||||
#include <BAN/MAC.h>
|
||||
#include <BAN/UniqPtr.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class ARPTable
|
||||
{
|
||||
BAN_NON_COPYABLE(ARPTable);
|
||||
BAN_NON_MOVABLE(ARPTable);
|
||||
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::UniqPtr<ARPTable>> create();
|
||||
|
||||
BAN::ErrorOr<BAN::MACAddress> get_mac_from_ipv4(BAN::IPv4Address);
|
||||
|
||||
private:
|
||||
ARPTable();
|
||||
|
||||
private:
|
||||
BAN::HashMap<BAN::IPv4Address, BAN::MACAddress> m_arp_table;
|
||||
|
||||
friend class BAN::UniqPtr<ARPTable>;
|
||||
};
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <BAN/Vector.h>
|
||||
#include <kernel/FS/TmpFS/FileSystem.h>
|
||||
#include <kernel/Networking/ARPTable.h>
|
||||
#include <kernel/Networking/NetworkInterface.h>
|
||||
#include <kernel/Networking/NetworkSocket.h>
|
||||
#include <kernel/PCI.h>
|
||||
|
@ -13,6 +14,9 @@ namespace Kernel
|
|||
|
||||
class NetworkManager : public TmpFileSystem
|
||||
{
|
||||
BAN_NON_COPYABLE(NetworkManager);
|
||||
BAN_NON_MOVABLE(NetworkManager);
|
||||
|
||||
public:
|
||||
enum class SocketType
|
||||
{
|
||||
|
@ -25,6 +29,8 @@ namespace Kernel
|
|||
static BAN::ErrorOr<void> initialize();
|
||||
static NetworkManager& get();
|
||||
|
||||
ARPTable& arp_table() { return *m_arp_table; }
|
||||
|
||||
BAN::ErrorOr<void> add_interface(PCI::Device& pci_device);
|
||||
|
||||
void unbind_socket(uint16_t port, BAN::RefPtr<NetworkSocket>);
|
||||
|
@ -38,6 +44,7 @@ namespace Kernel
|
|||
NetworkManager();
|
||||
|
||||
private:
|
||||
BAN::UniqPtr<ARPTable> m_arp_table;
|
||||
BAN::Vector<BAN::RefPtr<NetworkInterface>> m_interfaces;
|
||||
BAN::HashMap<int, BAN::WeakPtr<NetworkSocket>> m_bound_sockets;
|
||||
};
|
||||
|
|
|
@ -11,6 +11,9 @@ namespace Kernel
|
|||
|
||||
class NetworkSocket : public TmpInode, public BAN::Weakable<NetworkSocket>
|
||||
{
|
||||
BAN_NON_COPYABLE(NetworkSocket);
|
||||
BAN_NON_MOVABLE(NetworkSocket);
|
||||
|
||||
public:
|
||||
static constexpr uint16_t PORT_NONE = 0;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue