summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-12 04:39:50 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-12 04:40:13 +0100
commit75e0ddd46a35f4824b12e4a4713e03314318169b (patch)
tree38147808a46c7904cbc877daa1942ecc44fc399d /Kernel
parent5bd9844dd61d61bc224e5c8d76fd916dd87b9b30 (diff)
downloadserenity-75e0ddd46a35f4824b12e4a4713e03314318169b.zip
Kernel: More work on ICMP support.
We can now kinda sorta respond to ICMP::EchoRequest although there's still something not entirely right with the packets.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/ICMP.h17
-rw-r--r--Kernel/IPv4Packet.h5
-rw-r--r--Kernel/NetworkTask.cpp9
3 files changed, 13 insertions, 18 deletions
diff --git a/Kernel/ICMP.h b/Kernel/ICMP.h
index 0e21b58b5d..6155d431ed 100644
--- a/Kernel/ICMP.h
+++ b/Kernel/ICMP.h
@@ -25,27 +25,22 @@ public:
word checksum() const { return ntohs(m_checksum); }
void set_checksum(word w) { m_checksum = htons(w); }
- const void* payload() const { return &m_payload[0]; }
- void* payload() { return &m_payload[0]; }
+ const void* payload() const { return this + 1; }
+ void* payload() { return this + 1; }
private:
byte m_type { 0 };
byte m_code { 0 };
word m_checksum { 0 };
- dword m_rest_of_header { 0 };
- byte m_payload[0];
+ // NOTE: The rest of the header is 4 bytes
};
-static_assert(sizeof(ICMPHeader) == 8);
-
-struct [[gnu::packed]] IPv4ICMPPacket {
- IPv4Packet ipv4_packet;
- ICMPHeader icmp_header;
-};
+static_assert(sizeof(ICMPHeader) == 4);
struct [[gnu::packed]] ICMPEchoPacket {
ICMPHeader header;
NetworkOrdered<word> identifier;
NetworkOrdered<word> sequence_number;
- byte payload[];
+ void* payload() { return this + 1; }
+ const void* payload() const { return this + 1; }
};
diff --git a/Kernel/IPv4Packet.h b/Kernel/IPv4Packet.h
index 2ff5769002..ae7df3e415 100644
--- a/Kernel/IPv4Packet.h
+++ b/Kernel/IPv4Packet.h
@@ -38,8 +38,8 @@ public:
const IPv4Address& destination() const { return m_destination; }
void set_destination(const IPv4Address& address) { m_destination = address; }
- void* payload() { return m_payload; }
- const void* payload() const { return m_payload; }
+ void* payload() { return this + 1; }
+ const void* payload() const { return this + 1; }
private:
byte m_version_and_ihl;
@@ -52,7 +52,6 @@ private:
word m_checksum;
IPv4Address m_source;
IPv4Address m_destination;
- byte m_payload[0];
};
static_assert(sizeof(IPv4Packet) == 20);
diff --git a/Kernel/NetworkTask.cpp b/Kernel/NetworkTask.cpp
index 41a2d08ca7..6718254a38 100644
--- a/Kernel/NetworkTask.cpp
+++ b/Kernel/NetworkTask.cpp
@@ -156,6 +156,7 @@ void handle_ipv4(const EthernetFrameHeader& eth, int frame_size)
void handle_icmp(const EthernetFrameHeader& eth, int frame_size)
{
+ (void)frame_size;
auto& ipv4_packet = *static_cast<const IPv4Packet*>(eth.payload());
auto& icmp_header = *static_cast<const ICMPHeader*>(ipv4_packet.payload());
kprintf("handle_icmp: type=%b, code=%b\n", icmp_header.type(), icmp_header.code());
@@ -165,7 +166,7 @@ void handle_icmp(const EthernetFrameHeader& eth, int frame_size)
// It's for me!
if (icmp_header.type() == ICMPType::EchoRequest) {
auto& request = reinterpret_cast<const ICMPEchoPacket&>(icmp_header);
- kprintf("ICMP echo request: id=%u, seq=%u\n", (int)request.identifier, (int)request.sequence_number);
+ kprintf("ICMP echo request: id=%u, seq=%u, len=%u\n", (int)request.identifier, (int)request.sequence_number, ipv4_packet.length() - sizeof(ICMPEchoPacket));
byte* response_buffer = (byte*)kmalloc(ipv4_packet.length());
memset(response_buffer, 0, ipv4_packet.length());
struct [[gnu::packed]] EchoResponse {
@@ -178,13 +179,13 @@ void handle_icmp(const EthernetFrameHeader& eth, int frame_size)
response.ipv4.set_source(e1000.ipv4_address());
response.ipv4.set_destination(ipv4_packet.source());
response.ipv4.set_protocol(IPv4Protocol::ICMP);
- response.ipv4.set_length(sizeof(IPv4ICMPPacket));
+ response.ipv4.set_length(ipv4_packet.length());
response.icmp_echo.header.set_type(ICMPType::EchoReply);
response.icmp_echo.header.set_code(0);
response.icmp_echo.identifier = request.identifier;
response.icmp_echo.sequence_number = request.sequence_number;
- memcpy(response.icmp_echo.payload, request.payload, ipv4_packet.length() - sizeof(ICMPEchoPacket));
- e1000.send_ipv4(eth.source(), &response, ipv4_packet.length());
+ memcpy(response.icmp_echo.payload(), request.payload(), ipv4_packet.length() - sizeof(EchoResponse));
+ e1000.send_ipv4(eth.source(), response_buffer, ipv4_packet.length());
kfree(response_buffer);
}
}