From 98cbfa3561e708a3cde46dade0b2c610103b4daa Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Thu, 8 Jun 2023 17:38:16 +0200 Subject: [PATCH] genode_c_api: MAC address reporter utility Issue #4918 --- .../genode_c_api/mac_address_reporter.h | 43 ++++++ .../lib/genode_c_api/mac_address_reporter.cc | 132 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 repos/os/include/genode_c_api/mac_address_reporter.h create mode 100644 repos/os/src/lib/genode_c_api/mac_address_reporter.cc diff --git a/repos/os/include/genode_c_api/mac_address_reporter.h b/repos/os/include/genode_c_api/mac_address_reporter.h new file mode 100644 index 0000000000..592a3dfc4a --- /dev/null +++ b/repos/os/include/genode_c_api/mac_address_reporter.h @@ -0,0 +1,43 @@ +/* + * \brief C-API Genode MAC address reporter utility + * \author Christian Helmuth + * \date 2023-06-06 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _GENODE_C_API__MAC_ADDRESS_REPORTER_H_ +#define _GENODE_C_API__MAC_ADDRESS_REPORTER_H_ + +#include + + +#ifdef __cplusplus + +#include + +void genode_mac_address_reporter_init(Genode::Env &, Genode::Allocator &); + +void genode_mac_address_reporter_config(Genode::Xml_node const &); + +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +struct genode_mac_address { unsigned char addr[6]; }; + +void genode_mac_address_register(char const * name, struct genode_mac_address addr); + +#ifdef __cplusplus +} +#endif + +#endif /* _GENODE_C_API__MAC_ADDRESS_REPORTER_H_ */ diff --git a/repos/os/src/lib/genode_c_api/mac_address_reporter.cc b/repos/os/src/lib/genode_c_api/mac_address_reporter.cc new file mode 100644 index 0000000000..1d500c61a7 --- /dev/null +++ b/repos/os/src/lib/genode_c_api/mac_address_reporter.cc @@ -0,0 +1,132 @@ +/* + * \brief C-API Genode MAC address reporter utility + * \author Christian Helmuth + * \date 2023-06-06 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include +#include +#include + +#include + +using namespace Genode; + +typedef String<32> Mac_name; + +struct Mac_address : Registry::Element +{ + Mac_name name; + Net::Mac_address addr; + + Mac_address(Registry ®istry, + Mac_name const &name, + Net::Mac_address const &addr) + : + Registry::Element(registry, *this), + name(name), addr(addr) + { } + + void report(Xml_generator &report) const + { + report.node("nic", [&] () { + report.attribute("name", name); + report.attribute("mac_address", String<20>(addr)); + }); + } +}; + + +class Mac_address_registry +{ + private: + + Env &_env; + Allocator &_alloc; + + Registry _registry { }; + + Constructible _reporter { }; + + void _report(); + + public: + + Mac_address_registry(Env &env, Allocator &alloc) + : _env(env), _alloc(alloc) { } + + void apply_config(Xml_node const &config); + + void register_address(Mac_name const &name, Net::Mac_address const &addr); +}; + + +void Mac_address_registry::_report() +{ + if (!_reporter.constructed()) + return; + + _reporter->generate([&] (Reporter::Xml_generator &report) { + _registry.for_each([&] (Mac_address const &e) { + e.report(report); + }); + }); +} + + +void Mac_address_registry::register_address(Mac_name const &name, + Net::Mac_address const &addr) +{ + bool found = false; + _registry.for_each([&] (Mac_address const &e) { + if (e.addr == addr) + found = true; + }); + if (found) return; + + new (_alloc) Mac_address(_registry, name, addr); + + _report(); +} + + +void Mac_address_registry::apply_config(Xml_node const &config) +{ + config.with_optional_sub_node("report", [&] (Xml_node const &xml) { + if (xml.attribute_value("mac_address", false)) + _reporter.construct(_env, "devices", "devices"); + }); + + _report(); +} + + +static Mac_address_registry * _mac_registry = nullptr; + +void genode_mac_address_reporter_init(Env &env, Allocator &alloc) +{ + static Mac_address_registry registry { env, alloc }; + + _mac_registry = ®istry; +} + + +void genode_mac_address_reporter_config(Xml_node const &config) +{ + if (_mac_registry) + _mac_registry->apply_config(config); +} + + +extern "C" void genode_mac_address_register(char const *name, genode_mac_address addr) +{ + if (_mac_registry) + _mac_registry->register_address(Mac_name(name), addr.addr); +}