diff --git a/include/AlertableEntity.h b/include/AlertableEntity.h index 6b0275663b..8b4829f737 100644 --- a/include/AlertableEntity.h +++ b/include/AlertableEntity.h @@ -24,8 +24,6 @@ #include "ntop_includes.h" -class NetworkInterface; - class AlertableEntity { protected: std::map alert_cache[MAX_NUM_PERIODIC_SCRIPTS]; @@ -45,12 +43,12 @@ class AlertableEntity { } /* Return true if the element was inserted, false if already present */ - inline bool triggerAlert(std::string key, ScriptPeriodicity p) { + inline bool triggerAlert(std::string key, ScriptPeriodicity p) { return(triggered_alerts[(u_int)p].insert(key).second); } /* Return true if the element was existing and thus deleted, false if not present */ - inline bool releaseAlert(std::string key, ScriptPeriodicity p) { + inline bool releaseAlert(std::string key, ScriptPeriodicity p) { return((triggered_alerts[(u_int)p].erase(key) == 1) ? true : false); } diff --git a/include/NetworkInterface.h b/include/NetworkInterface.h index faa9a9ee04..895d7e66ce 100644 --- a/include/NetworkInterface.h +++ b/include/NetworkInterface.h @@ -493,7 +493,8 @@ class NetworkInterface : public AlertableEntity { u_int8_t location_filter); int getMacsIpAddresses(lua_State *vm, int idx); void getFlowsStats(lua_State* vm); - void getNetworksStats(lua_State* vm); + void getNetworkStats(lua_State* vm, u_int8_t network_id) const; + void getNetworksStats(lua_State* vm) const; int getFlows(lua_State* vm, u_int32_t *begin_slot, bool walk_all, @@ -597,7 +598,7 @@ class NetworkInterface : public AlertableEntity { #endif return(-1); }; - NetworkStats* getNetworkStats(u_int8_t networkId); + NetworkStats* getNetworkStats(u_int8_t networkId) const; void allocateNetworkStats(); void getsDPIStats(lua_State *vm); #ifdef NTOPNG_PRO diff --git a/include/NetworkStats.h b/include/NetworkStats.h index 73f5814f2a..48f0fa06cf 100644 --- a/include/NetworkStats.h +++ b/include/NetworkStats.h @@ -24,8 +24,9 @@ #include "ntop_includes.h" -class NetworkStats { +class NetworkStats : public AlertableEntity { private: + u_int8_t network_id; TrafficStats ingress, ingress_broadcast; /* outside -> network */ TrafficStats egress, egress_broadcast; /* network -> outside */ TrafficStats inner, inner_broadcast; /* network -> network (local traffic) */ @@ -72,6 +73,7 @@ class NetworkStats { incTcp(&tcp_packet_stats_inner, ooo_pkts, retr_pkts, lost_pkts, keep_alive_pkts); }; + inline void setNetworkId(u_int8_t id) { network_id = id; }; void lua(lua_State* vm); bool serialize(json_object *my_object); void deserialize(json_object *obj); diff --git a/include/ntop_includes.h b/include/ntop_includes.h index d0bfcee38f..c7a845f126 100644 --- a/include/ntop_includes.h +++ b/include/ntop_includes.h @@ -184,8 +184,9 @@ using namespace std; #include "Ping.h" #include "TrafficStats.h" #include "TcpPacketStats.h" -#include "NetworkStats.h" #include "ntop_typedefs.h" +#include "AlertableEntity.h" +#include "NetworkStats.h" #include "Trace.h" #include "ProtoStats.h" #include "Utils.h" @@ -255,7 +256,6 @@ using namespace std; #endif #include "InterfaceStatsHash.h" #include "GenericHashEntry.h" -#include "AlertableEntity.h" #if defined(NTOPNG_PRO) && defined(HAVE_NINDEX) #include "nindex_api.h" #endif diff --git a/include/ntop_typedefs.h b/include/ntop_typedefs.h index 16a99099b9..39b6a38dba 100644 --- a/include/ntop_typedefs.h +++ b/include/ntop_typedefs.h @@ -560,6 +560,10 @@ typedef struct { class SNMP; #endif +/* Forward class declarations for the Lua context */ +class NetworkStats; +class Host; + struct ntopngLuaContext { char *allowed_ifname, *user, *group; void *zmq_context, *zmq_subscriber; diff --git a/scripts/callbacks/interface/alerts/network.lua b/scripts/callbacks/interface/alerts/network.lua new file mode 100644 index 0000000000..bfb2fb336d --- /dev/null +++ b/scripts/callbacks/interface/alerts/network.lua @@ -0,0 +1,116 @@ +-- +-- (C) 2019 - ntop.org +-- + +local dirs = ntop.getDirs() +package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path +require "lua_utils" +require "alert_utils" + +alerts_api = require("alerts_api") + +local do_trace = true +local config_alerts = nil +local ifname = nil + +-- The function below ia called once (#pragma once) +function setup(str_granularity) + print("alert.lua:setup("..str_granularity..") called\n") + ifname = interface.setActiveInterfaceId(tonumber(interface.getId())) + config_alerts = getNetworksConfiguredAlertThresholds(ifname, str_granularity) + + -- Load the threshold checking functions + package.path = dirs.installdir .. "/scripts/callbacks/interface/alerts/network/?.lua;" .. package.path + checks = require("check") +end + +-- ################################################################# + +-- The function below is called once per network +local function checkNetworkAlertsThreshold(network_key, network_info, granularity, num_granularity, rules) + if do_trace then print("checkNetworkAlertsThreshold()\n") end + + for function_name, params in pairs(rules) do + -- IMPORTANT: do not use "local" with the variables below + -- as they need to be accessible by the evaluated function + threshold_value = params["edge"] + alert_key_name = params["key"] + threshold_operator = params["operator"] + metric_name = params["metric"] + threshold_gran = granularity + threshold_num_gran = num_granularity + n_info = network_info + + print("[Alert @ "..granularity.."] ".. network_key .." ["..function_name.."]\n") + + if true then + -- This is where magic happens: load() evaluates the string + local what = 'return checks.'..function_name..'(metric_name, n_info, threshold_gran, threshold_num_gran)' + local func, err = load(what, 't') + + if func then + local ok, value = pcall(func) + + if ok then + local alarmed = false + local network_alert = alerts_api:newAlert({entity = "network", type = "threshold_cross", severity = "error"}) + + if do_trace then print("Execution OK. value: "..tostring(value)..", operator: "..threshold_operator..", threshold: "..threshold_value.."]\n") end + + threshold_value = tonumber(threshold_value) + + if threshold_operator == "lt" then + if value < threshold_value then alarmed = true end + else + if value > threshold_value then alarmed = true end + end + + if alarmed then + if interface.storeTriggeredAlert(alert_key_name, num_granularity) then + -- IMPORTANT: uncommenting the line below break all + -- network_alert:trigger(network_key, "Network "..network_key.." crossed threshold "..metric_name) + print("Trigger alert [value: "..tostring(value).."]\n") + end + else + if interface.releaseTriggeredAlert(alert_key_name, num_granularity) then + print("DON'T trigger alert [value: "..tostring(value).."]\n") + -- network_alert:release(network_key) + end + end + else + if do_trace then print("Execution error: "..tostring(rc).."\n") end + end + else + print("Compilation error:", err) + end + end + + print("=============\n") + end +end + +-- ################################################################# + +-- The function below is called once per local network +function checkNetworkAlerts(granularity) + local info = network.getNetworkStats() + local network_key = info and info.network_key + + if not network_key then + return + end + + local network_alert = config_alerts[network_key] + local num_granularity = granularity2id(granularity) + + -- specific network alerts + if network_alert and table.len(network_alert) > 0 then + checkNetworkAlertsThreshold(network_key, info, granularity, num_granularity, network_alert) + end + + -- generic network alerts + network_alert = config_alerts["local_networks"] + if network_alert and table.len(network_alert) > 0 then + checkNetworkAlertsThreshold(network_key, info, granularity, num_granularity, network_alert) + end +end diff --git a/scripts/callbacks/interface/alerts/network/check.lua b/scripts/callbacks/interface/alerts/network/check.lua new file mode 100644 index 0000000000..27cdf70600 --- /dev/null +++ b/scripts/callbacks/interface/alerts/network/check.lua @@ -0,0 +1,49 @@ +-- +-- (C) 2019 - ntop.org +-- + +local check = {} + +-- ################################################################# + +local function cached_val_key(metric_name, granularity_num) + return string.format("%s:%s", metric_name, granularity_num) +end + +-- ################################################################# + +local function delta_val(metric_name, granularity_num, curr_val) + local key = cached_val_key(metric_name, granularity_num) + + -- Read cached value and purify it + local prev_val = network.getCachedAlertValue(key, granularity_num) + prev_val = tonumber(prev_val) or 0 + + -- Save the value for the next round + network.setCachedAlertValue(key, tostring(curr_val), granularity_num) + + -- Compute the delta + return curr_val - prev_val +end + +-- ################################################################# + +function check.egress(metric_name, info, granularity, granularity_num) + return delta_val(metric_name, granularity_num, info["egress"]) +end + +-- ################################################################# + +function check.ingress(metric_name, info, granularity, granularity_num) + return delta_val(metric_name, granularity_num, info["ingress"]) +end + +-- ################################################################# + +function check.inner(metric_name, info, granularity, granularity_num) + return delta_val(metric_name, granularity_num, info["inner"]) +end + +-- ################################################################# + +return check diff --git a/scripts/lua/test_alerts.lua b/scripts/lua/test_alerts.lua index 66541f8d87..2a84a725f2 100644 --- a/scripts/lua/test_alerts.lua +++ b/scripts/lua/test_alerts.lua @@ -21,7 +21,7 @@ dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") -- ntop.checkHostsAlertsMin() -- checks the current networks alerts --- ntop.checkNetworksAlertsMin() +ntop.checkNetworksAlertsMin() -- checks the current interface alerts -- interface.checkAlertsMin() diff --git a/src/LuaEngine.cpp b/src/LuaEngine.cpp index 68263972ae..2dd92cbc64 100644 --- a/src/LuaEngine.cpp +++ b/src/LuaEngine.cpp @@ -2737,6 +2737,22 @@ static int ntop_get_interface_flows_stats(lua_State* vm) { /* ****************************************** */ +// ***API*** +static int ntop_get_interface_network_stats(lua_State* vm) { + struct ntopngLuaContext *c = getLuaVMContext(vm); + NetworkStats *ns = c ? c->network : NULL; + + if(ns) { + lua_newtable(vm); + ns->lua(vm); + } else + lua_pushnil(vm); + + return(CONST_LUA_OK); +} + +/* ****************************************** */ + // ***API*** static int ntop_get_interface_networks_stats(lua_State* vm) { NetworkInterface *ntop_interface = getCurrentInterface(vm); @@ -7970,7 +7986,7 @@ static int ntop_host_get_cached_alert_value(lua_State* vm) { char *key; std::string val; ScriptPeriodicity periodicity; - + ntop->getTrace()->traceEvent(TRACE_DEBUG, "%s() called", __FUNCTION__); if(!h) return(CONST_LUA_ERROR); @@ -7983,7 +7999,7 @@ static int ntop_host_get_cached_alert_value(lua_State* vm) { val = h->getAlertCachedValue(std::string(key), periodicity); lua_pushstring(vm, val.c_str()); - + return(CONST_LUA_OK); } @@ -7994,7 +8010,7 @@ static int ntop_host_set_cached_alert_value(lua_State* vm) { Host *h = c ? c->host : NULL; char *key, *value; ScriptPeriodicity periodicity; - + ntop->getTrace()->traceEvent(TRACE_DEBUG, "%s() called", __FUNCTION__); if(!h) return(CONST_LUA_ERROR); @@ -8010,12 +8026,12 @@ static int ntop_host_set_cached_alert_value(lua_State* vm) { if((!key) || (!value)) return(CONST_LUA_PARAM_ERROR); - + h->setAlertCacheValue(std::string(key), std::string(value), periodicity); - + return(CONST_LUA_OK); } - + /* ****************************************** */ static int ntop_host_store_triggered_alert(lua_State* vm) { @@ -8023,7 +8039,7 @@ static int ntop_host_store_triggered_alert(lua_State* vm) { Host *h = c ? c->host : NULL; char *key = NULL; ScriptPeriodicity periodicity; - + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); @@ -8031,10 +8047,10 @@ static int ntop_host_store_triggered_alert(lua_State* vm) { if((periodicity = (ScriptPeriodicity)lua_tonumber(vm, 2)) >= MAX_NUM_PERIODIC_SCRIPTS) return(CONST_LUA_PARAM_ERROR); if((!h) || (!key)) return(CONST_LUA_PARAM_ERROR); - + lua_pushboolean(vm, h->triggerAlert(std::string(key), periodicity)); - - return(CONST_LUA_OK); + + return(CONST_LUA_OK); } /* ****************************************** */ @@ -8044,7 +8060,7 @@ static int ntop_host_release_triggered_alert(lua_State* vm) { Host *h = c ? c->host : NULL; char *key = NULL; ScriptPeriodicity periodicity; - + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); @@ -8053,8 +8069,103 @@ static int ntop_host_release_triggered_alert(lua_State* vm) { if((!h) || (!key)) return(CONST_LUA_PARAM_ERROR); lua_pushboolean(vm, h->releaseAlert(std::string(key), periodicity)); - - return(CONST_LUA_OK); + + return(CONST_LUA_OK); +} + +/* ****************************************** */ + +static int ntop_network_get_cached_alert_value(lua_State* vm) { + struct ntopngLuaContext *c = getLuaVMContext(vm); + NetworkStats *ns = c ? c->network : NULL; + char *key; + std::string val; + ScriptPeriodicity periodicity; + + ntop->getTrace()->traceEvent(TRACE_DEBUG, "%s() called", __FUNCTION__); + + if(!ns) return(CONST_LUA_ERROR); + + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); + + if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((periodicity = (ScriptPeriodicity)lua_tonumber(vm, 2)) >= MAX_NUM_PERIODIC_SCRIPTS) return(CONST_LUA_PARAM_ERROR); + + val = ns->getAlertCachedValue(std::string(key), periodicity); + lua_pushstring(vm, val.c_str()); + + return(CONST_LUA_OK); +} + +/* ****************************************** */ + +static int ntop_network_set_cached_alert_value(lua_State* vm) { + struct ntopngLuaContext *c = getLuaVMContext(vm); + NetworkStats *ns = c ? c->network : NULL; + char *key, *value; + ScriptPeriodicity periodicity; + + ntop->getTrace()->traceEvent(TRACE_DEBUG, "%s() called", __FUNCTION__); + + if(!ns) return(CONST_LUA_ERROR); + + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); + + if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((value = (char*)lua_tostring(vm, 2)) == NULL) return(CONST_LUA_PARAM_ERROR); + + if(ntop_lua_check(vm, __FUNCTION__, 3, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((periodicity = (ScriptPeriodicity)lua_tonumber(vm, 3)) >= MAX_NUM_PERIODIC_SCRIPTS) return(CONST_LUA_PARAM_ERROR); + + if((!key) || (!value)) + return(CONST_LUA_PARAM_ERROR); + + ns->setAlertCacheValue(std::string(key), std::string(value), periodicity); + + return(CONST_LUA_OK); +} + +/* ****************************************** */ + +static int ntop_network_store_triggered_alert(lua_State* vm) { + struct ntopngLuaContext *c = getLuaVMContext(vm); + NetworkStats *ns = c ? c->network : NULL; + char *key = NULL; + ScriptPeriodicity periodicity; + + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); + + if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((periodicity = (ScriptPeriodicity)lua_tonumber(vm, 2)) >= MAX_NUM_PERIODIC_SCRIPTS) return(CONST_LUA_PARAM_ERROR); + + if((!ns) || (!key)) return(CONST_LUA_PARAM_ERROR); + + lua_pushboolean(vm, ns->triggerAlert(std::string(key), periodicity)); + + return(CONST_LUA_OK); +} + +/* ****************************************** */ + +static int ntop_network_release_triggered_alert(lua_State* vm) { + struct ntopngLuaContext *c = getLuaVMContext(vm); + NetworkStats *ns = c ? c->network : NULL; + char *key = NULL; + ScriptPeriodicity periodicity; + + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); + + if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); + if((periodicity = (ScriptPeriodicity)lua_tonumber(vm, 2)) >= MAX_NUM_PERIODIC_SCRIPTS) return(CONST_LUA_PARAM_ERROR); + + if((!ns) || (!key)) return(CONST_LUA_PARAM_ERROR); + lua_pushboolean(vm, ns->releaseAlert(std::string(key), periodicity)); + + return(CONST_LUA_OK); } /* ****************************************** */ @@ -8064,7 +8175,7 @@ static int ntop_interface_get_cached_alert_value(lua_State* vm) { char *key; std::string val; ScriptPeriodicity periodicity; - + ntop->getTrace()->traceEvent(TRACE_DEBUG, "%s() called", __FUNCTION__); if(!c->iface) return(CONST_LUA_ERROR); @@ -8074,10 +8185,10 @@ static int ntop_interface_get_cached_alert_value(lua_State* vm) { if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); if((periodicity = (ScriptPeriodicity)lua_tonumber(vm, 2)) >= MAX_NUM_PERIODIC_SCRIPTS) return(CONST_LUA_PARAM_ERROR); - + val = c->iface->getAlertCachedValue(std::string(key), periodicity); lua_pushstring(vm, val.c_str()); - + return(CONST_LUA_OK); } @@ -8087,7 +8198,7 @@ static int ntop_interface_set_cached_alert_value(lua_State* vm) { struct ntopngLuaContext *c = getLuaVMContext(vm); char *key, *value; ScriptPeriodicity periodicity; - + ntop->getTrace()->traceEvent(TRACE_DEBUG, "%s() called", __FUNCTION__); if(!c->iface) return(CONST_LUA_ERROR); @@ -8103,30 +8214,30 @@ static int ntop_interface_set_cached_alert_value(lua_State* vm) { if((!key) || (!value)) return(CONST_LUA_PARAM_ERROR); - + c->iface->setAlertCacheValue(std::string(key), std::string(value), periodicity); - + return(CONST_LUA_OK); } - + /* ****************************************** */ static int ntop_interface_store_triggered_alert(lua_State* vm) { struct ntopngLuaContext *c = getLuaVMContext(vm); char *key = NULL; ScriptPeriodicity periodicity; - + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); - + if(ntop_lua_check(vm, __FUNCTION__, 2, LUA_TNUMBER) != CONST_LUA_OK) return(CONST_LUA_ERROR); if((periodicity = (ScriptPeriodicity)lua_tonumber(vm, 2)) >= MAX_NUM_PERIODIC_SCRIPTS) return(CONST_LUA_PARAM_ERROR); - + if((!c->iface) || (!key)) return(CONST_LUA_PARAM_ERROR); lua_pushboolean(vm, c->iface->triggerAlert(std::string(key), periodicity)); - - return(CONST_LUA_OK); + + return(CONST_LUA_OK); } /* ****************************************** */ @@ -8135,7 +8246,7 @@ static int ntop_interface_release_triggered_alert(lua_State* vm) { struct ntopngLuaContext *c = getLuaVMContext(vm); char *key = NULL; ScriptPeriodicity periodicity; - + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_ERROR); if((key = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); @@ -8144,8 +8255,8 @@ static int ntop_interface_release_triggered_alert(lua_State* vm) { if((!c->iface) || (!key)) return(CONST_LUA_PARAM_ERROR); lua_pushboolean(vm, c->iface->releaseAlert(std::string(key), periodicity)); - - return(CONST_LUA_OK); + + return(CONST_LUA_OK); } /* ****************************************** */ @@ -8734,7 +8845,7 @@ static const luaL_Reg ntop_interface_reg[] = { { "getHostCountry", ntop_get_interface_host_country }, { "getGroupedHosts", ntop_get_grouped_interface_hosts }, { "addMacsIpAddresses", ntop_add_macs_ip_addresses }, - { "getNetworksStats", ntop_get_interface_networks_stats }, + { "getNetworksStats", ntop_get_interface_networks_stats }, { "checkpointHostTalker", ntop_checkpoint_host_talker }, { "getFlowsInfo", ntop_get_interface_flows_info }, { "getGroupedFlows", ntop_get_interface_get_grouped_flows }, @@ -8898,11 +9009,11 @@ static const luaL_Reg ntop_interface_reg[] = { /* **************************************************************** */ static const luaL_Reg ntop_host_reg[] = { - { "getInfo", ntop_host_get_basic_fields }, - { "getFullInfo", ntop_host_get_all_fields }, - { "getCachedAlertValue", ntop_host_get_cached_alert_value }, - { "setCachedAlertValue", ntop_host_set_cached_alert_value }, - { "storeTriggerAlert", ntop_host_store_triggered_alert }, + { "getInfo", ntop_host_get_basic_fields }, + { "getFullInfo", ntop_host_get_all_fields }, + { "getCachedAlertValue", ntop_host_get_cached_alert_value }, + { "setCachedAlertValue", ntop_host_set_cached_alert_value }, + { "storeTriggerAlert", ntop_host_store_triggered_alert }, { "releaseTriggeredAlert", ntop_host_release_triggered_alert }, { NULL, NULL } @@ -8911,10 +9022,11 @@ static const luaL_Reg ntop_host_reg[] = { /* **************************************************************** */ static const luaL_Reg ntop_network_reg[] = { - // { "getCachedAlertValue", ntop_network_get_cached_alert_value }, - // { "setCachedAlertValue", ntop_network_set_cached_alert_value }, - // { "storeTriggerAlert", ntop_network_store_triggered_alert }, - // { "releaseTriggeredAlert", ntop_network_release_triggered_alert }, + { "getNetworkStats", ntop_get_interface_network_stats }, + { "getCachedAlertValue", ntop_network_get_cached_alert_value }, + { "setCachedAlertValue", ntop_network_set_cached_alert_value }, + { "storeTriggerAlert", ntop_network_store_triggered_alert }, + { "releaseTriggeredAlert", ntop_network_release_triggered_alert }, { NULL, NULL } }; diff --git a/src/NetworkInterface.cpp b/src/NetworkInterface.cpp index 63bd75e93f..eadc385b11 100644 --- a/src/NetworkInterface.cpp +++ b/src/NetworkInterface.cpp @@ -5054,20 +5054,17 @@ void NetworkInterface::getFlowsStats(lua_State* vm) { lua_insert(vm, -2); lua_settable(vm, -3); } + /* **************************************************** */ -void NetworkInterface::getNetworksStats(lua_State* vm) { +void NetworkInterface::getNetworkStats(lua_State* vm, u_int8_t network_id) const { NetworkStats *network_stats; - u_int8_t num_local_networks = ntop->getNumLocalNetworks(); - lua_newtable(vm); - for(u_int8_t network_id = 0; network_id < num_local_networks; network_id++) { - network_stats = getNetworkStats(network_id); - // do not add stats of networks that have not generated any traffic - if(!network_stats || !network_stats->trafficSeen()) - continue; + if((network_stats = getNetworkStats(network_id)) && network_stats->trafficSeen()) { lua_newtable(vm); + network_stats->lua(vm); + lua_push_int32_table_entry(vm, "network_id", network_id); lua_pushstring(vm, ntop->getLocalNetworkName(network_id)); lua_insert(vm, -2); @@ -5077,6 +5074,17 @@ void NetworkInterface::getNetworksStats(lua_State* vm) { /* **************************************************** */ +void NetworkInterface::getNetworksStats(lua_State* vm) const { + u_int8_t num_local_networks = ntop->getNumLocalNetworks(); + + lua_newtable(vm); + + for(u_int8_t network_id = 0; network_id < num_local_networks; network_id++) + getNetworkStats(vm, network_id); +} + +/* **************************************************** */ + u_int NetworkInterface::purgeIdleFlows() { u_int n = 0; time_t last_packet_time = getTimeLastPktRcvd(); @@ -6079,11 +6087,14 @@ void NetworkInterface::allocateNetworkStats() { oom_warning_sent = true; } } + + for(u_int8_t i = 0; i < numNetworks; i++) + networkStats[i].setNetworkId(i); } /* **************************************** */ -NetworkStats* NetworkInterface::getNetworkStats(u_int8_t networkId) { +NetworkStats* NetworkInterface::getNetworkStats(u_int8_t networkId) const { if((networkStats == NULL) || (networkId >= ntop->getNumLocalNetworks())) return(NULL); else diff --git a/src/NetworkStats.cpp b/src/NetworkStats.cpp index b077a369b0..410ec66743 100644 --- a/src/NetworkStats.cpp +++ b/src/NetworkStats.cpp @@ -23,12 +23,16 @@ /* *************************************** */ -NetworkStats::NetworkStats() { +NetworkStats::NetworkStats() : AlertableEntity() { + network_id = 0; } /* *************************************** */ void NetworkStats::lua(lua_State* vm) { + lua_push_str_table_entry(vm, "network_key", ntop->getLocalNetworkName(network_id)); + lua_push_uint64_table_entry(vm, "network_id", network_id); + lua_push_uint64_table_entry(vm, "ingress", ingress.getNumBytes()); lua_push_uint64_table_entry(vm, "egress", egress.getNumBytes()); lua_push_uint64_table_entry(vm, "inner", inner.getNumBytes());