diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-13 15:40:30 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-13 15:40:30 +0100 |
commit | 4dddf949c83579df866ad95ae3cea16a0b651a0b (patch) | |
tree | 47a47d2b554ecca226ba0aaa9d55938d54aa4202 /Kernel | |
parent | 48431b353540decd498749b56b87f2197104fdd3 (diff) | |
download | serenity-4dddf949c83579df866ad95ae3cea16a0b651a0b.zip |
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! :^)
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/IPv4Socket.cpp | 33 | ||||
-rw-r--r-- | Kernel/NetworkTask.cpp | 2 |
2 files changed, 29 insertions, 6 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<const UDPPacket*>(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<IPv4Socket> 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; |