Skip to content

Commit

Permalink
Merge pull request #1716 from caseywilliams/FACT-1851/systemd-network…
Browse files Browse the repository at this point in the history
…d-dhcp

(FACT-1851) Gather DHCP lease data under systemd-networkd
  • Loading branch information
Branan Riley committed May 8, 2018
2 parents 53b505e + d467663 commit b247279
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
2 changes: 2 additions & 0 deletions lib/inc/internal/facts/bsd/networking_resolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ namespace facter { namespace facts { namespace bsd {
virtual std::string find_dhcp_server(std::string const& interface) const;

private:
void find_dhclient_dhcp_servers(std::map<std::string, std::string>& servers) const;
void find_networkd_dhcp_servers(std::map<std::string, std::string>& servers) const;
void populate_binding(interface& iface, ifaddrs const* addr) const;
void populate_mtu(interface& iface, ifaddrs const* addr) const;
};
Expand Down
64 changes: 60 additions & 4 deletions lib/src/facts/bsd/networking_resolver.cc
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
#include <facter/util/string.hpp>
#include <internal/facts/bsd/networking_resolver.hpp>
#include <internal/util/bsd/scoped_ifaddrs.hpp>
#include <leatherman/execution/execution.hpp>
#include <leatherman/file_util/file.hpp>
#include <leatherman/file_util/directory.hpp>
#include <leatherman/logging/logging.hpp>
#include <leatherman/util/regex.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <netinet/in.h>
#include <unordered_map>

using namespace std;
using namespace facter::util::bsd;
using namespace leatherman::execution;
using namespace leatherman::util;
using facter::util::maybe_stoi;

namespace lth_file = leatherman::file_util;

Expand Down Expand Up @@ -117,11 +123,8 @@ namespace facter { namespace facts { namespace bsd {
// that has a non-loopback address
return {};
}

map<string, string> networking_resolver::find_dhcp_servers() const
void networking_resolver::find_dhclient_dhcp_servers(std::map<std::string, std::string>& servers) const
{
map<string, string> servers;

static vector<string> const dhclient_search_directories = {
"/var/lib/dhclient",
"/var/lib/dhcp",
Expand Down Expand Up @@ -153,6 +156,59 @@ namespace facter { namespace facts { namespace bsd {
return true;
}, "^dhclient.*lease.*$");
}
}

void networking_resolver::find_networkd_dhcp_servers(std::map<std::string, std::string>& servers) const
{
// Files in this lease directory are not part of systemd's public API,
// and they include warnings against parsing them, but they seem to be
// the only way to get this information for now.
// Each file is named after the interface's index number.
static const string networkd_lease_directory = "/run/systemd/netif/leases/";

if (!boost::filesystem::is_directory(networkd_lease_directory)) return;

static boost::regex ip_link_re("^(\\d+):\\s+([^:]+)");
unordered_map<int, string> iface_index_names;
string key, value;

// Gather a map of interface indices and their interface names from `ip link show` --
// Only the index is known in the lease files.
each_line("ip", {"link", "show"}, [&](string line) {
if (re_search(line, ip_link_re, &key, &value)) {
iface_index_names.insert(make_pair(stoi(key), value));
}
return true;
});

LOG_DEBUG("searching \"{1}\" for systemd-networkd DHCP lease files", networkd_lease_directory);

lth_file::each_file(networkd_lease_directory, [&](string const& path) {
LOG_DEBUG("searching \"{1}\" for systemd-networkd DHCP lease information", path);
string server_address;

static boost::regex server_address_re("^SERVER_ADDRESS=(.*)$");
lth_file::each_line(path, [&](string& line) {
boost::trim(line);
if (re_search(line, server_address_re, &server_address)) {
boost::filesystem::path p {path};
auto iface_index = maybe_stoi(p.filename().string());
if (!iface_index) return true;
servers.emplace(make_pair(iface_index_names[iface_index.get()], server_address));
}
return true;
});
return true;
});
}

map<string, string> networking_resolver::find_dhcp_servers() const
{
map<string, string> servers;

find_networkd_dhcp_servers(servers);
if (servers.empty()) find_dhclient_dhcp_servers(servers);

return servers;
}

Expand Down

0 comments on commit b247279

Please sign in to comment.