From f18beba3cb3d85ed6e0f44fdff9256c50adcc5e1 Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Sun, 6 Oct 2024 11:12:16 +0200 Subject: Kernel/Networking: Modify outgoing packet in place This avoids creation of new buffers and unnecessary memcpys. The old interface still exists for UDP but will be removed when I am less lazy. From testing it does not appear to have any performance improvement but this is most likely due to other bottlenecks as extra copies should always be worse. --- kernel/network/ipv4.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'kernel/network/ipv4.c') diff --git a/kernel/network/ipv4.c b/kernel/network/ipv4.c index 6074141..de6984a 100644 --- a/kernel/network/ipv4.c +++ b/kernel/network/ipv4.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -26,6 +27,37 @@ static u16 ip_checksum(const u16 *data, u16 length) { return htons(~acc); } +void send_ipv4_packet2(ipv4_t ip, u8 protocol, u16 length) { + u16 header[10]; + header[0] = (4 /*version*/ << 4) | (5 /*IHL*/); + + header[1] = htons(length + 20); + + header[2] = 0; + + header[3] = 0; + header[4] = (protocol << 8) | 0xF8; + + header[5] = 0; + header[6] = (ip_address.d >> 0) & 0xFFFF; + header[7] = (ip_address.d >> 16) & 0xFFFF; + + header[8] = (ip.d >> 0) & 0xFFFF; + header[9] = (ip.d >> 16) & 0xFFFF; + + header[5] = ip_checksum(header, 20); + u16 packet_length = length + 20; + // TODO + // assert(packet_length < sizeof(ipv4_buffer)); + u8 *packet = nic_get_buffer() + sizeof(struct EthernetHeader); + memcpy(packet, header, 20); + + u8 mac[6]; + for (; !get_mac_from_ip(ip, mac);) + ; + send_ethernet_packet2(mac, 0x0800, packet_length); +} + u8 ipv4_buffer[0x1000]; void send_ipv4_packet(ipv4_t ip, u8 protocol, const u8 *payload, u16 length) { u16 header[10]; -- cgit v1.2.3