Kernel: Implement basic recvfrom

This commit is contained in:
2024-02-02 13:50:00 +02:00
parent 7b287a1d5b
commit 0f154c3173
20 changed files with 339 additions and 116 deletions

View File

@@ -102,6 +102,7 @@ namespace Kernel
// Socket API
BAN::ErrorOr<void> bind(const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<ssize_t> sendto(const sys_sendto_t*);
BAN::ErrorOr<ssize_t> recvfrom(sys_recvfrom_t*);
// General API
BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
@@ -126,7 +127,8 @@ namespace Kernel
// Socket API
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<ssize_t> sendto_impl(const sys_sendto_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<ssize_t> sendto_impl(const sys_sendto_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<ssize_t> recvfrom_impl(sys_recvfrom_t*) { return BAN::Error::from_errno(ENOTSUP); }
// General API
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); }

View File

@@ -23,7 +23,7 @@ namespace Kernel
static BAN::ErrorOr<BAN::RefPtr<E1000>> create(PCI::Device&);
~E1000();
virtual uint8_t* get_mac_address() override { return m_mac_address; }
virtual BAN::MACAddress get_mac_address() const override { return m_mac_address; }
virtual bool link_up() override { return m_link_up; }
virtual int link_speed() override;
@@ -66,11 +66,7 @@ namespace Kernel
BAN::UniqPtr<DMARegion> m_rx_descriptor_region;
BAN::UniqPtr<DMARegion> m_tx_descriptor_region;
uint8_t m_mac_address[6] {};
uint16_t m_rx_current {};
uint16_t m_tx_current {};
void* m_rx_buffers[E1000_RX_DESCRIPTOR_COUNT] {};
void* m_tx_buffers[E1000_TX_DESCRIPTOR_COUNT] {};
BAN::MACAddress m_mac_address {};
bool m_link_up { false };
friend class BAN::RefPtr<E1000>;

View File

@@ -1,10 +1,38 @@
#pragma once
#include <BAN/ByteSpan.h>
#include <BAN/Endianness.h>
#include <BAN/IPv4.h>
#include <BAN/Vector.h>
namespace Kernel
{
BAN::ErrorOr<void> add_ipv4_header(BAN::Vector<uint8_t>&, uint32_t src_ipv4, uint32_t dst_ipv4, uint8_t protocol);
struct IPv4Header
{
uint8_t version_IHL;
uint8_t DSCP_ECN;
BAN::NetworkEndian<uint16_t> total_length { 0 };
BAN::NetworkEndian<uint16_t> identification { 0 };
BAN::NetworkEndian<uint16_t> flags_frament { 0 };
uint8_t time_to_live;
uint8_t protocol;
BAN::NetworkEndian<uint16_t> checksum { 0 };
BAN::IPv4Address src_address;
BAN::IPv4Address dst_address;
constexpr uint16_t calculate_checksum() const
{
return 0xFFFF
- (((uint16_t)version_IHL << 8) | DSCP_ECN)
- total_length
- identification
- flags_frament
- (((uint16_t)time_to_live << 8) | protocol);
}
};
static_assert(sizeof(IPv4Header) == 20);
void add_ipv4_header(BAN::ByteSpan packet, BAN::IPv4Address src_ipv4, BAN::IPv4Address dst_ipv4, uint8_t protocol);
}

View File

@@ -2,7 +2,9 @@
#include <BAN/Errors.h>
#include <BAN/ByteSpan.h>
#include <BAN/MAC.h>
#include <kernel/Device/Device.h>
#include <kernel/Networking/IPv4.h>
namespace Kernel
{
@@ -19,13 +21,14 @@ namespace Kernel
NetworkInterface();
virtual ~NetworkInterface() {}
virtual uint8_t* get_mac_address() = 0;
uint32_t get_ipv4_address() const { return m_ipv4_address; }
virtual BAN::MACAddress get_mac_address() const = 0;
BAN::IPv4Address get_ipv4_address() const { return m_ipv4_address; }
virtual bool link_up() = 0;
virtual int link_speed() = 0;
BAN::ErrorOr<void> add_interface_header(BAN::Vector<uint8_t>&, uint8_t destination_mac[6]);
size_t interface_header_size() const;
void add_interface_header(BAN::ByteSpan packet, BAN::MACAddress destination);
virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return m_name; }
@@ -38,7 +41,7 @@ namespace Kernel
const dev_t m_rdev;
char m_name[10];
uint32_t m_ipv4_address {};
BAN::IPv4Address m_ipv4_address { 0 };
};
}

