1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#include <pybind11/functional.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <set>
#include <iostream>
#include "libnethogs.h"
namespace py = pybind11;
//--- for some reason this is a global defined in main.cpp
extern std::set<pid_t> pidsToWatch;
//--- hacky way to get callbacks working and handle signals
std::function<void(int, NethogsMonitorRecord const *)> empty_callback;
std::function<void(int, NethogsMonitorRecord const *)> loop_callback;
void loop_callback_wrapper(
int action,
NethogsMonitorRecord const *record)
{
py::gil_scoped_acquire acquire;
if (PyErr_CheckSignals() != 0) {
nethogsmonitor_breakloop();
PyErr_Clear();
}
else if (loop_callback) {
loop_callback(action, record);
}
}
int nethogsmonitor_loop_py(
std::function<void(int, NethogsMonitorRecord const *)> &cb,
char *filter,
int to_ms)
{
int retval;
loop_callback = cb;
{
py::gil_scoped_release release;
retval = nethogsmonitor_loop(loop_callback_wrapper, filter, to_ms);
}
loop_callback = empty_callback;
return retval;
}
int nethogsmonitor_loop_devices_py(
std::function<void(int, NethogsMonitorRecord const *)> &cb,
char *filter,
std::vector<std::string> __devicenames,
bool all,
int to_ms)
{
// this is ok because we only use the vector here
std::vector<char*> _devicenames;
for (auto& _dn : __devicenames)
{
_devicenames.push_back(const_cast<char*>(_dn.c_str()));
}
int devc = _devicenames.size();
char **devicenames = (_devicenames.empty()) ? NULL : _devicenames.data();
int retval;
loop_callback = cb;
{
py::gil_scoped_release release;
retval = nethogsmonitor_loop_devices(loop_callback_wrapper, filter, devc, devicenames, all, to_ms);
}
loop_callback = empty_callback;
return retval;
}
std::vector<NethogsPackageStats> nethogs_packet_stats_py()
{
NethogsPackageStats* stats;
int stat_count;
nethogs_packet_stats(&stats, &stat_count);
std::vector<NethogsPackageStats> stats_vector(stat_count);
std::copy_n(stats,stat_count, stats_vector.begin());
free(stats);
return stats_vector;
}
void nethogs_enable_udp_py(bool state)
{
nethogs_enable_udp(state);
}
//--- python module binding
PYBIND11_MODULE(nethogs, m) {
py::class_<NethogsMonitorRecord>(m, "NethogsMonitorRecord")
.def_readwrite("record_id", &NethogsMonitorRecord::record_id)
.def_readwrite("name", &NethogsMonitorRecord::name)
.def_readwrite("pid", &NethogsMonitorRecord::pid)
.def_readwrite("uid", &NethogsMonitorRecord::uid)
.def_readwrite("device_name", &NethogsMonitorRecord::device_name)
.def_readwrite("sent_bytes", &NethogsMonitorRecord::sent_bytes)
.def_readwrite("recv_bytes", &NethogsMonitorRecord::recv_bytes)
.def_readwrite("sent_bytes_last", &NethogsMonitorRecord::sent_bytes_last)
.def_readwrite("recv_bytes_last", &NethogsMonitorRecord::recv_bytes_last)
.def_readwrite("sent_kbs", &NethogsMonitorRecord::sent_kbs)
.def_readwrite("recv_kbs", &NethogsMonitorRecord::recv_kbs);
py::class_<NethogsPackageStats>(m, "NethogsPackageStats")
.def_readonly("ps_recv", &NethogsPackageStats::ps_recv)
.def_readonly("ps_drop", &NethogsPackageStats::ps_drop)
.def_readonly("ps_ifdrop", &NethogsPackageStats::ps_ifdrop)
.def_readonly("devicename", &NethogsPackageStats::devicename);
m.def("nethogsmonitor_loop", &nethogsmonitor_loop_py, R"pbdoc(
Nethogs monitor loop
)pbdoc");
m.def("nethogsmonitor_loop_devices", &nethogsmonitor_loop_devices_py, R"pbdoc(
Nethogs monitor loop
)pbdoc");
m.def("nethogsmonitor_breakloop", &nethogsmonitor_breakloop, R"pbdoc(
Nethogs monitor loop break
)pbdoc");
m.def("nethogs_packet_stats", &nethogs_packet_stats_py, R"pbdoc(
Nethogs pcap packet stats
)pbdoc");
m.def("nethogs_enable_udp", &nethogs_enable_udp_py, R"pbdoc(
Enables or disables the recording of UDP, default is False.
)pbdoc");
#ifdef VERSION
m.attr("__version__") = VERSION;
#else
m.attr("__version__") = "unknown";
#endif
}
|