Skip to content

Commit

Permalink
Add netstat sample application
Browse files Browse the repository at this point in the history
  • Loading branch information
dtrugman committed Jan 1, 2024
1 parent ec87534 commit 1bef73e
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ How does that affect `pfs`?

The directory `sample` contains a full blown application that calls all(!) the supported APIs and prints all the information gathered. When compiling the library, the sample applications is compiled as well.

You can find a basic implementation of `netstat` (see `sample/tool_netstat.cpp`) and `lsmod` (see `sample/tool_lsmod.cpp`) that you can easily reuse in your projects.

Anyway, here are some cool (and concise) examples:

**Example 1:** Iterater over all the loaded unsigned or out-of-tree kernel modules
Expand Down
20 changes: 14 additions & 6 deletions sample/sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,20 @@ int main(int argc, char** argv)

// clang-format off
auto commands = std::vector<command>{
{command("system", "", "Enumerate system-wide information", enum_system)},
{command("net", "", "Enumerate network information", enum_net)},
{command("tasks", "[task-id]...", "Enumerate running tasks", enum_tasks)},
{command("fds", "[task-id]...", "Enumerate fds for a specific task", enum_fds)},
{command("lsmod", "[filter]", "Enumerate all loaded modules that match the filter", tool_lsmod)},
{command("blocks", "[block-name]...", "Enumerate block devices", enum_blocks)},
{command("system", "",
"Enumerate system-wide information", enum_system)},
{command("net", "",
"Enumerate network information", enum_net)},
{command("tasks", "[task-id]...",
"Enumerate running tasks", enum_tasks)},
{command("fds", "[task-id]...",
"Enumerate fds for a specific task", enum_fds)},
{command("blocks", "[block-name]...",
"Enumerate block devices", enum_blocks)},
{command("lsmod", "[filter]",
"Enumerate all loaded modules that match the filter", tool_lsmod)},
{command("netstat", "(tcp|udp) [task-id]...",
"Enumerate all sockets of said type for tasks", tool_netstat)},
};
// clang-format on

Expand Down
1 change: 1 addition & 0 deletions sample/tool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
#define SAMPLE_TOOL_HPP

int tool_lsmod(std::vector<std::string>&& args);
int tool_netstat(std::vector<std::string>&& args);

#endif // SAMPLE_TOOL_HPP
92 changes: 92 additions & 0 deletions sample/tool_netstat.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2020-present Daniel Trugman
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <regex>

#include "format.hpp"
#include "log.hpp"
#include "tool.hpp"

static const std::string TCP("tcp");
static const std::string UDP("udp");

void task_netstat(const pfs::task& task, const std::string& type)
{
LOG("=========================================================");
LOG("Netstat for task ID[" << task.id() << "]");
LOG("=========================================================");

auto inodes = task.get_fds_inodes();
pfs::net::net_socket_filter filter = [&inodes](const pfs::net_socket& sock){
return inodes.find(sock.inode) == inodes.end();
};

auto net = task.get_net();
std::vector<pfs::net_socket> sockets;
if (type == TCP)
{
sockets = net.get_tcp(filter);
}
else if (type == UDP)
{
sockets = net.get_udp(filter);
}

print(sockets);
}

int tool_netstat(std::vector<std::string>&& args)
{
if (args.size() < 1)
{
return -EINVAL;
}

std::string type(args[0]);
if (type != TCP && type != UDP)
{
return -EINVAL;
}

try
{
pfs::procfs pfs;

if (args.size() > 1)
{
for (unsigned arg = 1; arg < args.size(); ++arg)
{
auto id = std::stoi(args[arg]);
auto task = pfs.get_task(id);
task_netstat(task, type);
}
}
else
{
for (auto& task : pfs.get_processes())
{
task_netstat(task, type);
}
}
}
catch (const std::runtime_error& ex)
{
LOG("Error when printing netstat:");
LOG(TAB << ex.what());
}

return 0;
}

0 comments on commit 1bef73e

Please sign in to comment.