Skip to content

Commit

Permalink
Net interface supports filters
Browse files Browse the repository at this point in the history
  • Loading branch information
dtrugman committed Jan 1, 2024
1 parent 02c4c26 commit 6b8a234
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 54 deletions.
39 changes: 24 additions & 15 deletions include/pfs/net.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef PFS_NET_HPP
#define PFS_NET_HPP

#include <functional>
#include <string>
#include <vector>

Expand All @@ -41,31 +42,39 @@ class net final
net& operator=(net&&) = delete;

public:
std::vector<net_device> get_dev() const;
using net_device_filter = std::function<bool(const net_device&)>;
using net_socket_filter = std::function<bool(const net_socket&)>;
using netlink_socket_filter = std::function<bool(const netlink_socket&)>;
using unix_socket_filter = std::function<bool(const unix_socket&)>;
using net_route_filter = std::function<bool(const net_route&)>;

std::vector<net_socket> get_icmp() const;
std::vector<net_socket> get_icmp6() const;
std::vector<net_socket> get_raw() const;
std::vector<net_socket> get_raw6() const;
std::vector<net_socket> get_tcp() const;
std::vector<net_socket> get_tcp6() const;
std::vector<net_socket> get_udp() const;
std::vector<net_socket> get_udp6() const;
std::vector<net_socket> get_udplite() const;
std::vector<net_socket> get_udplite6() const;
public:
std::vector<net_device> get_dev(net_device_filter filter = nullptr) const;

