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! :^)
This commit is contained in:
Andreas Kling 2019-03-13 15:40:30 +01:00
parent 48431b3535
commit 4dddf949c8
Notes: sideshowbarker 2024-07-19 15:04:12 +09:00
4 changed files with 34 additions and 10 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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];

View file

@ -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";