1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 22:57:35 +00:00

Kernel+Userland: Expose list of network adapters through /proc/netadapters.

Added a simple /bin/ifconfig program that just pretty-prints that file. :^)
This commit is contained in:
Andreas Kling 2019-06-16 07:06:49 +02:00
parent 264890bfc3
commit 9e0f7acfe5
6 changed files with 69 additions and 0 deletions

View file

@ -9,6 +9,7 @@
#include <Kernel/FileSystem/Custody.h> #include <Kernel/FileSystem/Custody.h>
#include <Kernel/FileSystem/FileDescription.h> #include <Kernel/FileSystem/FileDescription.h>
#include <Kernel/FileSystem/VirtualFileSystem.h> #include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/Net/NetworkAdapter.h>
#include <Kernel/PCI.h> #include <Kernel/PCI.h>
#include <Kernel/VM/MemoryManager.h> #include <Kernel/VM/MemoryManager.h>
#include <Kernel/kmalloc.h> #include <Kernel/kmalloc.h>
@ -40,6 +41,7 @@ enum ProcFileType {
FI_Root_dmesg, FI_Root_dmesg,
FI_Root_pci, FI_Root_pci,
FI_Root_uptime, FI_Root_uptime,
FI_Root_netadapters,
FI_Root_self, // symlink FI_Root_self, // symlink
FI_Root_sys, // directory FI_Root_sys, // directory
__FI_Root_End, __FI_Root_End,
@ -251,6 +253,19 @@ ByteBuffer procfs$uptime(InodeIdentifier)
return builder.to_byte_buffer(); return builder.to_byte_buffer();
} }
ByteBuffer procfs$netadapters(InodeIdentifier)
{
StringBuilder builder;
NetworkAdapter::for_each([&builder](auto& adapter) {
builder.appendf("%s,%s,%s,%s\n",
adapter.name().characters(),
adapter.class_name(),
adapter.mac_address().to_string().characters(),
adapter.ipv4_address().to_string().characters());
});
return builder.to_byte_buffer();
}
ByteBuffer procfs$pid_vmo(InodeIdentifier identifier) ByteBuffer procfs$pid_vmo(InodeIdentifier identifier)
{ {
auto handle = ProcessInspectionHandle::from_pid(to_pid(identifier)); auto handle = ProcessInspectionHandle::from_pid(to_pid(identifier));
@ -1098,6 +1113,7 @@ ProcFS::ProcFS()
m_entries[FI_Root_self] = { "self", FI_Root_self, procfs$self }; m_entries[FI_Root_self] = { "self", FI_Root_self, procfs$self };
m_entries[FI_Root_pci] = { "pci", FI_Root_pci, procfs$pci }; m_entries[FI_Root_pci] = { "pci", FI_Root_pci, procfs$pci };
m_entries[FI_Root_uptime] = { "uptime", FI_Root_uptime, procfs$uptime }; m_entries[FI_Root_uptime] = { "uptime", FI_Root_uptime, procfs$uptime };
m_entries[FI_Root_netadapters] = { "netadapters", FI_Root_netadapters, procfs$netadapters };
m_entries[FI_Root_sys] = { "sys", FI_Root_sys }; m_entries[FI_Root_sys] = { "sys", FI_Root_sys };
m_entries[FI_PID_vm] = { "vm", FI_PID_vm, procfs$pid_vm }; m_entries[FI_PID_vm] = { "vm", FI_PID_vm, procfs$pid_vm };

View file

@ -107,6 +107,9 @@ E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, byte irq)
, m_pci_address(pci_address) , m_pci_address(pci_address)
{ {
s_the = this; s_the = this;
set_interface_name("e1k");
kprintf("E1000: Found at PCI address %b:%b:%b\n", pci_address.bus(), pci_address.slot(), pci_address.function()); kprintf("E1000: Found at PCI address %b:%b:%b\n", pci_address.bus(), pci_address.slot(), pci_address.function());
enable_bus_mastering(m_pci_address); enable_bus_mastering(m_pci_address);

View file

@ -10,6 +10,7 @@ LoopbackAdapter& LoopbackAdapter::the()
LoopbackAdapter::LoopbackAdapter() LoopbackAdapter::LoopbackAdapter()
{ {
set_interface_name("loop");
set_ipv4_address({ 127, 0, 0, 1 }); set_ipv4_address({ 127, 0, 0, 1 });
} }

View file

@ -14,6 +14,13 @@ static Lockable<HashTable<NetworkAdapter*>>& all_adapters()
return *table; return *table;
} }
void NetworkAdapter::for_each(Function<void(NetworkAdapter&)> callback)
{
LOCKER(all_adapters().lock());
for (auto& it : all_adapters().resource())
callback(*it);
}
NetworkAdapter* NetworkAdapter::from_ipv4_address(const IPv4Address& address) NetworkAdapter* NetworkAdapter::from_ipv4_address(const IPv4Address& address)
{ {
LOCKER(all_adapters().lock()); LOCKER(all_adapters().lock());
@ -90,6 +97,12 @@ void NetworkAdapter::set_ipv4_address(const IPv4Address& address)
m_ipv4_address = address; m_ipv4_address = address;
} }
void NetworkAdapter::set_interface_name(const StringView& basename)
{
// FIXME: Find a unique name for this interface, starting with $basename.
m_name = String::format("%s0", basename.characters());
}
bool PacketQueueAlarm::is_ringing() const bool PacketQueueAlarm::is_ringing() const
{ {
return m_adapter.has_queued_packets(); return m_adapter.has_queued_packets();

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <AK/ByteBuffer.h> #include <AK/ByteBuffer.h>
#include <AK/Function.h>
#include <AK/SinglyLinkedList.h> #include <AK/SinglyLinkedList.h>
#include <AK/Types.h> #include <AK/Types.h>
#include <Kernel/Alarm.h> #include <Kernel/Alarm.h>
@ -26,10 +27,13 @@ private:
class NetworkAdapter { class NetworkAdapter {
public: public:
static void for_each(Function<void(NetworkAdapter&)>);
static NetworkAdapter* from_ipv4_address(const IPv4Address&); static NetworkAdapter* from_ipv4_address(const IPv4Address&);
virtual ~NetworkAdapter(); virtual ~NetworkAdapter();
virtual const char* class_name() const = 0; virtual const char* class_name() const = 0;
const String& name() const { return m_name; }
MACAddress mac_address() { return m_mac_address; } MACAddress mac_address() { return m_mac_address; }
IPv4Address ipv4_address() const { return m_ipv4_address; } IPv4Address ipv4_address() const { return m_ipv4_address; }
@ -46,6 +50,7 @@ public:
protected: protected:
NetworkAdapter(); NetworkAdapter();
void set_interface_name(const StringView& basename);
void set_mac_address(const MACAddress& mac_address) { m_mac_address = mac_address; } void set_mac_address(const MACAddress& mac_address) { m_mac_address = mac_address; }
virtual void send_raw(const byte*, int) = 0; virtual void send_raw(const byte*, int) = 0;
void did_receive(const byte*, int); void did_receive(const byte*, int);
@ -55,4 +60,5 @@ private:
IPv4Address m_ipv4_address; IPv4Address m_ipv4_address;
PacketQueueAlarm m_packet_queue_alarm; PacketQueueAlarm m_packet_queue_alarm;
SinglyLinkedList<ByteBuffer> m_packet_queue; SinglyLinkedList<ByteBuffer> m_packet_queue;
String m_name;
}; };

30
Userland/ifconfig.cpp Normal file
View file

@ -0,0 +1,30 @@
#include <LibCore/CFile.h>
#include <stdio.h>
int main(int argc, char** argv)
{
UNUSED_PARAM(argc);
UNUSED_PARAM(argv);
CFile file("/proc/netadapters");
if (!file.open(CIODevice::ReadOnly)) {
fprintf(stderr, "Error: %s\n", file.error_string());
return 1;
}
for (;;) {
auto line = file.read_line(1024);
if (line.is_null())
break;
auto parts = String::copy(line, Chomp).split(',');
if (parts.size() < 4)
continue;
printf("%s:\n", parts[0].characters());
printf(" mac: %s\n", parts[2].characters());
printf(" ipv4: %s\n", parts[3].characters());
printf(" class: %s\n", parts[1].characters());
printf("\n");
}
return 0;
}