std::vector<net_socket> get_icmp(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_icmp6(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_raw(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_raw6(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_tcp(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_tcp6(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_udp(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_udp6(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_udplite(net_socket_filter filter = nullptr) const;
std::vector<net_socket> get_udplite6(net_socket_filter filter = nullptr) const;

std::vector<netlink_socket> get_netlink() const;
std::vector<netlink_socket> get_netlink(netlink_socket_filter filter = nullptr) const;

std::vector<unix_socket> get_unix() const;
std::vector<unix_socket> get_unix(unix_socket_filter filter = nullptr) const;

std::vector<net_route> get_route() const;
std::vector<net_route> get_route(net_route_filter filter = nullptr) const;

private:
friend class task;
net(const std::string& parent_root);

private:
std::vector<net_socket> get_net_sockets(const std::string& file) const;
std::vector<net_socket> get_net_sockets(const std::string& file,
net_socket_filter filter = nullptr) const;

static std::string build_net_root(const std::string& parent_root);

Expand Down
24 changes: 21 additions & 3 deletions include/pfs/parsers/generic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ template <typename Inserter>
using inserted_type = typename Inserter::container_type::value_type;

template <typename Inserter>
void parse_lines(
const std::string& path, Inserter inserter,
void parse_and_filter_lines(
const std::string& path,
Inserter inserter,
std::function<inserted_type<Inserter>(const std::string&)> parser,
std::function<bool(const inserted_type<Inserter>&)> filter = nullptr,
size_t lines_to_skip = 0)
{
std::ifstream in(path);
Expand All @@ -55,10 +57,26 @@ void parse_lines(
continue;
}

inserter = parser(line);
auto inserted = parser(line);
if (filter && filter(inserted))
{
continue;
}

inserter = std::move(inserted);
}
}

template <typename Inserter>
void parse_lines(
const std::string& path,
Inserter inserter,
std::function<inserted_type<Inserter>(const std::string&)> parser,
size_t lines_to_skip = 0)
{
parse_and_filter_lines(path, inserter, parser, nullptr, lines_to_skip);
}

template <typename T>
static void to_number(const std::string& value, T& out,
utils::base base = utils::base::decimal)
Expand Down
75 changes: 40 additions & 35 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,127 +36,132 @@ std::string net::build_net_root(const std::string& parent_root)
return parent_root + NET_DIR;
}

std::vector<net_device> net::get_dev() const
std::vector<net_device> net::get_dev(net_device_filter filter) const
{
static const std::string DEV_FILE("dev");
auto path = _net_root + DEV_FILE;

static const size_t HEADER_LINES = 2;

std::vector<net_device> output;
parsers::parse_lines(path, std::back_inserter(output),
parsers::parse_net_device_line, HEADER_LINES);
parsers::parse_and_filter_lines(path, std::back_inserter(output),
parsers::parse_net_device_line, filter, HEADER_LINES);
return output;
}

std::vector<net_socket> net::get_icmp() const
std::vector<net_socket> net::get_icmp(net_socket_filter filter) const
{
static const std::string ICMP_FILE("icmp");
return get_net_sockets(ICMP_FILE);
return get_net_sockets(ICMP_FILE, filter);
}

std::vector<net_socket> net::get_icmp6() const
std::vector<net_socket> net::get_icmp6(net_socket_filter filter) const
{
static const std::string ICMP6_FILE("icmp6");
return get_net_sockets(ICMP6_FILE);
return get_net_sockets(ICMP6_FILE, filter);
}

std::vector<net_socket> net::get_raw() const
std::vector<net_socket> net::get_raw(net_socket_filter filter) const
{
static const std::string RAW_FILE("raw");
return get_net_sockets(RAW_FILE);
return get_net_sockets(RAW_FILE, filter);
}

std::vector<net_socket> net::get_raw6() const
std::vector<net_socket> net::get_raw6(net_socket_filter filter) const
{
static const std::string RAW6_FILE("raw6");
return get_net_sockets(RAW6_FILE);
return get_net_sockets(RAW6_FILE, filter);
}

std::vector<net_socket> net::get_tcp() const
std::vector<net_socket> net::get_tcp(net_socket_filter filter) const
{
static const std::string TCP_FILE("tcp");
return get_net_sockets(TCP_FILE);
return get_net_sockets(TCP_FILE, filter);
}

std::vector<net_socket> net::get_tcp6() const
std::vector<net_socket> net::get_tcp6(net_socket_filter filter) const
{
static const std::string TCP6_FILE("tcp6");
return get_net_sockets(TCP6_FILE);
return get_net_sockets(TCP6_FILE, filter);
}

std::vector<net_socket> net::get_udp() const
std::vector<net_socket> net::get_udp(net_socket_filter filter) const
{
static const std::string UDP_FILE("udp");
return get_net_sockets(UDP_FILE);
return get_net_sockets(UDP_FILE, filter);
}

std::vector<net_socket> net::get_udp6() const
std::vector<net_socket> net::get_udp6(net_socket_filter filter) const
{
static const std::string UDP6_FILE("udp6");
return get_net_sockets(UDP6_FILE);
return get_net_sockets(UDP6_FILE, filter);
}

std::vector<net_socket> net::get_udplite() const
std::vector<net_socket> net::get_udplite(net_socket_filter filter) const
{
static const std::string UDPLITE_FILE("udplite");
return get_net_sockets(UDPLITE_FILE);
return get_net_sockets(UDPLITE_FILE, filter);
}

std::vector<net_socket> net::get_udplite6() const
std::vector<net_socket> net::get_udplite6(net_socket_filter filter) const
{
static const std::string UDPLITE6_FILE("udplite6");
return get_net_sockets(UDPLITE6_FILE);
return get_net_sockets(UDPLITE6_FILE, filter);
}

std::vector<netlink_socket> net::get_netlink() const
std::vector<netlink_socket> net::get_netlink(netlink_socket_filter filter) const
{
static const std::string NETLINK_FILE("netlink");
auto path = _net_root + NETLINK_FILE;

static const size_t HEADER_LINES = 1;

std::vector<netlink_socket> output;
parsers::parse_lines(path, std::back_inserter(output),
parsers::parse_netlink_socket_line, HEADER_LINES);
parsers::parse_and_filter_lines(path, std::back_inserter(output),
parsers::parse_netlink_socket_line,
filter, HEADER_LINES);
return output;
}

std::vector<unix_socket> net::get_unix() const
std::vector<unix_socket> net::get_unix(unix_socket_filter filter) const
{
static const std::string UNIX_FILE("unix");
auto path = _net_root + UNIX_FILE;

static const size_t HEADER_LINES = 1;

std::vector<unix_socket> output;
parsers::parse_lines(path, std::back_inserter(output),
parsers::parse_unix_socket_line, HEADER_LINES);
parsers::parse_and_filter_lines(path, std::back_inserter(output),
parsers::parse_unix_socket_line,
filter, HEADER_LINES);
return output;
}

std::vector<net_socket> net::get_net_sockets(const std::string& file) const
std::vector<net_socket> net::get_net_sockets(const std::string& file,
net_socket_filter filter) const
{
auto path = _net_root + file;

static const size_t HEADER_LINES = 1;

std::vector<net_socket> output;
parsers::parse_lines(path, std::back_inserter(output),
parsers::parse_net_socket_line, HEADER_LINES);
parsers::parse_and_filter_lines(path, std::back_inserter(output),
parsers::parse_net_socket_line,
filter, HEADER_LINES);
return output;
}

std::vector<net_route> net::get_route() const
std::vector<net_route> net::get_route(net_route_filter filter) const
{
static const size_t HEADER_LINES = 1;

static const std::string ROUTES_FILE("route");
auto path = _net_root + ROUTES_FILE;

std::vector<net_route> output;
parsers::parse_lines(path, std::back_inserter(output),
parsers::parse_net_route_line, HEADER_LINES);
parsers::parse_and_filter_lines(path, std::back_inserter(output),
parsers::parse_net_route_line,
filter, HEADER_LINES);
return output;
}

Expand Down
10 changes: 9 additions & 1 deletion test/test_parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ TEST_CASE("Parse lines functionality", "[parsers]")
std::vector<std::string> content;
std::vector<std::string> expected;
std::vector<std::string> output;
std::function<bool(const std::string&)> filter = nullptr;
size_t skipped = 0;

std::string file;
Expand All @@ -96,7 +97,14 @@ TEST_CASE("Parse lines functionality", "[parsers]")
skipped = 5;
}

SECTION("Filter lines")
{
content = {"a", "x", "x", "b", "x", "c"};
expected = {"a", "b", "c"};
filter = [](const std::string& entry) { return entry == "x"; };
}

file = create_temp_file(content);
parse_lines(file, std::back_inserter(output), parser, skipped);
parse_and_filter_lines(file, std::back_inserter(output), parser, filter, skipped);
REQUIRE(output == expected);
}

0 comments on commit 6b8a234

Please sign in to comment.