diff options
author | Anton Kling <anton@kling.gg> | 2024-10-06 11:12:16 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-10-06 11:12:16 +0200 |
commit | f18beba3cb3d85ed6e0f44fdff9256c50adcc5e1 (patch) | |
tree | 42e15026c9a0154269e5c7de71cd829866d6d564 /kernel/network/ipv4.c | |
parent | 6dc2637972f93dea8cc831d7ee225daefb74b8ab (diff) |
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.
Diffstat (limited to 'kernel/network/ipv4.c')
-rw-r--r-- | kernel/network/ipv4.c | 32 |
1 files changed, 32 insertions, 0 deletions
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 <assert.h> #include <drivers/pit.h> +#include <drivers/rtl8139.h> #include <kmalloc.h> #include <network/arp.h> #include <network/bytes.h> @@ -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]; |