summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-13 15:40:30 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-13 15:40:30 +0100
commit4dddf949c83579df866ad95ae3cea16a0b651a0b (patch)
tree47a47d2b554ecca226ba0aaa9d55938d54aa4202 /Kernel
parent48431b353540decd498749b56b87f2197104fdd3 (diff)
downloadserenity-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.cpp33
-rw-r--r--Kernel/NetworkTask.cpp2
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;