2#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
4#include "pedigree/kernel/process/TerminationDeferral.h"
5#include "pedigree/kernel/process/Thread.h"
6#include "pedigree/kernel/processor/Processor.h"
7#include "pedigree/kernel/processor/ProcessorInformation.h"
8#include "pedigree/kernel/utilities/utility.h"
13#include "modules/system/network-stack/NetworkStack.h"
14#include "network-namespace.h"
17class NetworkFile final :
public File {
20 :
File(
String(
"interfaces"), 0, 0, 0, inode, filesystem, 0, parent) {
26 uint64_t
readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
bool =
true)
override {
29 const String contents = generateString();
30 if (location >= contents.length())
32 if (size > contents.length() - location)
33 size = contents.length() - location;
34 MemoryCopy(
reinterpret_cast<void*
>(buffer), contents.cstr() + location, size);
38 uint64_t
writeBytewise(uint64_t, uint64_t, uintptr_t,
bool =
true)
override {
42 size_t getSize()
override {
43 return generateString().length();
51 static String generateString() {
55 contents.Format(
"lo: %s, mtu 65536\n IPv4: %s Netmask: 255.0.0.0\n",
56 space->flags() & 1 ?
"up" :
"down",
57 space->address() ?
"127.0.0.1" :
"0.0.0.0");
60 auto* stack = NetworkStack::instanceIfAvailable();
62 return String(
"No network devices.\n");
65 for (
size_t index = 0;; ++index) {
67 if (!stack->acquireDevice(index, device))
71 struct netif* interface;
80 ip4_addr_t address, netmask, gateway;
84 snapshot.interface = device.interface();
88 const auto copy = [](
void* context) {
89 auto& result = *
static_cast<Snapshot*
>(context);
90 auto* iface = result.interface;
91 MemoryCopy(result.name, iface->name,
sizeof(result.name));
92 result.number = iface->num;
93 result.mtu = iface->mtu;
98 if (result.macLength >
sizeof(result.mac))
99 result.macLength =
sizeof(result.mac);
100 MemoryCopy(result.mac, iface->hwaddr, result.macLength);
101 result.address = *netif_ip4_addr(iface);
102 result.netmask = *netif_ip4_netmask(iface);
103 result.gateway = *netif_ip4_gw(iface);
105 result.ipv6[i] = *netif_ip6_addr(iface, i);
106 result.ipv6Valid[i] = ip6_addr_isvalid(netif_ip6_addr_state(iface, i));
110 contents +=
"Network status unavailable.\n";
115 line.Format(
"%c%c%u: %s, link flag %s, mtu %u%s\n", snapshot.name[0], snapshot.name[1],
116 snapshot.number, snapshot.up ?
"up" :
"down", snapshot.link ?
"up" :
"down",
117 snapshot.mtu, snapshot.defaultRoute ?
", default route" :
"");
120 device.device()->getName(name);
121 contents +=
" Device: ";
123 contents +=
"\n MAC:";
124 for (
unsigned i = 0; i < snapshot.macLength; ++i) {
125 line.Format(
"%s%02x", i ?
":" :
" ", snapshot.mac[i]);
129 char address[IP4ADDR_STRLEN_MAX], netmask[IP4ADDR_STRLEN_MAX], gateway[IP4ADDR_STRLEN_MAX];
130 ip4addr_ntoa_r(&snapshot.address, address,
sizeof(address));
131 ip4addr_ntoa_r(&snapshot.netmask, netmask,
sizeof(netmask));
132 ip4addr_ntoa_r(&snapshot.gateway, gateway,
sizeof(gateway));
133 line.Format(
" IPv4: %s Netmask: %s Gateway: %s\n", address, netmask, gateway);
136 if (!snapshot.ipv6Valid[i])
138 char ipv6[IP6ADDR_STRLEN_MAX];
139 if (ip6addr_ntoa_r(&snapshot.ipv6[i], ipv6,
sizeof(ipv6))) {
140 contents +=
" IPv6: ";
146 if (!contents.length())
147 contents =
String(
"No network devices.\n");
152class NetworkDevFile final :
public File {
154 NetworkDevFile(
size_t inode,
Filesystem* filesystem,
File* parent)
155 :
File(
String(
"dev"), 0, 0, 0, inode, filesystem, 0, parent) {
161 uint64_t
readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
bool =
true)
override {
162 String contents = generateString();
163 if (location >= contents.length())
165 size = min(size, contents.length() - location);
166 MemoryCopy(
reinterpret_cast<void*
>(buffer), contents.cstr() + location, size);
169 uint64_t
writeBytewise(uint64_t, uint64_t, uintptr_t,
bool =
true)
override {
172 size_t getSize()
override {
173 return generateString().length();
181 static String generateString() {
183 "Inter-| Receive | Transmit\n"
184 " face |bytes packets errs drop fifo frame compressed multicast|bytes packets "
185 "errs drop fifo colls carrier compressed\n");
187 contents +=
"lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
190 auto* stack = NetworkStack::instanceIfAvailable();
194 for (
size_t index = 0;; ++index) {
196 if (!stack->acquireDevice(index, device))
199 struct netif* interface;
202 } snapshot = {device.interface(), {}, 0};
203 const auto copy = [](
void* context) {
204 auto& result = *
static_cast<Snapshot*
>(context);
205 MemoryCopy(result.name, result.interface->name,
sizeof(result.name));
206 result.number = result.interface->num;
211 line.Format(
"%c%c%u: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n", snapshot.name[0], snapshot.name[1],
220void ProcFs::initialiseNetworkFile() {
222 directory->setPermissions(FILE_UR | FILE_UX | FILE_GR | FILE_GX | FILE_OR | FILE_OX);
223 m_pRoot->addEntry(directory->getName(), directory);
224 auto* interfaces =
new NetworkFile(getNextInode(),
this, directory);
225 directory->addEntry(interfaces->getName(), interfaces);
226 auto* devices =
new NetworkDevFile(getNextInode(),
this, directory);
227 directory->addEntry(devices->getName(), devices);
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual bool isBytewise() const
void setGidOnly(size_t gid)
void setPermissionsOnly(uint32_t perms)
void setUidOnly(size_t uid)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
static ProcessorInformation & information()
#define LWIP_IPV6_NUM_ADDRESSES
#define netif_is_up(netif)
struct netif * netif_default
#define netif_is_link_up(netif)
#define NETIF_MAX_HWADDR_LEN
err_t tcpip_callback_wait(tcpip_callback_fn function, void *ctx)