diff options
author | Anton Kling <anton@kling.gg> | 2023-11-22 21:58:30 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-11-22 21:58:30 +0100 |
commit | ec91e81a4fcfd7ee6bc4150f06d8740e82f808da (patch) | |
tree | 6cad6ef6dc775d56758bc4da4a2bddd13cdec35f /kernel | |
parent | 90e4da9473ee2fc6419b7821274ec102219551f9 (diff) |
Networking: Split network packets if they are too large
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/drivers/rtl8139.c | 11 | ||||
-rw-r--r-- | kernel/drivers/rtl8139.h | 2 | ||||
-rw-r--r-- | kernel/network/ethernet.c | 3 | ||||
-rw-r--r-- | kernel/network/tcp.c | 6 |
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; |