summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-11-22 21:58:30 +0100
committerAnton Kling <anton@kling.gg>2023-11-22 21:58:30 +0100
commitec91e81a4fcfd7ee6bc4150f06d8740e82f808da (patch)
tree6cad6ef6dc775d56758bc4da4a2bddd13cdec35f
parent90e4da9473ee2fc6419b7821274ec102219551f9 (diff)
Networking: Split network packets if they are too large
-rw-r--r--kernel/drivers/rtl8139.c11
-rw-r--r--kernel/drivers/rtl8139.h2
-rw-r--r--kernel/network/ethernet.c3
-rw-r--r--kernel/network/tcp.c6
4 files changed, 16 insertions, 6 deletions
diff --git a/kernel/drivers/rtl8139.c b/kernel/drivers/rtl8139.c
index 4b53ef4..dd81533 100644
--- a/kernel/drivers/rtl8139.c
+++ b/kernel/drivers/rtl8139.c
@@ -103,12 +103,16 @@ __attribute__((interrupt)) void rtl8139_handler(void *regs) {
EOI(0xB);
}
-int rtl8139_send_data(u8 *data, u16 data_size) {
+void rtl8139_send_data(u8 *data, u16 data_size) {
const struct PCI_DEVICE *device = &rtl8139;
// FIXME: It should block or fail if there is too little space for the
// buffer
- if (data_size > 0x1000)
- return 0;
+ if (data_size > 0x1000) {
+ rtl8139_send_data(data, 0x1000);
+ data += 0x1000;
+ data_size -= 0x1000;
+ return rtl8139_send_data(data, data_size);
+ }
if (send_buffers_loop > 3) {
send_buffers_loop = 0;
}
@@ -117,7 +121,6 @@ int rtl8139_send_data(u8 *data, u16 data_size) {
(u32)virtual_to_physical(send_buffers[send_buffers_loop], NULL));
outl(device->gen.base_mem_io + 0x10 + send_buffers_loop * 4, data_size);
send_buffers_loop += 1;
- return 1;
}
void get_mac_address(u8 mac[6]) {
diff --git a/kernel/drivers/rtl8139.h b/kernel/drivers/rtl8139.h
index 7cbca4b..c61e6de 100644
--- a/kernel/drivers/rtl8139.h
+++ b/kernel/drivers/rtl8139.h
@@ -1,4 +1,4 @@
#include <typedefs.h>
void get_mac_address(u8 mac[6]);
void rtl8139_init(void);
-int rtl8139_send_data(u8 *data, u16 data_size);
+void rtl8139_send_data(u8 *data, u16 data_size);
diff --git a/kernel/network/ethernet.c b/kernel/network/ethernet.c
index 6255ecb..940802f 100644
--- a/kernel/network/ethernet.c
+++ b/kernel/network/ethernet.c
@@ -67,6 +67,7 @@ void handle_ethernet(const u8 *packet, u64 packet_length) {
void send_ethernet_packet(u8 mac_dst[6], u16 type, u8 *payload,
u64 payload_length) {
+ assert(payload_length <= 1500);
// FIXME: Janky allocation, do this better
u64 buffer_size =
sizeof(struct ETHERNET_HEADER) + payload_length + sizeof(u32);
@@ -82,6 +83,6 @@ void send_ethernet_packet(u8 mac_dst[6], u16 type, u8 *payload,
eth_header->type = htons(type);
*(u32 *)(buffer) = htonl(crc32((const char *)buffer_start, buffer_size - 4));
- assert(rtl8139_send_data(buffer_start, buffer_size));
+ rtl8139_send_data(buffer_start, buffer_size);
kfree(buffer_start);
}
diff --git a/kernel/network/tcp.c b/kernel/network/tcp.c
index 14bd0cb..e4b0891 100644
--- a/kernel/network/tcp.c
+++ b/kernel/network/tcp.c
@@ -113,6 +113,12 @@ void tcp_close_connection(struct INCOMING_TCP_CONNECTION *inc) {
void send_tcp_packet(struct INCOMING_TCP_CONNECTION *inc, u8 *payload,
u16 payload_length) {
+ if (payload_length > 1500 - 20 - sizeof(struct TCP_HEADER)) {
+ send_tcp_packet(inc, payload, 1500 - 20 - sizeof(struct TCP_HEADER));
+ payload_length -= 1500 - 20 - sizeof(struct TCP_HEADER);
+ payload += 1500 - 20 - sizeof(struct TCP_HEADER);
+ return send_tcp_packet(inc, payload, payload_length);
+ }
struct TCP_HEADER header = {0};
header.src_port = htons(inc->dst_port);
header.dst_port = inc->n_port;