mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 02:38:11 +00:00
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:
parent
be46f1bb1f
commit
3d5296a901
3 changed files with 27 additions and 15 deletions
|
@ -245,11 +245,16 @@ void IPv4Socket::send_tcp_packet(NetworkAdapter& adapter, word flags, const void
|
||||||
|
|
||||||
memcpy(tcp_packet.payload(), payload, payload_size);
|
memcpy(tcp_packet.payload(), payload, payload_size);
|
||||||
tcp_packet.set_checksum(compute_tcp_checksum(adapter.ipv4_address(), m_destination_address, tcp_packet, 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(),
|
adapter.ipv4_address().to_string().characters(),
|
||||||
source_port(),
|
source_port(),
|
||||||
m_destination_address.to_string().characters(),
|
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));
|
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) {
|
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;
|
return data_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +379,7 @@ ssize_t IPv4Socket::recvfrom(void* buffer, size_t buffer_length, int flags, sock
|
||||||
|
|
||||||
if (type() == SOCK_STREAM) {
|
if (type() == SOCK_STREAM) {
|
||||||
auto& tcp_packet = *static_cast<const TCPPacket*>(ipv4_packet.payload());
|
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);
|
ASSERT(buffer_length >= payload_size);
|
||||||
if (addr) {
|
if (addr) {
|
||||||
auto& ia = *(sockaddr_in*)addr;
|
auto& ia = *(sockaddr_in*)addr;
|
||||||
|
@ -395,5 +400,4 @@ void IPv4Socket::did_receive(ByteBuffer&& packet)
|
||||||
#ifdef IPV4_SOCKET_DEBUG
|
#ifdef IPV4_SOCKET_DEBUG
|
||||||
kprintf("IPv4Socket(%p): did_receive %d bytes, packets in queue: %d\n", this, packet.size(), m_receive_queue.size_slow());
|
kprintf("IPv4Socket(%p): did_receive %d bytes, packets in queue: %d\n", this, packet.size(), m_receive_queue.size_slow());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,8 +262,10 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& tcp_packet = *static_cast<const TCPPacket*>(ipv4_packet.payload());
|
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
|
#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(),
|
ipv4_packet.source().to_string().characters(),
|
||||||
tcp_packet.source_port(),
|
tcp_packet.source_port(),
|
||||||
ipv4_packet.destination().to_string().characters(),
|
ipv4_packet.destination().to_string().characters(),
|
||||||
|
@ -273,7 +275,8 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
|
||||||
tcp_packet.flags(),
|
tcp_packet.flags(),
|
||||||
tcp_packet.has_syn() ? "SYN" : "",
|
tcp_packet.has_syn() ? "SYN" : "",
|
||||||
tcp_packet.has_ack() ? "ACK" : "",
|
tcp_packet.has_ack() ? "ACK" : "",
|
||||||
tcp_packet.window_size()
|
tcp_packet.window_size(),
|
||||||
|
payload_size
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -293,10 +296,8 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
|
||||||
ASSERT(socket->type() == SOCK_STREAM);
|
ASSERT(socket->type() == SOCK_STREAM);
|
||||||
ASSERT(socket->source_port() == tcp_packet.destination_port());
|
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()) {
|
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;
|
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->set_tcp_ack_number(socket->tcp_sequence_number() + payload_size);
|
||||||
|
|
||||||
socket->send_tcp_packet(*adapter, TCPFlags::ACK);
|
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()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,30 +42,37 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Connecting to %s...", addr_str);
|
||||||
|
fflush(stdout);
|
||||||
rc = connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr));
|
rc = connect(fd, (struct sockaddr*)&dst_addr, sizeof(dst_addr));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("connect");
|
perror("connect");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
printf("ok!\n");
|
||||||
|
|
||||||
char buffer[BUFSIZ];
|
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);
|
rc = send(fd, (const char*)msg, strlen(msg), 0);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("send");
|
perror("send");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf("Message sent.\n");
|
printf("ok!\n");
|
||||||
|
|
||||||
|
printf("Waiting for response...");
|
||||||
ssize_t nrecv = recv(fd, buffer, sizeof(buffer), 0);
|
ssize_t nrecv = recv(fd, buffer, sizeof(buffer), 0);
|
||||||
if (nrecv < 0) {
|
if (nrecv < 0) {
|
||||||
perror("recvfrom");
|
perror("recvfrom");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
buffer[nrecv] = '\0';
|
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);
|
rc = close(fd);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("close");
|
perror("close");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue