From a7c14c842a3bcfdc3bba0dfa1500f6a20902bb46 Mon Sep 17 00:00:00 2001 From: Jason Antman Date: Sat, 26 Aug 2017 14:29:21 -0400 Subject: [PATCH] fixes #129 - libnethogs support for limiting to specific devices --- contrib/python-wrapper.py | 46 ++++++++++++++++++++++++++++++++++++--- src/libnethogs.cpp | 11 +++++++--- src/libnethogs.h | 18 +++++++++++++++ 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/contrib/python-wrapper.py b/contrib/python-wrapper.py index 11f6329..f4e1895 100644 --- a/contrib/python-wrapper.py +++ b/contrib/python-wrapper.py @@ -62,7 +62,29 @@ def signal_handler(signal, frame): lib.nethogsmonitor_breakloop() -def run_monitor_loop(lib): +def dev_args(devnames): + """ + Return the appropriate ctypes arguments for a device name list, to pass + to libnethogs ``nethogsmonitor_loop_devices``. The return value is a + 2-tuple of devc (``ctypes.c_int``) and devicenames (``ctypes.POINTER``) + to an array of ``ctypes.c_char``). + + :param devnames: list of device names to monitor + :type devnames: list + :return: 2-tuple of devc, devicenames ctypes arguments + :rtype: tuple + """ + devc = len(devnames) + devnames_type = ctypes.c_char_p * devc + devnames_arg = devnames_type() + for idx, val in enumerate(devnames): + devnames_arg[idx] = (val + chr(0)).encode('ascii') + return ctypes.c_int(devc), ctypes.cast( + devnames_arg, ctypes.POINTER(ctypes.c_char_p) + ) + + +def run_monitor_loop(lib, devnames): # Create a type for my callback func. The callback func returns void (None), and accepts as # params an int and a pointer to a NethogsMonitorRecord instance. # The params and return type of the callback function are mandated by nethogsmonitor_loop(). @@ -70,7 +92,19 @@ def run_monitor_loop(lib): CALLBACK_FUNC_TYPE = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_int, ctypes.POINTER(NethogsMonitorRecord)) - rc = lib.nethogsmonitor_loop(CALLBACK_FUNC_TYPE(network_activity_callback)) + if len(devnames) < 1: + # monitor all devices + rc = lib.nethogsmonitor_loop( + CALLBACK_FUNC_TYPE(network_activity_callback) + ) + else: + devc, devicenames = dev_args(devnames) + rc = lib.nethogsmonitor_loop_devices( + CALLBACK_FUNC_TYPE(network_activity_callback), + devc, + devicenames, + ctypes.c_bool(False) + ) if rc != LoopStatus.OK: print('nethogsmonitor_loop returned {}'.format(LoopStatus.MAP[rc])) @@ -102,7 +136,13 @@ signal.signal(signal.SIGTERM, signal_handler) lib = ctypes.CDLL(LIBRARY_NAME) -monitor_thread = threading.Thread(target=run_monitor_loop, args=(lib,)) +device_names = [] +# You can use this to monitor only certain devices, like: +# device_names = ['enp4s0', 'docker0'] + +monitor_thread = threading.Thread( + target=run_monitor_loop, args=(lib, device_names,) +) monitor_thread.start() diff --git a/src/libnethogs.cpp b/src/libnethogs.cpp index 18a30e2..b45ebca 100644 --- a/src/libnethogs.cpp +++ b/src/libnethogs.cpp @@ -72,10 +72,10 @@ static bool wait_for_next_trigger() { return true; } -static int nethogsmonitor_init() { +static int nethogsmonitor_init(int devc, char **devicenames, bool all) { process_init(); - device *devices = get_default_devices(); + device *devices = get_devices(devc, devicenames, all); if (devices == NULL) { std::cerr << "No devices to monitor" << std::endl; return NETHOGS_STATUS_NO_DEVICE; @@ -272,11 +272,16 @@ static void nethogsmonitor_clean_up() { } int nethogsmonitor_loop(NethogsMonitorCallback cb) { + return nethogsmonitor_loop_devices(cb, 0, NULL, false); +} + +int nethogsmonitor_loop_devices(NethogsMonitorCallback cb, + int devc, char **devicenames, bool all) { if (monitor_run_flag) { return NETHOGS_STATUS_FAILURE; } - int return_value = nethogsmonitor_init(); + int return_value = nethogsmonitor_init(devc, devicenames, all); if (return_value != NETHOGS_STATUS_OK) { return return_value; } diff --git a/src/libnethogs.h b/src/libnethogs.h index 75340fe..4caacb8 100644 --- a/src/libnethogs.h +++ b/src/libnethogs.h @@ -57,6 +57,24 @@ typedef void (*NethogsMonitorCallback)(int action, NETHOGS_DSO_VISIBLE int nethogsmonitor_loop(NethogsMonitorCallback cb); +/** + * @brief Enter the process monitoring loop and reports updates using the + * callback provided as parameter. Specify which network devices to monitor. + * All parameters other than cb are passed through to get_devices(). + * This call will block until nethogsmonitor_breakloop() is called or a failure + * occurs. + * @param cb A pointer to a callback function following the + * NethogsMonitorCallback definition + * @param devc number of values in devicenames array + * @param devicenames pointer to array of devicenames (char arrays) + * @param all when false, loopback interface and down/not running interfaces + * will be avoided. When true, find all interfaces including down/not running. + */ + +NETHOGS_DSO_VISIBLE int nethogsmonitor_loop_devices(NethogsMonitorCallback cb, + int devc, char **devicenames, + bool all); + /** * @brief Makes the call to nethogsmonitor_loop return. */