The Pedigree Project 0.1
ProcFs-resolver.cc
1/*
2 * Copyright (c) 2026, Pedigree Developers
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted.
6 */
7
8#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
9
10#include "pedigree/kernel/process/TerminationDeferral.h"
11#include "pedigree/kernel/utilities/utility.h"
12
13#include "ProcFs.h"
16
17namespace {
18class ResolverFile final : public File {
19 public:
20 ResolverFile(size_t inode, Filesystem* filesystem, File* parent)
21 : File(String("resolv.conf"), 0, 0, 0, inode, filesystem, 0, parent) {
22 setPermissionsOnly(FILE_UR | FILE_GR | FILE_OR);
23 setUidOnly(0);
24 setGidOnly(0);
25 }
26
27 uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer,
28 bool bCanBlock = true) override {
29 if (!size)
30 return 0;
31 const String contents = generateString();
32 if (location >= contents.length())
33 return 0;
34 const uint64_t remaining = contents.length() - location;
35 if (size > remaining)
36 size = remaining;
37 MemoryCopy(reinterpret_cast<void*>(buffer), contents.cstr() + location, size);
38 return size;
39 }
40
41 uint64_t writeBytewise(uint64_t, uint64_t, uintptr_t, bool = true) override {
42 return 0;
43 }
44
45 size_t getSize() override {
46 return generateString().length();
47 }
48
49 private:
50 bool isBytewise() const override {
51 return true;
52 }
53
54 static String generateString() {
55 String contents;
56#if LWIP_DNS
57 TerminationDeferral lifetime;
58 ip_addr_t servers[DNS_MAX_SERVERS] = {};
59 // DHCP updates this table on the TCP/IP thread. Copy there so formatting
60 // never retains pointers into resolver state after the callback completes.
61 const auto snapshot = [](void* context) {
62 auto* addresses = static_cast<ip_addr_t*>(context);
63 for (size_t i = 0; i < DNS_MAX_SERVERS; ++i)
64 addresses[i] = *dns_getserver(static_cast<u8_t>(i));
65 };
66 if (tcpip_callback_wait(snapshot, servers) != ERR_OK)
67 return contents;
68
69 for (const auto& server : servers) {
70 if (ip_addr_isany(&server))
71 continue;
72 char address[IPADDR_STRLEN_MAX];
73 if (!ipaddr_ntoa_r(&server, address, sizeof(address)))
74 continue;
75 contents += "nameserver ";
76 contents += address;
77 contents += "\n";
78 }
79#endif
80 return contents;
81 }
82};
83} // namespace
84
85void ProcFs::initialiseResolverFile() {
86 auto* resolver = new ResolverFile(getNextInode(), this, m_pRoot);
87 m_pRoot->addEntry(resolver->getName(), resolver);
88}
Definition File.h:75
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
Definition File.cc:1369
virtual bool isBytewise() const
Definition File.cc:1365
void setGidOnly(size_t gid)
Definition File.cc:1448
void setPermissionsOnly(uint32_t perms)
Definition File.cc:1440
void setUidOnly(size_t uid)
Definition File.cc:1444
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
Definition File.cc:1376
@ ERR_OK
Definition err.h:82
#define DNS_MAX_SERVERS
Definition opt.h:1048
err_t tcpip_callback_wait(tcpip_callback_fn function, void *ctx)
Definition tcpip.c:365