Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report pcap stas #264

Merged
merged 4 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions python/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ int nethogsmonitor_loop_devices_py(
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;
}

//--- python module binding
PYBIND11_MODULE(nethogs, m) {
py::class_<NethogsMonitorRecord>(m, "NethogsMonitorRecord")
Expand All @@ -81,6 +96,12 @@ PYBIND11_MODULE(nethogs, m) {
.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");
Expand All @@ -90,6 +111,10 @@ PYBIND11_MODULE(nethogs, m) {
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");


#ifdef VERSION
m.attr("__version__") = VERSION;
Expand Down
17 changes: 17 additions & 0 deletions src/decpcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,23 @@ struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
return dp_fillhandle(temp);
}

/* function to get packet statistics, e.g. dropped packets */

dp_stat dp_stats(struct dp_handle* handle)
{
struct pcap_stat ps;
if(pcap_stats(handle->pcap_handle, &ps) == PCAP_ERROR)
{
fprintf(stderr, "Error getting pcap_stats: %s\n",
pcap_geterr(handle->pcap_handle));
ps.ps_recv = 0;
ps.ps_drop = 0;
ps.ps_ifdrop = 0;
return ps;
}
return ps;
}

/* functions to add callbacks */

void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
Expand Down
5 changes: 5 additions & 0 deletions src/decpcap.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ enum dp_packet_type {
* pcap
};*/
typedef struct pcap_pkthdr dp_header;
typedef struct pcap_stat dp_stat;

typedef int (*dp_callback)(u_char *, const dp_header *, const u_char *);

Expand All @@ -69,6 +70,10 @@ struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
int to_ms, char *filter, char *errbuf);
struct dp_handle *dp_open_offline(char *fname, char *ebuf);

/* function to get packet statistics, e.g. dropped packets */

dp_stat dp_stats(struct dp_handle* handle);

/* functions to add callbacks */

void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
Expand Down
35 changes: 23 additions & 12 deletions src/libnethogs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern "C" {
#include <map>
#include <memory>
#include <vector>
#include <list>

//////////////////////////////
extern ProcList *processes;
Expand All @@ -33,7 +34,7 @@ static fd_set pc_loop_fd_set;
static std::vector<int> pc_loop_fd_list;
static bool pc_loop_use_select = true;

static handle *handles = NULL;
static std::list<handle> handles;

static std::pair<int, int> create_self_pipe() {
int pfd[2];
Expand Down Expand Up @@ -117,7 +118,7 @@ static int nethogsmonitor_init(int devc, char **devicenames, bool all,
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
fprintf(stderr, "Error putting libpcap in nonblocking mode\n");
}
handles = new handle(newhandle, current_dev->name, handles);
handles.push_front(handle(newhandle, current_dev->name));

if (pc_loop_use_select) {
// some devices may not support pcap_get_selectable_fd
Expand Down Expand Up @@ -264,15 +265,10 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb) {

static void nethogsmonitor_clean_up() {
// clean up
handle *current_handle = handles;
handle *rem;
while (current_handle != NULL) {
for(auto current_handle = handles.begin(); current_handle != handles.end(); current_handle++){
pcap_close(current_handle->content->pcap_handle);
rem = current_handle;
current_handle = current_handle->next;
free(rem);
}
handles = NULL;
handles.clear();

// close file descriptors
for (std::vector<int>::const_iterator it = pc_loop_fd_list.begin();
Expand Down Expand Up @@ -307,8 +303,7 @@ int nethogsmonitor_loop_devices(NethogsMonitorCallback cb, char *filter,
while (monitor_run_flag) {
bool packets_read = false;

handle *current_handle = handles;
while (current_handle != NULL) {
for(auto current_handle = handles.begin(); current_handle != handles.end(); current_handle++) {
userdata->device = current_handle->devicename;
userdata->sa_family = AF_UNSPEC;
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
Expand All @@ -320,7 +315,6 @@ int nethogsmonitor_loop_devices(NethogsMonitorCallback cb, char *filter,
} else {
gettimeofday(&curtime, NULL);
}
current_handle = current_handle->next;
}

time_t const now = ::time(NULL);
Expand All @@ -345,3 +339,20 @@ void nethogsmonitor_breakloop() {
monitor_run_flag = false;
write(self_pipe.second, "x", 1);
}

void nethogs_packet_stats(NethogsPackageStats **stats, int *stats_size)
{

*stats = static_cast<NethogsPackageStats *>(malloc(handles.size() * sizeof(NethogsPackageStats)));
int i = 0;

for(auto current_handle = handles.begin(); current_handle != handles.end(); current_handle ++){
dp_stat stat = dp_stats(current_handle->content);
stats[i]->ps_recv = stat.ps_recv;
stats[i]->ps_drop = stat.ps_drop;
stats[i]->ps_ifdrop = stat.ps_ifdrop;
stats[i]->devicename = current_handle->devicename;
i++;
}
*stats_size = handles.size();
}
17 changes: 17 additions & 0 deletions src/libnethogs.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern "C" {

#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>

#define NETHOGS_DSO_VISIBLE __attribute__((visibility("default")))
#define NETHOGS_DSO_HIDDEN __attribute__((visibility("hidden")))
Expand All @@ -32,6 +33,14 @@ typedef struct NethogsMonitorRecord {
float recv_kbs;
} NethogsMonitorRecord;

typedef struct NethogsPackageStats
{
u_int ps_recv; /** number of packets received */
u_int ps_drop; /** number of packets dropped because there was no room in the operating system's buffer when they arrived, because packets weren't being read fast enough */
u_int ps_ifdrop; /** number of packets dropped by the network interface or its driver. */
const char *devicename; /** name of the network interface */
} NethogsPackageStats;

/**
* @brief Defines a callback to handle updates about applications
* @param action NETHOGS_APP_ACTION_SET if data is being added or updated,
Expand Down Expand Up @@ -95,6 +104,14 @@ NETHOGS_DSO_VISIBLE int nethogsmonitor_loop_devices(NethogsMonitorCallback cb,
*/
NETHOGS_DSO_VISIBLE void nethogsmonitor_breakloop();

/**
* @brief returns the pcap packet stats per device
*
* @param stats C-Style array the will hold the stats
* @param stats_size elements and therefore devices in stats
*/
NETHOGS_DSO_VISIBLE void nethogs_packet_stats(NethogsPackageStats **stats, int *stats_size);

#undef NETHOGS_DSO_VISIBLE
#undef NETHOGS_DSO_HIDDEN

Expand Down
8 changes: 4 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <fcntl.h>
#include <set>
#include <vector>
#include <list>

#ifdef __linux__
#include <linux/capability.h>
Expand Down Expand Up @@ -236,7 +237,7 @@ int main(int argc, char **argv) {
int nb_devices = 0;
int nb_failed_devices = 0;

handle *handles = NULL;
std::list<handle> handles;
device *current_dev = devices;
while (current_dev != NULL) {
++nb_devices;
Expand All @@ -262,7 +263,7 @@ int main(int argc, char **argv) {
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
fprintf(stderr, "Error putting libpcap in nonblocking mode\n");
}
handles = new handle(newhandle, current_dev->name, handles);
handles.push_front(handle(newhandle, current_dev->name));

if (pc_loop_use_select) {
// some devices may not support pcap_get_selectable_fd
Expand Down Expand Up @@ -308,8 +309,7 @@ int main(int argc, char **argv) {
while (1) {
bool packets_read = false;

for (handle *current_handle = handles; current_handle != NULL;
current_handle = current_handle->next) {
for (auto current_handle = handles.begin(); current_handle != handles.end(); current_handle ++) {
userdata->device = current_handle->devicename;
userdata->sa_family = AF_UNSPEC;
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
Expand Down
5 changes: 1 addition & 4 deletions src/nethogs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,10 @@ int process_ip6(u_char *userdata, const dp_header * /* header */,

class handle {
public:
handle(dp_handle *m_handle, const char *m_devicename = NULL,
handle *m_next = NULL) {
handle(dp_handle *m_handle, const char *m_devicename = NULL) {
content = m_handle;
next = m_next;
devicename = m_devicename;
}
dp_handle *content;
const char *devicename;
handle *next;
};