aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMarvin Borner2020-11-07 22:54:11 +0100
committerMarvin Borner2020-11-07 22:54:11 +0100
commit7473694a6cc65d3666ce26094d5eb4365a22daf1 (patch)
treecaa695b502fede3fe202044a4375b437179a37e8 /kernel
parent2ec4c397d57b238d7fea661828738a8828aa0cc1 (diff)
Fixed TCP handling, basic HTTP server
Diffstat (limited to 'kernel')
-rw-r--r--kernel/features/net.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/kernel/features/net.c b/kernel/features/net.c
index 178e89d..18addbb 100644
--- a/kernel/features/net.c
+++ b/kernel/features/net.c
@@ -1,5 +1,6 @@
// MIT License, Copyright (c) 2020 Marvin Borner
+#include <assert.h>
#include <cpu.h>
#include <def.h>
#include <mem.h>
@@ -204,7 +205,7 @@ void udp_send_packet(u32 dst, u16 src_port, u16 dst_port, void *data, int len)
free(packet);
}
-u32 seq_no, ack_no = 0; // TODO: Per socket
+static u32 seq_no, ack_no, tcp_state = 0; // TODO: Per socket
void tcp_send_packet(u32 dst, u16 src_port, u16 dst_port, u16 flags, void *data, int len)
{
print("TCP send packet\n");
@@ -220,11 +221,6 @@ void tcp_send_packet(u32 dst, u16 src_port, u16 dst_port, u16 flags, void *data,
packet->urgent = 0;
packet->checksum = 0; // Later
- /* if ((flags & 0xff) == TCP_FLAG_SYN) */
- /* seq_no++; */
- /* else */
- /* seq_no += (u32)len; */
-
if (data)
memcpy(packet->data, data, (u32)len);
@@ -288,37 +284,62 @@ void dhcp_handle_packet(struct dhcp_packet *packet)
}
}
+// enum tcp_state { TCP_LISTEN, TCP_SYN_SENT, TCP_SYN_RECIEVED, TCP_ESTABLISHED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, TCP_CLOSE_WAIT, TCP_CLOSING, TCP_LAST_ACK, TCP_TIME_WAIT, TCP_CLOSED };
+// TODO: Fix TCP retransmission (dropped packages; probably race condition)
+//#define test_http "HTTP/1.1 200"
+#define test_http "HTTP/1.2 200\nContent-Length: 14\nConnection: close\n\n<h1>Hallo</h1>"
void tcp_handle_packet(struct tcp_packet *packet, u32 dst, int len)
{
printf("TCP Port: %d\n", ntohs(packet->dst_port));
u32 data_length = (u32)len - (htons(packet->flags) >> 12) * 4;
u16 flags = (u16)ntohs(packet->flags);
- printf("%d\n", htonl(packet->seq_number));
- /* if (seq_no != ntohl(packet->ack_number)) { */
- /* printf("Dropping packet seq_no: %d\n", seq_no); */
- /* return; */
- /* } */
+ u32 recv_ack = ntohl(packet->ack_number);
+ u32 recv_seq = ntohl(packet->seq_number);
- /* ack_no = ntohl(packet->seq_number) + data_length; */
- if (flags & TCP_FLAG_SYN) {
- ack_no = ntohl(packet->seq_number) + 1;
+ if (tcp_state == 0 && (flags & 0xff) == TCP_FLAG_SYN) {
+ ack_no = recv_seq + 1;
seq_no = 1000;
tcp_send_packet(dst, ntohs(packet->dst_port), ntohs(packet->src_port),
TCP_FLAG_SYN | TCP_FLAG_ACK, NULL, 0);
- } else if (flags & TCP_FLAG_FIN) {
- print("Finished, closing socket\n");
- /* ack_no = ntohl(packet->seq_number) + 1; */
- /* tcp_send_packet(dst, ntohs(packet->dst_port), ntohs(packet->src_port), */
- /* TCP_FLAG_ACK | TCP_FLAG_FIN, NULL, 0); */
- } else if (flags & TCP_FLAG_ACK) {
- print("ACK, sending back\n");
- ack_no += 1;
- seq_no += 1;
+ tcp_state++;
+ return;
+ } else if (tcp_state == 1 && (flags & 0xff) == TCP_FLAG_ACK) {
+ /* assert(recv_ack == seq_no + 1); */
+
+ tcp_state++;
+ return;
+ } else if (tcp_state == 2 && (flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_PSH)) {
+ /* assert(recv_ack == seq_no + 1); */
+
+ /* for (u32 i = 0; i < data_length; ++i) { */
+ /* if (packet->data[i]) */
+ /* printf("%c", packet->data[i]); */
+ /* } */
+
+ ack_no += data_length;
+ seq_no++;
+
tcp_send_packet(dst, ntohs(packet->dst_port), ntohs(packet->src_port), TCP_FLAG_ACK,
NULL, 0);
tcp_send_packet(dst, ntohs(packet->dst_port), ntohs(packet->src_port),
- TCP_FLAG_PSH | TCP_FLAG_ACK, NULL, 42);
+ TCP_FLAG_PSH | TCP_FLAG_ACK, strdup(test_http), strlen(test_http));
+ return;
+ } else if (tcp_state == 2 && (flags & 0xff) == (TCP_FLAG_ACK)) {
+ ack_no = recv_seq + 1;
+ seq_no = recv_ack;
+
+ tcp_state = 3;
+ return;
+ } else if (tcp_state == 3 && (flags & 0xff) == (TCP_FLAG_ACK | TCP_FLAG_FIN)) {
+ ack_no = recv_seq + 1;
+ seq_no = recv_ack;
+
+ tcp_send_packet(dst, ntohs(packet->dst_port), ntohs(packet->src_port),
+ TCP_FLAG_FIN | TCP_FLAG_ACK, NULL, 0);
+
+ tcp_state = 0;
+ return;
}
}
@@ -333,6 +354,7 @@ void udp_handle_packet(struct udp_packet *packet)
void ip_handle_packet(struct ip_packet *packet, int len)
{
+ (void)len;
switch (packet->protocol) {
case IP_PROT_ICMP:
print("ICMP Packet!\n");
@@ -340,7 +362,8 @@ void ip_handle_packet(struct ip_packet *packet, int len)
break;
case IP_PROT_TCP:
print("TCP Packet!\n");
- tcp_handle_packet((struct tcp_packet *)packet->data, packet->src, len);
+ tcp_handle_packet((struct tcp_packet *)packet->data, packet->src,
+ ntohs(packet->length) - sizeof(*packet));
break;
case IP_PROT_UDP:
print("UDP Packet!\n");
@@ -365,10 +388,12 @@ void arp_handle_packet(struct arp_packet *packet, int len)
print("Returning ARP request\n");
arp_send_packet(dst_mac, dst_protocol_addr, ARP_REPLY);
}
+ return;
} else if (ntohs(packet->opcode) == ARP_REPLY) {
print("Got ARP reply\n");
} else {
printf("Got unknown ARP, opcode = %d\n", packet->opcode);
+ return;
}
// Store