mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
Kernel: Add a way to look up NetworkAdapters by IPv4 address.
This commit is contained in:
parent
c6a2012fe9
commit
8e667747f0
Notes:
sideshowbarker
2024-07-19 15:04:43 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/8e667747f0a
3 changed files with 36 additions and 13 deletions
|
@ -3,13 +3,39 @@
|
|||
#include <Kernel/EthernetFrameHeader.h>
|
||||
#include <Kernel/kmalloc.h>
|
||||
#include <Kernel/EtherType.h>
|
||||
#include <AK/HashTable.h>
|
||||
#include <AK/Lock.h>
|
||||
|
||||
static Lockable<HashTable<NetworkAdapter*>>& all_adapters()
|
||||
{
|
||||
static Lockable<HashTable<NetworkAdapter*>>* table;
|
||||
if (!table)
|
||||
table = new Lockable<HashTable<NetworkAdapter*>>;
|
||||
return *table;
|
||||
}
|
||||
|
||||
NetworkAdapter* NetworkAdapter::from_ipv4_address(const IPv4Address& address)
|
||||
{
|
||||
LOCKER(all_adapters().lock());
|
||||
for (auto* adapter : all_adapters().resource()) {
|
||||
if (adapter->ipv4_address() == address)
|
||||
return adapter;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NetworkAdapter::NetworkAdapter()
|
||||
{
|
||||
// FIXME: I wanna lock :(
|
||||
ASSERT_INTERRUPTS_DISABLED();
|
||||
all_adapters().resource().set(this);
|
||||
}
|
||||
|
||||
NetworkAdapter::~NetworkAdapter()
|
||||
{
|
||||
// FIXME: I wanna lock :(
|
||||
ASSERT_INTERRUPTS_DISABLED();
|
||||
all_adapters().resource().remove(this);
|
||||
}
|
||||
|
||||
void NetworkAdapter::send(const MACAddress& destination, const ARPPacket& packet)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
class NetworkAdapter {
|
||||
public:
|
||||
static NetworkAdapter* from_ipv4_address(const IPv4Address&);
|
||||
virtual ~NetworkAdapter();
|
||||
|
||||
virtual const char* class_name() const = 0;
|
||||
|
|
|
@ -33,7 +33,7 @@ void NetworkTask_main()
|
|||
for (;;) {
|
||||
auto packet = e1000.dequeue_packet();
|
||||
if (packet.is_null()) {
|
||||
sleep(1);
|
||||
sleep(100);
|
||||
continue;
|
||||
}
|
||||
if (packet.size() < (int)(sizeof(EthernetFrameHeader))) {
|
||||
|
@ -94,23 +94,20 @@ void handle_arp(const EthernetFrameHeader& eth, int frame_size)
|
|||
);
|
||||
#endif
|
||||
|
||||
// FIXME: Get the adapter through some kind of lookup by IPv4 address.
|
||||
auto& e1000 = *E1000NetworkAdapter::the();
|
||||
|
||||
if (packet.operation() == ARPOperation::Request) {
|
||||
// Who has this IP address?
|
||||
if (e1000.ipv4_address() == packet.target_protocol_address()) {
|
||||
if (auto* adapter = NetworkAdapter::from_ipv4_address(packet.target_protocol_address())) {
|
||||
// We do!
|
||||
kprintf("handle_arp: Responding to ARP request for my IPv4 address (%s)\n",
|
||||
e1000.ipv4_address().to_string().characters());
|
||||
adapter->ipv4_address().to_string().characters());
|
||||
ARPPacket response;
|
||||
response.set_operation(ARPOperation::Response);
|
||||
response.set_target_hardware_address(packet.sender_hardware_address());
|
||||
response.set_target_protocol_address(packet.sender_protocol_address());
|
||||
response.set_sender_hardware_address(e1000.mac_address());
|
||||
response.set_sender_protocol_address(e1000.ipv4_address());
|
||||
response.set_sender_hardware_address(adapter->mac_address());
|
||||
response.set_sender_protocol_address(adapter->ipv4_address());
|
||||
|
||||
e1000.send(packet.sender_hardware_address(), response);
|
||||
adapter->send(packet.sender_hardware_address(), response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -168,9 +165,8 @@ void handle_icmp(const EthernetFrameHeader& eth, int frame_size)
|
|||
);
|
||||
#endif
|
||||
|
||||
// FIXME: Get adapater via lookup.
|
||||
auto& adapter = *E1000NetworkAdapter::the();
|
||||
if (ipv4_packet.destination() != adapter.ipv4_address())
|
||||
auto* adapter = NetworkAdapter::from_ipv4_address(ipv4_packet.destination());
|
||||
if (!adapter)
|
||||
return;
|
||||
|
||||
if (icmp_header.type() == ICMPType::EchoRequest) {
|
||||
|
@ -190,6 +186,6 @@ void handle_icmp(const EthernetFrameHeader& eth, int frame_size)
|
|||
if (size_t icmp_payload_size = icmp_packet_size - sizeof(ICMPEchoPacket))
|
||||
memcpy(response.payload(), request.payload(), icmp_payload_size);
|
||||
response.header.set_checksum(internet_checksum(&response, icmp_packet_size));
|
||||
adapter.send_ipv4(eth.source(), ipv4_packet.source(), IPv4Protocol::ICMP, move(buffer));
|
||||
adapter->send_ipv4(eth.source(), ipv4_packet.source(), IPv4Protocol::ICMP, move(buffer));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue