IPv4: Last burst of TCP hacking for today.

Connecting to a test server and exchanging data back and forth works.
This commit is contained in:
Andreas Kling 2019-03-14 01:42:29 +01:00
parent be46f1bb1f
commit 3d5296a901
3 changed files with 27 additions and 15 deletions

View file

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

View file

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

View file

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