View File

@@ -32,6 +32,8 @@ namespace Kernel
BAN::ErrorOr<BAN::RefPtr<NetworkSocket>> create_socket(SocketType, mode_t, uid_t, gid_t);
void on_receive(BAN::ConstByteSpan);
private:
NetworkManager();

View File

@@ -4,6 +4,8 @@
#include <kernel/FS/TmpFS/Inode.h>
#include <kernel/Networking/NetworkInterface.h>
#include <netinet/in.h>
namespace Kernel
{
@@ -16,16 +18,22 @@ namespace Kernel
void bind_interface_and_port(NetworkInterface*, uint16_t port);
~NetworkSocket();
virtual BAN::ErrorOr<void> add_protocol_header(BAN::Vector<uint8_t>&, uint16_t src_port, uint16_t dst_port) = 0;
virtual size_t protocol_header_size() const = 0;
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t src_port, uint16_t dst_port) = 0;
virtual uint8_t protocol() const = 0;
virtual void add_packet(BAN::ConstByteSpan, BAN::IPv4Address sender_address, uint16_t sender_port) = 0;
protected:
NetworkSocket(mode_t mode, uid_t uid, gid_t gid);
virtual BAN::ErrorOr<size_t> read_packet(BAN::ByteSpan, sockaddr_in* sender_address) = 0;
virtual void on_close_impl() override;
virtual BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override;
virtual BAN::ErrorOr<ssize_t> sendto_impl(const sys_sendto_t*) override;
virtual BAN::ErrorOr<ssize_t> recvfrom_impl(sys_recvfrom_t*) override;
protected:
NetworkInterface* m_interface = nullptr;

View File

@@ -1,23 +1,54 @@
#pragma once
#include <BAN/CircularQueue.h>
#include <BAN/Endianness.h>
#include <kernel/Memory/VirtualRange.h>
#include <kernel/Networking/NetworkInterface.h>
#include <kernel/Networking/NetworkSocket.h>
#include <kernel/Semaphore.h>
namespace Kernel
{
struct UDPHeader
{
BAN::NetworkEndian<uint16_t> src_port;
BAN::NetworkEndian<uint16_t> dst_port;
BAN::NetworkEndian<uint16_t> length;
BAN::NetworkEndian<uint16_t> checksum;
};
static_assert(sizeof(UDPHeader) == 8);
class UDPSocket final : public NetworkSocket
{
public:
static BAN::ErrorOr<BAN::RefPtr<UDPSocket>> create(mode_t, uid_t, gid_t);
virtual BAN::ErrorOr<void> add_protocol_header(BAN::Vector<uint8_t>&, uint16_t src_port, uint16_t dst_port) override;
virtual size_t protocol_header_size() const override { return sizeof(UDPHeader); }
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t src_port, uint16_t dst_port) override;
virtual uint8_t protocol() const override { return 0x11; }
protected:
virtual void add_packet(BAN::ConstByteSpan, BAN::IPv4Address sender_addr, uint16_t sender_port) override;
virtual BAN::ErrorOr<size_t> read_packet(BAN::ByteSpan, sockaddr_in* sender_address) override;
private:
UDPSocket(mode_t, uid_t, gid_t);
struct PacketInfo
{
BAN::IPv4Address sender_addr;
uint16_t sender_port;
size_t packet_size;
};
private:
static constexpr size_t packet_buffer_size = 10 * PAGE_SIZE;
BAN::UniqPtr<VirtualRange> m_packet_buffer;
BAN::CircularQueue<PacketInfo, 128> m_packets;
size_t m_packet_total_size { 0 };
Semaphore m_semaphore;
friend class BAN::RefPtr<UDPSocket>;
};

View File

@@ -115,6 +115,7 @@ namespace Kernel
BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
BAN::ErrorOr<long> sys_bind(int socket, const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<long> sys_sendto(const sys_sendto_t*);
BAN::ErrorOr<long> sys_recvfrom(sys_recvfrom_t*);
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
BAN::ErrorOr<long> sys_dup(int fildes);