summaryrefslogtreecommitdiff
path: root/Kernel/NetworkAdapter.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-12 12:43:30 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-12 12:43:30 +0100
commit87ecf290f471b9624a00442958a4cd74eead4dc8 (patch)
treeab8e1487c1685b557f526b00b162b8988f0d020a /Kernel/NetworkAdapter.cpp
parent9858be636f4f3ad94b0551cf840adb7dd0d5538f (diff)
downloadserenity-87ecf290f471b9624a00442958a4cd74eead4dc8.zip
Kernel: More work on the ICMP and IPv4 support.
Diffstat (limited to 'Kernel/NetworkAdapter.cpp')
-rw-r--r--Kernel/NetworkAdapter.cpp29
1 files changed, 19 insertions, 10 deletions
diff --git a/Kernel/NetworkAdapter.cpp b/Kernel/NetworkAdapter.cpp
index 260cee7b19..8a2aa25a74 100644
--- a/Kernel/NetworkAdapter.cpp
+++ b/Kernel/NetworkAdapter.cpp
@@ -24,19 +24,28 @@ void NetworkAdapter::send(const MACAddress& destination, const ARPPacket& packet
kfree(eth);
}
-void NetworkAdapter::send_ipv4(const MACAddress& destination, const void* packet, size_t packet_size)
+void NetworkAdapter::send_ipv4(const MACAddress& destination_mac, const IPv4Address& destination_ipv4, IPv4Protocol protocol, ByteBuffer&& payload)
{
- size_t size_in_bytes = sizeof(EthernetFrameHeader) + packet_size;
- auto* eth = (EthernetFrameHeader*)kmalloc(size_in_bytes);
- eth->set_source(mac_address());
- eth->set_destination(destination);
- eth->set_ether_type(EtherType::IPv4);
- memcpy(eth->payload(), packet, packet_size);
- send_raw((byte*)eth, size_in_bytes);
- kfree(eth);
+ size_t size_in_bytes = sizeof(EthernetFrameHeader) + sizeof(IPv4Packet) + payload.size();
+ auto buffer = ByteBuffer::create_zeroed(size_in_bytes);
+ auto& eth = *(EthernetFrameHeader*)buffer.pointer();
+ eth.set_source(mac_address());
+ eth.set_destination(destination_mac);
+ eth.set_ether_type(EtherType::IPv4);
+ auto& ipv4 = *(IPv4Packet*)eth.payload();
+ ipv4.set_version(4);
+ ipv4.set_internet_header_length(5);
+ ipv4.set_source(ipv4_address());
+ ipv4.set_destination(destination_ipv4);
+ ipv4.set_protocol((byte)protocol);
+ ipv4.set_length(sizeof(IPv4Packet) + payload.size());
+ ipv4.set_ident(1);
+ ipv4.set_ttl(64);
+ ipv4.set_checksum(ipv4.compute_checksum());
+ memcpy(ipv4.payload(), payload.pointer(), payload.size());
+ send_raw((const byte*)&eth, size_in_bytes);
}
-
void NetworkAdapter::did_receive(const byte* data, int length)
{
InterruptDisabler disabler;