Merge pull request #264 from AndreasGocht/report_pcap_stas
Report pcap stas
This commit is contained in:
@@ -66,6 +66,21 @@ int nethogsmonitor_loop_devices_py(
|
|||||||
return retval;
|
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
|
//--- python module binding
|
||||||
PYBIND11_MODULE(nethogs, m) {
|
PYBIND11_MODULE(nethogs, m) {
|
||||||
py::class_<NethogsMonitorRecord>(m, "NethogsMonitorRecord")
|
py::class_<NethogsMonitorRecord>(m, "NethogsMonitorRecord")
|
||||||
@@ -81,6 +96,12 @@ PYBIND11_MODULE(nethogs, m) {
|
|||||||
.def_readwrite("sent_kbs", &NethogsMonitorRecord::sent_kbs)
|
.def_readwrite("sent_kbs", &NethogsMonitorRecord::sent_kbs)
|
||||||
.def_readwrite("recv_kbs", &NethogsMonitorRecord::recv_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(
|
m.def("nethogsmonitor_loop", &nethogsmonitor_loop_py, R"pbdoc(
|
||||||
Nethogs monitor loop
|
Nethogs monitor loop
|
||||||
)pbdoc");
|
)pbdoc");
|
||||||
@@ -90,6 +111,10 @@ PYBIND11_MODULE(nethogs, m) {
|
|||||||
m.def("nethogsmonitor_breakloop", &nethogsmonitor_breakloop, R"pbdoc(
|
m.def("nethogsmonitor_breakloop", &nethogsmonitor_breakloop, R"pbdoc(
|
||||||
Nethogs monitor loop break
|
Nethogs monitor loop break
|
||||||
)pbdoc");
|
)pbdoc");
|
||||||
|
m.def("nethogs_packet_stats", &nethogs_packet_stats_py, R"pbdoc(
|
||||||
|
Nethogs pcap packet stats
|
||||||
|
)pbdoc");
|
||||||
|
|
||||||
|
|
||||||
#ifdef VERSION
|
#ifdef VERSION
|
||||||
m.attr("__version__") = VERSION;
|
m.attr("__version__") = VERSION;
|
||||||
|
|||||||
@@ -110,6 +110,23 @@ struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
|
|||||||
return dp_fillhandle(temp);
|
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 */
|
/* functions to add callbacks */
|
||||||
|
|
||||||
void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
|
void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ enum dp_packet_type {
|
|||||||
* pcap
|
* pcap
|
||||||
};*/
|
};*/
|
||||||
typedef struct pcap_pkthdr dp_header;
|
typedef struct pcap_pkthdr dp_header;
|
||||||
|
typedef struct pcap_stat dp_stat;
|
||||||
|
|
||||||
typedef int (*dp_callback)(u_char *, const dp_header *, const u_char *);
|
typedef int (*dp_callback)(u_char *, const dp_header *, const u_char *);
|
||||||
|
|
||||||
@@ -69,6 +70,10 @@ struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
|
|||||||
int to_ms, char *filter, char *errbuf);
|
int to_ms, char *filter, char *errbuf);
|
||||||
struct dp_handle *dp_open_offline(char *fname, char *ebuf);
|
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 */
|
/* functions to add callbacks */
|
||||||
|
|
||||||
void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
|
void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ extern "C" {
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
extern ProcList *processes;
|
extern ProcList *processes;
|
||||||
@@ -33,7 +34,7 @@ static fd_set pc_loop_fd_set;
|
|||||||
static std::vector<int> pc_loop_fd_list;
|
static std::vector<int> pc_loop_fd_list;
|
||||||
static bool pc_loop_use_select = true;
|
static bool pc_loop_use_select = true;
|
||||||
|
|
||||||
static handle *handles = NULL;
|
static std::list<handle> handles;
|
||||||
|
|
||||||
static std::pair<int, int> create_self_pipe() {
|
static std::pair<int, int> create_self_pipe() {
|
||||||
int pfd[2];
|
int pfd[2];
|
||||||
@@ -117,7 +118,7 @@ static int nethogsmonitor_init(int devc, char **devicenames, bool all,
|
|||||||
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
|
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
|
||||||
fprintf(stderr, "Error putting libpcap in nonblocking mode\n");
|
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) {
|
if (pc_loop_use_select) {
|
||||||
// some devices may not support pcap_get_selectable_fd
|
// some devices may not support pcap_get_selectable_fd
|
||||||
@@ -264,15 +265,10 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb) {
|
|||||||
|
|
||||||
static void nethogsmonitor_clean_up() {
|
static void nethogsmonitor_clean_up() {
|
||||||
// clean up
|
// clean up
|
||||||
handle *current_handle = handles;
|
for(auto current_handle = handles.begin(); current_handle != handles.end(); current_handle++){
|
||||||
handle *rem;
|
|
||||||
while (current_handle != NULL) {
|
|
||||||
pcap_close(current_handle->content->pcap_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
|
// close file descriptors
|
||||||
for (std::vector<int>::const_iterator it = pc_loop_fd_list.begin();
|
for (std::vector<int>::const_iterator it = pc_loop_fd_list.begin();
|
||||||
@@ -307,8 +303,7 @@ int nethogsmonitor_loop_devices(NethogsMonitorCallback cb, char *filter,
|
|||||||
while (monitor_run_flag) {
|
while (monitor_run_flag) {
|
||||||
bool packets_read = false;
|
bool packets_read = false;
|
||||||
|
|
||||||
handle *current_handle = handles;
|
for(auto current_handle = handles.begin(); current_handle != handles.end(); current_handle++) {
|
||||||
while (current_handle != NULL) {
|
|
||||||
userdata->device = current_handle->devicename;
|
userdata->device = current_handle->devicename;
|
||||||
userdata->sa_family = AF_UNSPEC;
|
userdata->sa_family = AF_UNSPEC;
|
||||||
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
|
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
|
||||||
@@ -320,7 +315,6 @@ int nethogsmonitor_loop_devices(NethogsMonitorCallback cb, char *filter,
|
|||||||
} else {
|
} else {
|
||||||
gettimeofday(&curtime, NULL);
|
gettimeofday(&curtime, NULL);
|
||||||
}
|
}
|
||||||
current_handle = current_handle->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t const now = ::time(NULL);
|
time_t const now = ::time(NULL);
|
||||||
@@ -345,3 +339,20 @@ void nethogsmonitor_breakloop() {
|
|||||||
monitor_run_flag = false;
|
monitor_run_flag = false;
|
||||||
write(self_pipe.second, "x", 1);
|
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();
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#define NETHOGS_DSO_VISIBLE __attribute__((visibility("default")))
|
#define NETHOGS_DSO_VISIBLE __attribute__((visibility("default")))
|
||||||
#define NETHOGS_DSO_HIDDEN __attribute__((visibility("hidden")))
|
#define NETHOGS_DSO_HIDDEN __attribute__((visibility("hidden")))
|
||||||
@@ -32,6 +33,14 @@ typedef struct NethogsMonitorRecord {
|
|||||||
float recv_kbs;
|
float recv_kbs;
|
||||||
} NethogsMonitorRecord;
|
} 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
|
* @brief Defines a callback to handle updates about applications
|
||||||
* @param action NETHOGS_APP_ACTION_SET if data is being added or updated,
|
* @param action NETHOGS_APP_ACTION_SET if data is being added or updated,
|
||||||
@@ -95,6 +104,14 @@ NETHOGS_DSO_VISIBLE int nethogsmonitor_loop_devices(NethogsMonitorCallback cb,
|
|||||||
*/
|
*/
|
||||||
NETHOGS_DSO_VISIBLE void nethogsmonitor_breakloop();
|
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_VISIBLE
|
||||||
#undef NETHOGS_DSO_HIDDEN
|
#undef NETHOGS_DSO_HIDDEN
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
@@ -236,7 +237,7 @@ int main(int argc, char **argv) {
|
|||||||
int nb_devices = 0;
|
int nb_devices = 0;
|
||||||
int nb_failed_devices = 0;
|
int nb_failed_devices = 0;
|
||||||
|
|
||||||
handle *handles = NULL;
|
std::list<handle> handles;
|
||||||
device *current_dev = devices;
|
device *current_dev = devices;
|
||||||
while (current_dev != NULL) {
|
while (current_dev != NULL) {
|
||||||
++nb_devices;
|
++nb_devices;
|
||||||
@@ -262,7 +263,7 @@ int main(int argc, char **argv) {
|
|||||||
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
|
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
|
||||||
fprintf(stderr, "Error putting libpcap in nonblocking mode\n");
|
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) {
|
if (pc_loop_use_select) {
|
||||||
// some devices may not support pcap_get_selectable_fd
|
// some devices may not support pcap_get_selectable_fd
|
||||||
@@ -308,8 +309,7 @@ int main(int argc, char **argv) {
|
|||||||
while (1) {
|
while (1) {
|
||||||
bool packets_read = false;
|
bool packets_read = false;
|
||||||
|
|
||||||
for (handle *current_handle = handles; current_handle != NULL;
|
for (auto current_handle = handles.begin(); current_handle != handles.end(); current_handle ++) {
|
||||||
current_handle = current_handle->next) {
|
|
||||||
userdata->device = current_handle->devicename;
|
userdata->device = current_handle->devicename;
|
||||||
userdata->sa_family = AF_UNSPEC;
|
userdata->sa_family = AF_UNSPEC;
|
||||||
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
|
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
|
||||||
|
|||||||
@@ -237,13 +237,10 @@ int process_ip6(u_char *userdata, const dp_header * /* header */,
|
|||||||
|
|
||||||
class handle {
|
class handle {
|
||||||
public:
|
public:
|
||||||
handle(dp_handle *m_handle, const char *m_devicename = NULL,
|
handle(dp_handle *m_handle, const char *m_devicename = NULL) {
|
||||||
handle *m_next = NULL) {
|
|
||||||
content = m_handle;
|
content = m_handle;
|
||||||
next = m_next;
|
|
||||||
devicename = m_devicename;
|
devicename = m_devicename;
|
||||||
}
|
}
|
||||||
dp_handle *content;
|
dp_handle *content;
|
||||||
const char *devicename;
|
const char *devicename;
|
||||||
handle *next;
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user