mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-26 14:28:49 +00:00
Kernel: Clean up and sanitize incoming packet handling a bit more
Once we've converted from an Ethernet frame to an IPv4 packet, we can pass the IPv4Packet around instead of the EthernetFrameHeader. Also add some more code to ignore invalid-looking packets.
This commit is contained in:
parent
f9de264f88
commit
7e309e27dd
Notes:
sideshowbarker
2024-07-19 12:48:07 +09:00
Author: https://github.com/awesomekling
Commit: 7e309e27dd
1 changed files with 39 additions and 25 deletions
|
@ -20,11 +20,11 @@
|
|||
//#define UDP_DEBUG
|
||||
//#define TCP_DEBUG
|
||||
|
||||
static void handle_arp(const EthernetFrameHeader&, int frame_size);
|
||||
static void handle_ipv4(const EthernetFrameHeader&, int frame_size);
|
||||
static void handle_icmp(const EthernetFrameHeader&, int frame_size);
|
||||
static void handle_udp(const EthernetFrameHeader&, int frame_size);
|
||||
static void handle_tcp(const EthernetFrameHeader&, int frame_size);
|
||||
static void handle_arp(const EthernetFrameHeader&, size_t frame_size);
|
||||
static void handle_ipv4(const EthernetFrameHeader&, size_t frame_size);
|
||||
static void handle_icmp(const EthernetFrameHeader&, const IPv4Packet&);
|
||||
static void handle_udp(const IPv4Packet&);
|
||||
static void handle_tcp(const IPv4Packet&);
|
||||
|
||||
Lockable<HashMap<IPv4Address, MACAddress>>& arp_table()
|
||||
{
|
||||
|
@ -118,9 +118,9 @@ void NetworkTask_main()
|
|||
}
|
||||
}
|
||||
|
||||
void handle_arp(const EthernetFrameHeader& eth, int frame_size)
|
||||
void handle_arp(const EthernetFrameHeader& eth, size_t frame_size)
|
||||
{
|
||||
constexpr int minimum_arp_frame_size = sizeof(EthernetFrameHeader) + sizeof(ARPPacket);
|
||||
constexpr size_t minimum_arp_frame_size = sizeof(EthernetFrameHeader) + sizeof(ARPPacket);
|
||||
if (frame_size < minimum_arp_frame_size) {
|
||||
kprintf("handle_arp: Frame too small (%d, need %d)\n", frame_size, minimum_arp_frame_size);
|
||||
return;
|
||||
|
@ -180,9 +180,9 @@ void handle_arp(const EthernetFrameHeader& eth, int frame_size)
|
|||
}
|
||||
}
|
||||
|
||||
void handle_ipv4(const EthernetFrameHeader& eth, int frame_size)
|
||||
void handle_ipv4(const EthernetFrameHeader& eth, size_t frame_size)
|
||||
{
|
||||
constexpr int minimum_ipv4_frame_size = sizeof(EthernetFrameHeader) + sizeof(IPv4Packet);
|
||||
constexpr size_t minimum_ipv4_frame_size = sizeof(EthernetFrameHeader) + sizeof(IPv4Packet);
|
||||
if (frame_size < minimum_ipv4_frame_size) {
|
||||
kprintf("handle_ipv4: Frame too small (%d, need %d)\n", frame_size, minimum_ipv4_frame_size);
|
||||
return;
|
||||
|
@ -208,21 +208,19 @@ void handle_ipv4(const EthernetFrameHeader& eth, int frame_size)
|
|||
|
||||
switch ((IPv4Protocol)packet.protocol()) {
|
||||
case IPv4Protocol::ICMP:
|
||||
return handle_icmp(eth, frame_size);
|
||||
return handle_icmp(eth, packet);
|
||||
case IPv4Protocol::UDP:
|
||||
return handle_udp(eth, frame_size);
|
||||
return handle_udp(packet);
|
||||
case IPv4Protocol::TCP:
|
||||
return handle_tcp(eth, frame_size);
|
||||
return handle_tcp(packet);
|
||||
default:
|
||||
kprintf("handle_ipv4: Unhandled protocol %u\n", packet.protocol());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_icmp(const EthernetFrameHeader& eth, int frame_size)
|
||||
void handle_icmp(const EthernetFrameHeader& eth, const IPv4Packet& ipv4_packet)
|
||||
{
|
||||
(void)frame_size;
|
||||
auto& ipv4_packet = *static_cast<const IPv4Packet*>(eth.payload());
|
||||
auto& icmp_header = *static_cast<const ICMPHeader*>(ipv4_packet.payload());
|
||||
#ifdef ICMP_DEBUG
|
||||
kprintf("handle_icmp: source=%s, destination=%s, type=%b, code=%b\n",
|
||||
|
@ -266,10 +264,12 @@ void handle_icmp(const EthernetFrameHeader& eth, int frame_size)
|
|||
}
|
||||
}
|
||||
|
||||
void handle_udp(const EthernetFrameHeader& eth, int frame_size)
|
||||
void handle_udp(const IPv4Packet& ipv4_packet)
|
||||
{
|
||||
(void)frame_size;
|
||||
auto& ipv4_packet = *static_cast<const IPv4Packet*>(eth.payload());
|
||||
if (ipv4_packet.payload_size() < sizeof(UDPPacket)) {
|
||||
kprintf("handle_udp: Packet too small (%u, need %zu)\n", ipv4_packet.payload_size());
|
||||
return;
|
||||
}
|
||||
|
||||
auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination());
|
||||
if (!adapter) {
|
||||
|
@ -298,18 +298,26 @@ void handle_udp(const EthernetFrameHeader& eth, int frame_size)
|
|||
socket->did_receive(ipv4_packet.source(), udp_packet.source_port(), KBuffer::copy(&ipv4_packet, sizeof(IPv4Packet) + ipv4_packet.payload_size()));
|
||||
}
|
||||
|
||||
void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
|
||||
void handle_tcp(const IPv4Packet& ipv4_packet)
|
||||
{
|
||||
(void)frame_size;
|
||||
auto& ipv4_packet = *static_cast<const IPv4Packet*>(eth.payload());
|
||||
|
||||
auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination());
|
||||
if (!adapter) {
|
||||
kprintf("handle_tcp: this packet is not for me, it's for %s\n", ipv4_packet.destination().to_string().characters());
|
||||
if (ipv4_packet.payload_size() < sizeof(TCPPacket)) {
|
||||
kprintf("handle_tcp: IPv4 payload is too small to be a TCP packet (%u, need %zu)\n", ipv4_packet.payload_size(), sizeof(TCPPacket));
|
||||
return;
|
||||
}
|
||||
|
||||
auto& tcp_packet = *static_cast<const TCPPacket*>(ipv4_packet.payload());
|
||||
|
||||
size_t minimum_tcp_header_size = 5 * sizeof(u32);
|
||||
size_t maximum_tcp_header_size = 15 * sizeof(u32);
|
||||
if (tcp_packet.header_size() < minimum_tcp_header_size || tcp_packet.header_size() > maximum_tcp_header_size) {
|
||||
kprintf("handle_tcp: TCP packet header has invalid size %zu\n", tcp_packet.header_size());
|
||||
}
|
||||
|
||||
if (ipv4_packet.payload_size() < tcp_packet.header_size()) {
|
||||
kprintf("handle_tcp: IPv4 payload is smaller than TCP header claims (%u, supposedly %u)\n", ipv4_packet.payload_size(), tcp_packet.header_size());
|
||||
return;
|
||||
}
|
||||
|
||||
size_t payload_size = ipv4_packet.payload_size() - tcp_packet.header_size();
|
||||
|
||||
#ifdef TCP_DEBUG
|
||||
|
@ -329,6 +337,12 @@ void handle_tcp(const EthernetFrameHeader& eth, int frame_size)
|
|||
payload_size);
|
||||
#endif
|
||||
|
||||
auto adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination());
|
||||
if (!adapter) {
|
||||
kprintf("handle_tcp: this packet is not for me, it's for %s\n", ipv4_packet.destination().to_string().characters());
|
||||
return;
|
||||
}
|
||||
|
||||
IPv4SocketTuple tuple(ipv4_packet.destination(), tcp_packet.destination_port(), ipv4_packet.source(), tcp_packet.source_port());
|
||||
|
||||
#ifdef TCP_DEBUG
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue