summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-14 01:42:29 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-14 01:44:42 +0100
commit3d5296a901a02093c57a854405c87668feb35b48 (patch)
tree2f130bf774c66cb4156a1e3a3d486b3cd543d5cd
parentbe46f1bb1ff497e6d113705ffa3b751ba455e65d (diff)
downloadserenity-3d5296a901a02093c57a854405c87668feb35b48.zip
IPv4: Last burst of TCP hacking for today.
Connecting to a test server and exchanging data back and forth works.
-rw-r--r--Kernel/IPv4Socket.cpp14
-rw-r--r--Kernel/NetworkTask.cpp15
-rw-r--r--Userland/tc.cpp13
3 files changed, 27 insertions, 15 deletions
diff --git a/Kernel/IPv4Socket.cpp b/Kernel/IPv4Socket.cpp
index 5ab2a3e283..8a090a35fc 100644
--- a/Kernel/IPv4Socket.cpp
+++ b/Kernel/IPv4Socket.cpp
@@ -245,11 +245,16 @@ void IPv4Socket::send_tcp_packet(NetworkAdapter& adapter, word flags, const void
memcpy(tcp_packet.payload(), payload, payload_size);
tcp_packet.set_checksum(compute_tcp_checksum(adapter.ipv4_address(), m_destination_address, tcp_packet, payload_size));
- kprintf("sending tcp packet from %s:%u to %s:%u!\n",
+ 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(),
source_port(),
m_destination_address.to_string().characters(),
- m_destination_port);
+ m_destination_port,
+ tcp_packet.has_syn() ? "SYN" : "",
+ tcp_packet.has_ack() ? "ACK" : "",
+ tcp_packet.sequence_number(),
+ tcp_packet.ack_number()
+ );
adapter.send_ipv4(MACAddress(), m_destination_address, IPv4Protocol::TCP, move(buffer));
}
@@ -302,7 +307,7 @@ ssize_t IPv4Socket::sendto(const void* data, size_t data_length, int flags, cons
}
if (type() == SOCK_STREAM) {
- send_tcp_packet(*adapter, 0, data, data_length);
+ send_tcp_packet(*adapter, TCPFlags::PUSH | TCPFlags::ACK, data, data_length);
return data_length;
}
@@ -374,7 +379,7 @@ ssize_t IPv4Socket::recvfrom(void* buffer, size_t buffer_length, int flags, sock
if (type() == SOCK_STREAM) {
auto& tcp_packet = *static_cast<const TCPPacket*>(ipv4_packet.payload());
- size_t payload_size = packet_buffer.size() - tcp_packet.header_size();
+ size_t payload_size = packet_buffer.size() - sizeof(IPv4Packet) - tcp_packet.header_size();
ASSERT(buffer_length >= payload_size);
if (addr) {
auto& ia = *(sockaddr_in*)addr;
@@ -395,5 +400,4 @@ void IPv4Socket::did_receive(ByteBuffer&& packet)
#ifdef IPV4_SOCKET_DEBUG
kprintf("IPv4Socket(%p): did_receive %d bytes, packets in queue: %d\n", this, packet.size(), m_receive_queue.size_slow());
#endif
-
}
diff --git a/Kernel/NetworkTask.cpp b/Kernel/NetworkTask.cpp
index d128c721d7..03e2f21a88 100644
--- a/Kernel/NetworkTask.cpp
+++ b/Kernel/NetworkTask.cpp
@@ -262,8 +262,10 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
}
auto& tcp_packet = *static_cast<const TCPPacket*>(ipv4_packet.payload());
+ size_t payload_size = ipv4_packet.payload_size() - tcp_packet.header_size();
+
#ifdef TCP_DEBUG
- kprintf("handle_tcp: source=%s:%u, destination=%s:%u seq_no=%u, ack_no=%u, flags=%w (%s %s), window_size=%u\n",
+ kprintf("handle_tcp: source=%s:%u, destination=%s:%u seq_no=%u, ack_no=%u, flags=%w (%s %s), window_size=%u, payload_size=%u\n",
ipv4_packet.source().to_string().characters(),
tcp_packet.source_port(),
ipv4_packet.destination().to_string().characters(),
@@ -273,7 +275,8 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
tcp_packet.flags(),
tcp_packet.has_syn() ? "SYN" : "",
tcp_packet.has_ack() ? "ACK" : "",
- tcp_packet.window_size()
+ tcp_packet.window_size(),
+ payload_size
);
#endif
@@ -293,10 +296,8 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
ASSERT(socket->type() == SOCK_STREAM);
ASSERT(socket->source_port() == tcp_packet.destination_port());
- size_t payload_size = ipv4_packet.payload_size() - tcp_packet.header_size();
-
if (tcp_packet.ack_number() != socket->tcp_sequence_number()) {
- kprintf("handle_tcp: ack/seq mismatch: got %u, wanted %u\n", tcp_packet.ack_number(), socket->tcp_sequence_number());
+ kprintf("handle_tcp: ack/seq mismatch: got %u, wanted %u\n",tcp_packet.ack_number(), socket->tcp_sequence_number());
return;
}
@@ -310,8 +311,8 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
}
socket->set_tcp_ack_number(socket->tcp_sequence_number() + payload_size);
-
socket->send_tcp_packet(*adapter, TCPFlags::ACK);
- socket->did_receive(ByteBuffer::copy((const byte*)&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size()));
+ if (payload_size != 0)
+ socket->did_receive(ByteBuffer::copy((const byte*)&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size()));
}
diff --git a/Userland/tc.cpp b/Userland/tc.cpp
index 9a3139a962..1e68839ef2 100644
--- a/Userland/tc.cpp
+++ b/Userland/tc.cpp
@@ -42,30 +42,37 @@ int main(int argc, char** argv)
return 1;
}
+ printf("Connecting to %s...", addr_str);
+ fflush(stdout);
rc = connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr));
if (rc < 0) {
perror("connect");
return 1;
}
+ printf("ok!\n");
char buffer[BUFSIZ];
- const char* msg = "Test message!\n";
+ const char* msg = "I am a TCP client.";
+ printf("Sending a greeting...");
rc = send(fd, (const char*)msg, strlen(msg), 0);
if (rc < 0) {
perror("send");
return 1;
}
- printf("Message sent.\n");
+ printf("ok!\n");
+ printf("Waiting for response...");
ssize_t nrecv = recv(fd, buffer, sizeof(buffer), 0);
if (nrecv < 0) {
perror("recvfrom");
return 1;
}
buffer[nrecv] = '\0';
- printf("Server: %s\n", buffer);
+ printf("ok! Got response:\n");
+ printf("\033[36;1m%s\033[0m", buffer);
+ printf("(%d bytes received)\n", nrecv);
rc = close(fd);
if (rc < 0) {
perror("close");