Bladeren bron

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

Added a simple /bin/ifconfig program that just pretty-prints that file. :^)
Andreas Kling 6 jaren geleden
bovenliggende
commit
9e0f7acfe5

+ 16 - 0
Kernel/FileSystem/ProcFS.cpp

@@ -9,6 +9,7 @@
 #include <Kernel/FileSystem/Custody.h>
 #include <Kernel/FileSystem/FileDescription.h>
 #include <Kernel/FileSystem/VirtualFileSystem.h>
+#include <Kernel/Net/NetworkAdapter.h>
 #include <Kernel/PCI.h>
 #include <Kernel/VM/MemoryManager.h>
 #include <Kernel/kmalloc.h>
@@ -40,6 +41,7 @@ enum ProcFileType {
     FI_Root_dmesg,
     FI_Root_pci,
     FI_Root_uptime,
+    FI_Root_netadapters,
     FI_Root_self, // symlink
     FI_Root_sys,  // directory
     __FI_Root_End,
@@ -251,6 +253,19 @@ ByteBuffer procfs$uptime(InodeIdentifier)
     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)
 {
     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_pci] = { "pci", FI_Root_pci, procfs$pci };
     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_PID_vm] = { "vm", FI_PID_vm, procfs$pid_vm };

+ 3 - 0
Kernel/Net/E1000NetworkAdapter.cpp

@@ -107,6 +107,9 @@ E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, byte irq)
     , m_pci_address(pci_address)
 {
     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());
 
     enable_bus_mastering(m_pci_address);

+ 1 - 0
Kernel/Net/LoopbackAdapter.cpp

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

+ 13 - 0
Kernel/Net/NetworkAdapter.cpp

@@ -14,6 +14,13 @@ static Lockable<HashTable<NetworkAdapter*>>& all_adapters()
     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)
 {
     LOCKER(all_adapters().lock());
@@ -90,6 +97,12 @@ void NetworkAdapter::set_ipv4_address(const IPv4Address& 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
 {
     return m_adapter.has_queued_packets();

+ 6 - 0
Kernel/Net/NetworkAdapter.h

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

+ 30 - 0
Userland/ifconfig.cpp

@@ -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;
+}