Kernel: Implement basic recvfrom
This commit is contained in:
@@ -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); }
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user