From 4dddf949c83579df866ad95ae3cea16a0b651a0b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 13 Mar 2019 15:40:30 +0100 Subject: [PATCH] IPv4: More work on UDP support. I'm now able to connect to a simple UDP server on my host machine and exchange some data. Very cool! :^) --- Kernel/IPv4Socket.cpp | 33 ++++++++++++++++++++++++++++----- Kernel/NetworkTask.cpp | 2 +- Userland/ping.cpp | 2 +- Userland/uc.cpp | 7 ++++--- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Kernel/IPv4Socket.cpp b/Kernel/IPv4Socket.cpp index 3257719c6b..601f200414 100644 --- a/Kernel/IPv4Socket.cpp +++ b/Kernel/IPv4Socket.cpp @@ -27,7 +27,7 @@ IPv4Socket::IPv4Socket(int type, int protocol) : Socket(AF_INET, type, protocol) , m_lock("IPv4Socket") { - kprintf("%s(%u) IPv4Socket{%p} created with type=%u\n", current->name().characters(), current->pid(), this, type); + kprintf("%s(%u) IPv4Socket{%p} created with type=%u, protocol=%d\n", current->name().characters(), current->pid(), this, type, protocol); LOCKER(all_sockets().lock()); all_sockets().resource().set(this); } @@ -119,15 +119,38 @@ ssize_t IPv4Socket::sendto(const void* data, size_t data_length, int flags, cons auto& ia = *(const sockaddr_in*)addr; m_destination_address = IPv4Address((const byte*)&ia.sin_addr.s_addr); - m_destination_port = ia.sin_port; + m_destination_port = ntohs(ia.sin_port); + + m_source_port = 2413; kprintf("sendto: destination=%s:%u\n", m_destination_address.to_string().characters(), m_destination_port); // FIXME: If we can't find the right MAC address, block until it's available? // I feel like this should happen in a layer below this code. MACAddress mac_address; - adapter->send_ipv4(mac_address, m_destination_address, (IPv4Protocol)protocol(), ByteBuffer::copy((const byte*)data, data_length)); - return data_length; + + if (type() == SOCK_RAW) { + adapter->send_ipv4(mac_address, m_destination_address, (IPv4Protocol)protocol(), ByteBuffer::copy((const byte*)data, data_length)); + return data_length; + } + + if (type() == SOCK_DGRAM) { + auto buffer = ByteBuffer::create_zeroed(sizeof(UDPPacket) + data_length); + auto& udp_packet = *(UDPPacket*)(buffer.pointer()); + udp_packet.set_source_port(m_source_port); + udp_packet.set_destination_port(m_destination_port); + 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(), + source_port(), + m_destination_address.to_string().characters(), + m_destination_port); + adapter->send_ipv4(mac_address, m_destination_address, IPv4Protocol::UDP, move(buffer)); + return data_length; + } + + ASSERT_NOT_REACHED(); } ssize_t IPv4Socket::recvfrom(void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length) @@ -183,7 +206,7 @@ ssize_t IPv4Socket::recvfrom(void* buffer, size_t buffer_length, int flags, sock auto& udp_packet = *static_cast(ipv4_packet.payload()); ASSERT(udp_packet.length() >= sizeof(UDPPacket)); // FIXME: This should be rejected earlier. ASSERT(buffer_length >= (udp_packet.length() - sizeof(UDPPacket))); - ia.sin_port = udp_packet.destination_port(); + ia.sin_port = htons(udp_packet.destination_port()); memcpy(buffer, udp_packet.payload(), udp_packet.length() - sizeof(UDPPacket)); return udp_packet.length() - sizeof(UDPPacket); } diff --git a/Kernel/NetworkTask.cpp b/Kernel/NetworkTask.cpp index e85d5ab7bd..bf9d24ce69 100644 --- a/Kernel/NetworkTask.cpp +++ b/Kernel/NetworkTask.cpp @@ -232,7 +232,7 @@ void handle_udp(const EthernetFrameHeader& eth, int frame_size) LOCKER(IPv4Socket::all_sockets().lock()); for (RetainPtr socket : IPv4Socket::all_sockets().resource()) { LOCKER(socket->lock()); - if (socket->protocol() != (unsigned)IPv4Protocol::UDP) + if (socket->type() != SOCK_DGRAM) continue; if (socket->source_port() != udp_packet.destination_port()) continue; diff --git a/Userland/ping.cpp b/Userland/ping.cpp index 21ea2afc52..62ff8b41a2 100644 --- a/Userland/ping.cpp +++ b/Userland/ping.cpp @@ -46,7 +46,7 @@ int main(int argc, char** argv) return 1; } - const char* addr_str = "192.168.5.1"; + const char* addr_str = "127.0.0.1"; if (argc > 1) addr_str = argv[1]; diff --git a/Userland/uc.cpp b/Userland/uc.cpp index cb28aa53f9..672854d12e 100644 --- a/Userland/uc.cpp +++ b/Userland/uc.cpp @@ -9,8 +9,9 @@ int main(int argc, char** argv) { - (void)argc; - (void)argv; + const char* addr_str = "127.0.0.1"; + if (argc > 1) + addr_str = argv[1]; int fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { @@ -30,7 +31,7 @@ int main(int argc, char** argv) dst_addr.sin_family = AF_INET; dst_addr.sin_port = htons(8080); - dst_addr.sin_addr.s_addr = INADDR_ANY; + rc = inet_pton(AF_INET, addr_str, &dst_addr.sin_addr); char buffer[BUFSIZ]; const char* msg = "Test message";