Implements user script for device connection/disconnection alerts

Addresses #4614
This commit is contained in:
Simone Mainardi 2020-10-22 14:27:26 +02:00
parent 0c7429bc2f
commit f65aa2bc19
6 changed files with 165 additions and 130 deletions

View file

@ -1448,122 +1448,12 @@ end
-- #################################
-- A redis set with mac addresses as keys
local function getActiveDevicesHashKey(ifid)
function alert_utils.getActiveDevicesHashKey(ifid)
return "ntopng.cache.active_devices.ifid_" .. ifid
end
function alert_utils.deleteActiveDevicesKey(ifid)
ntop.delCache(getActiveDevicesHashKey(ifid))
end
-- #################################
local function getSavedDeviceNameKey(mac)
return "ntopng.cache.devnames." .. mac
end
local function setSavedDeviceName(mac, name)
local key = getSavedDeviceNameKey(mac)
ntop.setCache(key, name)
end
function getSavedDeviceName(mac)
local key = getSavedDeviceNameKey(mac)
return ntop.getCache(key)
end
function alert_utils.check_macs_alerts(ifid)
local alert_new_devices_enabled = ntop.getPref("ntopng.prefs.alerts.device_first_seen_alert") == "1"
local alert_device_connection_enabled = ntop.getPref("ntopng.prefs.alerts.device_connection_alert") == "1"
local active_devices_set = getActiveDevicesHashKey(ifid)
local prev_active_devices = swapKeysValues(ntop.getMembersCache(active_devices_set) or {})
local num_prev_active_devices = table.len(prev_active_devices)
local seen_devices_hash = getFirstSeenDevicesHashKey(ifid)
local seen_devices = ntop.getHashAllCache(seen_devices_hash) or {}
local num_seen_devices = table.len(seen_devices)
local max_active_devices_cardinality = 16384
if(num_seen_devices >= max_active_devices_cardinality) then
traceError(TRACE_INFO, TRACE_CONSOLE, string.format("Too many active devices, discarding %u devices", num_seen_devices))
ntop.delCache(active_devices_set)
prev_active_devices = {}
end
local active_devices = {}
callback_utils.foreachDevice(getInterfaceName(ifid), function(devicename, devicestats, devicebase)
-- note: location is always lan when capturing from a local interface
if (not devicestats.special_mac) and (devicestats.location == "lan") then
local mac = devicestats.mac
active_devices[mac] = 1
if not seen_devices[mac] then
-- First time we see a device
ntop.setHashCache(seen_devices_hash, mac, tostring(os.time()))
if alert_new_devices_enabled then
local name = getDeviceName(mac)
setSavedDeviceName(mac, name)
alerts_api.store(
alerts_api.macEntity(mac),
alert_consts.alert_types.alert_new_device.create(
alert_consts.alert_severities.warning,
name
)
)
end
end
if not prev_active_devices[mac] then
-- Device connection
ntop.setMembersCache(active_devices_set, mac)
-- Do not nofify new connected devices if the prev_active_devices
-- set was empty (cleared or on startup)
if num_prev_active_devices > 0 then
if alert_device_connection_enabled then
local name = getDeviceName(mac)
setSavedDeviceName(mac, name)
alerts_api.store(
alerts_api.macEntity(mac),
alert_consts.alert_types.alert_device_connection.create(
alert_consts.alert_severities.notice,
name
)
)
end
end
end
end
end)
-- Safety check to avoid notifying disconnected devices
-- during shutdown when they are no longer active in ntopng.
if not ntop.isShutdown() then
for mac in pairs(prev_active_devices) do
if not active_devices[mac] then
-- Device disconnection
local name = getSavedDeviceName(mac)
ntop.delMembersCache(active_devices_set, mac)
if alert_device_connection_enabled then
alerts_api.store(
alerts_api.macEntity(mac),
alert_consts.alert_types.alert_device_disconnection.create(
alert_consts.alert_severities.notice,
name
)
)
end
end
end
end
ntop.delCache(alert_utils.getActiveDevicesHashKey(ifid))
end
-- #################################