diff options
-rw-r--r-- | Kernel/IPv4Socket.cpp | 11 | ||||
-rw-r--r-- | Kernel/Makefile | 2 | ||||
-rw-r--r-- | Kernel/Net/.gitignore | 2 | ||||
-rw-r--r-- | Kernel/Net/LoopbackAdapter.cpp | 24 | ||||
-rw-r--r-- | Kernel/Net/LoopbackAdapter.h | 16 | ||||
-rw-r--r-- | Kernel/Net/Routing.cpp | 10 | ||||
-rw-r--r-- | Kernel/Net/Routing.h | 5 | ||||
-rw-r--r-- | Kernel/NetworkAdapter.cpp | 2 | ||||
-rw-r--r-- | Kernel/NetworkTask.cpp | 16 | ||||
-rw-r--r-- | Kernel/TCPSocket.cpp | 22 | ||||
-rw-r--r-- | Kernel/UDPSocket.cpp | 10 |
11 files changed, 95 insertions, 25 deletions
diff --git a/Kernel/IPv4Socket.cpp b/Kernel/IPv4Socket.cpp index 5820cc0a31..3a327e1a4e 100644 --- a/Kernel/IPv4Socket.cpp +++ b/Kernel/IPv4Socket.cpp @@ -9,6 +9,7 @@ #include <Kernel/TCP.h> #include <Kernel/UDP.h> #include <Kernel/ARP.h> +#include <Kernel/Net/Routing.h> #include <LibC/errno_numbers.h> #define IPV4_SOCKET_DEBUG @@ -128,12 +129,6 @@ ssize_t IPv4Socket::sendto(const void* data, size_t data_length, int flags, cons (void)flags; if (addr && addr_length != sizeof(sockaddr_in)) return -EINVAL; - // FIXME: Find the adapter some better way! - auto* adapter = NetworkAdapter::from_ipv4_address(IPv4Address(192, 168, 5, 2)); - if (!adapter) { - // FIXME: Figure out which error code to return. - ASSERT_NOT_REACHED(); - } if (addr) { if (addr->sa_family != AF_INET) { @@ -146,6 +141,10 @@ ssize_t IPv4Socket::sendto(const void* data, size_t data_length, int flags, cons m_destination_port = ntohs(ia.sin_port); } + auto* adapter = adapter_for_route_to(m_destination_address); + if (!adapter) + return -EHOSTUNREACH; + int rc = allocate_source_port_if_needed(); if (rc < 0) return rc; diff --git a/Kernel/Makefile b/Kernel/Makefile index 98826d5628..11cc3a4142 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -39,6 +39,8 @@ KERNEL_OBJS = \ UDPSocket.o \ NetworkAdapter.o \ E1000NetworkAdapter.o \ + Net/LoopbackAdapter.o \ + Net/Routing.o \ NetworkTask.o VFS_OBJS = \ diff --git a/Kernel/Net/.gitignore b/Kernel/Net/.gitignore new file mode 100644 index 0000000000..6142305dc1 --- /dev/null +++ b/Kernel/Net/.gitignore @@ -0,0 +1,2 @@ +*.o +*.d diff --git a/Kernel/Net/LoopbackAdapter.cpp b/Kernel/Net/LoopbackAdapter.cpp new file mode 100644 index 0000000000..1593f3b3cf --- /dev/null +++ b/Kernel/Net/LoopbackAdapter.cpp @@ -0,0 +1,24 @@ +#include <Kernel/Net/LoopbackAdapter.h> + +LoopbackAdapter& LoopbackAdapter::the() +{ + static LoopbackAdapter* the; + if (!the) + the = new LoopbackAdapter; + return *the; +} + +LoopbackAdapter::LoopbackAdapter() +{ + set_ipv4_address({ 127, 0, 0, 1 }); +} + +LoopbackAdapter::~LoopbackAdapter() +{ +} + +void LoopbackAdapter::send_raw(const byte* data, int size) +{ + dbgprintf("LoopbackAdapter: Sending %d byte(s) to myself.\n", size); + did_receive(data, size); +} diff --git a/Kernel/Net/LoopbackAdapter.h b/Kernel/Net/LoopbackAdapter.h new file mode 100644 index 0000000000..56cf6c4283 --- /dev/null +++ b/Kernel/Net/LoopbackAdapter.h @@ -0,0 +1,16 @@ +#pragma once + +#include <Kernel/NetworkAdapter.h> + +class LoopbackAdapter final : public NetworkAdapter { +public: + static LoopbackAdapter& the(); + + virtual ~LoopbackAdapter() override; + + virtual void send_raw(const byte*, int) override; + virtual const char* class_name() const override { return "LoopbackAdapter"; } + +private: + LoopbackAdapter(); +}; diff --git a/Kernel/Net/Routing.cpp b/Kernel/Net/Routing.cpp new file mode 100644 index 0000000000..9561fd9249 --- /dev/null +++ b/Kernel/Net/Routing.cpp @@ -0,0 +1,10 @@ +#include <Kernel/Net/Routing.h> +#include <Kernel/Net/LoopbackAdapter.h> + +NetworkAdapter* adapter_for_route_to(const IPv4Address& ipv4_address) +{ + // FIXME: Have an actual routing table. + if (ipv4_address == IPv4Address(127, 0, 0, 1)) + return &LoopbackAdapter::the(); + return NetworkAdapter::from_ipv4_address(IPv4Address(192, 168, 5, 2)); +} diff --git a/Kernel/Net/Routing.h b/Kernel/Net/Routing.h new file mode 100644 index 0000000000..85eb72a116 --- /dev/null +++ b/Kernel/Net/Routing.h @@ -0,0 +1,5 @@ +#pragma once + +#include <Kernel/NetworkAdapter.h> + +NetworkAdapter* adapter_for_route_to(const IPv4Address&); diff --git a/Kernel/NetworkAdapter.cpp b/Kernel/NetworkAdapter.cpp index 2188988b66..aa4d45b9b1 100644 --- a/Kernel/NetworkAdapter.cpp +++ b/Kernel/NetworkAdapter.cpp @@ -28,14 +28,12 @@ NetworkAdapter::NetworkAdapter() : m_packet_queue_alarm(*this) { // FIXME: I wanna lock :( - ASSERT_INTERRUPTS_DISABLED(); all_adapters().resource().set(this); } NetworkAdapter::~NetworkAdapter() { // FIXME: I wanna lock :( - ASSERT_INTERRUPTS_DISABLED(); all_adapters().resource().remove(this); } diff --git a/Kernel/NetworkTask.cpp b/Kernel/NetworkTask.cpp index b1b20c1c4e..9132765dc3 100644 --- a/Kernel/NetworkTask.cpp +++ b/Kernel/NetworkTask.cpp @@ -11,6 +11,7 @@ #include <Kernel/Process.h> #include <Kernel/EtherType.h> #include <Kernel/Lock.h> +#include <Kernel/Net/LoopbackAdapter.h> //#define ETHERNET_DEBUG #define IPV4_DEBUG @@ -34,16 +35,27 @@ Lockable<HashMap<IPv4Address, MACAddress>>& arp_table() void NetworkTask_main() { + LoopbackAdapter::the(); + auto* adapter_ptr = E1000NetworkAdapter::the(); ASSERT(adapter_ptr); auto& adapter = *adapter_ptr; adapter.set_ipv4_address(IPv4Address(192, 168, 5, 2)); + auto dequeue_packet = [&] () -> ByteBuffer { + if (LoopbackAdapter::the().has_queued_packets()) + return LoopbackAdapter::the().dequeue_packet(); + if (adapter.has_queued_packets()) + return adapter.dequeue_packet(); + return { }; + }; + kprintf("NetworkTask: Enter main loop.\n"); for (;;) { - auto packet = adapter.dequeue_packet(); + auto packet = dequeue_packet(); if (packet.is_null()) { - current->snooze_until(adapter.packet_queue_alarm()); + // FIXME: Wake up when one of the adapters has packets. + current->sleep(1); continue; } if (packet.size() < (int)(sizeof(EthernetFrameHeader))) { diff --git a/Kernel/TCPSocket.cpp b/Kernel/TCPSocket.cpp index f7eddb3b0b..dd856314e4 100644 --- a/Kernel/TCPSocket.cpp +++ b/Kernel/TCPSocket.cpp @@ -2,6 +2,7 @@ #include <Kernel/TCP.h> #include <Kernel/NetworkAdapter.h> #include <Kernel/Process.h> +#include <Kernel/Net/Routing.h> #include <Kernel/RandomDevice.h> Lockable<HashMap<word, TCPSocket*>>& TCPSocket::sockets_by_port() @@ -63,18 +64,18 @@ int TCPSocket::protocol_receive(const ByteBuffer& packet_buffer, void* buffer, s int TCPSocket::protocol_send(const void* data, int data_length) { - // FIXME: Figure out the adapter somehow differently. - auto* adapter = NetworkAdapter::from_ipv4_address(IPv4Address(192, 168, 5, 2)); + auto* adapter = adapter_for_route_to(destination_address()); if (!adapter) - ASSERT_NOT_REACHED(); + return -EHOSTUNREACH; send_tcp_packet(TCPFlags::PUSH | TCPFlags::ACK, data, data_length); return data_length; } void TCPSocket::send_tcp_packet(word flags, const void* payload, int payload_size) { - // FIXME: Figure out the adapter somehow differently. - auto& adapter = *NetworkAdapter::from_ipv4_address(IPv4Address(192, 168, 5, 2)); + // FIXME: Maybe the socket should be bound to an adapter instead of looking it up every time? + auto* adapter = adapter_for_route_to(destination_address()); + ASSERT(adapter); auto buffer = ByteBuffer::create_zeroed(sizeof(TCPPacket) + payload_size); auto& tcp_packet = *(TCPPacket*)(buffer.pointer()); @@ -96,9 +97,9 @@ void TCPSocket::send_tcp_packet(word flags, const void* payload, int payload_siz } memcpy(tcp_packet.payload(), payload, payload_size); - tcp_packet.set_checksum(compute_tcp_checksum(adapter.ipv4_address(), destination_address(), tcp_packet, payload_size)); + tcp_packet.set_checksum(compute_tcp_checksum(adapter->ipv4_address(), destination_address(), tcp_packet, payload_size)); kprintf("sending tcp packet from %s:%u to %s:%u with (%s %s) seq_no=%u, ack_no=%u\n", - adapter.ipv4_address().to_string().characters(), + adapter->ipv4_address().to_string().characters(), source_port(), destination_address().to_string().characters(), destination_port(), @@ -107,7 +108,7 @@ void TCPSocket::send_tcp_packet(word flags, const void* payload, int payload_siz tcp_packet.sequence_number(), tcp_packet.ack_number() ); - adapter.send_ipv4(MACAddress(), destination_address(), IPv4Protocol::TCP, move(buffer)); + adapter->send_ipv4(MACAddress(), destination_address(), IPv4Protocol::TCP, move(buffer)); } NetworkOrdered<word> TCPSocket::compute_tcp_checksum(const IPv4Address& source, const IPv4Address& destination, const TCPPacket& packet, word payload_size) @@ -153,10 +154,9 @@ NetworkOrdered<word> TCPSocket::compute_tcp_checksum(const IPv4Address& source, KResult TCPSocket::protocol_connect() { - // FIXME: Figure out the adapter somehow differently. - auto* adapter = NetworkAdapter::from_ipv4_address(IPv4Address(192, 168, 5, 2)); + auto* adapter = adapter_for_route_to(destination_address()); if (!adapter) - ASSERT_NOT_REACHED(); + return KResult(-EHOSTUNREACH); allocate_source_port_if_needed(); diff --git a/Kernel/UDPSocket.cpp b/Kernel/UDPSocket.cpp index 61cfed1202..c54d94a16f 100644 --- a/Kernel/UDPSocket.cpp +++ b/Kernel/UDPSocket.cpp @@ -3,6 +3,7 @@ #include <Kernel/NetworkAdapter.h> #include <Kernel/Process.h> #include <Kernel/RandomDevice.h> +#include <Kernel/Net/Routing.h> Lockable<HashMap<word, UDPSocket*>>& UDPSocket::sockets_by_port() { @@ -62,8 +63,9 @@ int UDPSocket::protocol_receive(const ByteBuffer& packet_buffer, void* buffer, s int UDPSocket::protocol_send(const void* data, int data_length) { - // FIXME: Figure out the adapter somehow differently. - auto& adapter = *NetworkAdapter::from_ipv4_address(IPv4Address(192, 168, 5, 2)); + auto* adapter = adapter_for_route_to(destination_address()); + if (!adapter) + return -EHOSTUNREACH; auto buffer = ByteBuffer::create_zeroed(sizeof(UDPPacket) + data_length); auto& udp_packet = *(UDPPacket*)(buffer.pointer()); udp_packet.set_source_port(source_port()); @@ -71,11 +73,11 @@ int UDPSocket::protocol_send(const void* data, int data_length) udp_packet.set_length(sizeof(UDPPacket) + data_length); memcpy(udp_packet.payload(), data, data_length); kprintf("sending as udp packet from %s:%u to %s:%u!\n", - adapter.ipv4_address().to_string().characters(), + adapter->ipv4_address().to_string().characters(), source_port(), destination_address().to_string().characters(), destination_port()); - adapter.send_ipv4(MACAddress(), destination_address(), IPv4Protocol::UDP, move(buffer)); + adapter->send_ipv4(MACAddress(), destination_address(), IPv4Protocol::UDP, move(buffer)); return data_length; } |