mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-30 07:59:35 +00:00
362 lines
11 KiB
Lua
362 lines
11 KiB
Lua
--
|
|
-- (C) 2018 - ntop.org
|
|
--
|
|
|
|
dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/?.lua;" .. package.path
|
|
if((dirs.scriptdir ~= nil) and (dirs.scriptdir ~= "")) then package.path = dirs.scriptdir .. "/lua/modules/?.lua;" .. package.path end
|
|
ignore_post_payload_parse = 1
|
|
require "lua_utils"
|
|
|
|
local network_state = {}
|
|
local if_stats = interface.getStats()
|
|
|
|
--------------------------------------------------------------------------------------------------------------
|
|
|
|
function network_state.getUpTime()
|
|
return secondsToTime( ntop.getUpTime() )
|
|
end
|
|
|
|
--return ndpi categoty table [ "category_name" = "bytes" ]
|
|
function network_state.check_ndpi_categories()
|
|
local t = {}
|
|
|
|
for i,v in pairs(if_stats.ndpi_categories) do
|
|
t[tostring(i)] = if_stats.ndpi_categories[i].bytes
|
|
end
|
|
|
|
return t
|
|
end
|
|
|
|
--makes the sum of "i1" and "i2" for each ndpi proto
|
|
--return ndpi proto table [ "proto_name" = "i1 + i2" ]
|
|
function network_state.check_ndpi_table(i1, i2)
|
|
local t, ndpi_stats = {}, interface.getnDPIStats()
|
|
local j = 1
|
|
for i,v in pairs( ndpi_stats.ndpi ) do
|
|
|
|
t[j] = { tostring(i), v[i1] }
|
|
if (i2 ~= nil) then t[j][2] = t[j][2] + v[i2] end
|
|
j = j + 1
|
|
end
|
|
|
|
return t
|
|
end
|
|
|
|
|
|
function network_state.check_traffic_categories()
|
|
local traffic = network_state.check_ndpi_categories()
|
|
local tot = 1
|
|
local res = {}
|
|
|
|
for i,v in pairs(traffic) do
|
|
tot = tot + v
|
|
end
|
|
|
|
for i,v in pairs(traffic) do
|
|
table.insert( res, {name = i, perc = math.floor(( v / tot ) * 1000) / 10 } )
|
|
end
|
|
|
|
function compare(a, b) return a.perc > b.perc end
|
|
|
|
table.sort( res, compare )
|
|
|
|
return res
|
|
end
|
|
|
|
--return the name and percentage of the ndpi proto that has generated more traffic
|
|
function network_state.check_top_traffic_application_protocol_categories()
|
|
local traffic = network_state.check_ndpi_categories()
|
|
local name, max, perc, tot = "non specificato", 0, 0, 1
|
|
|
|
for i,v in pairs(traffic) do
|
|
tot = tot + v
|
|
if max < v then
|
|
name, max = i, v
|
|
end
|
|
end
|
|
perc = math.floor(( max / tot ) * 100)
|
|
return name, perc
|
|
end
|
|
|
|
|
|
--return an array-table of all ndpi_proto_name and traffic percentage
|
|
function network_state.check_top_application_protocol()
|
|
local t, tot = {}, 1
|
|
local proto_app = network_state.check_ndpi_table("bytes.sent", "bytes.rcvd" )
|
|
for i,v in pairs(proto_app) do tot = tot + v[2] end
|
|
|
|
|
|
function compare(a,b) return a[2]>b[2] end
|
|
table.sort(proto_app, compare)
|
|
|
|
|
|
local c, res = 0, {}
|
|
|
|
for i,v in pairs(proto_app) do
|
|
|
|
local prc = math.floor( (v[2] / tot) * 100 )
|
|
c = c + 1
|
|
res[c] = { v[1] , prc }
|
|
|
|
end
|
|
return res
|
|
end
|
|
|
|
--return table with some interface stats
|
|
function network_state.check_ifstats_table()
|
|
local t = {
|
|
device_num = if_stats.stats.devices,
|
|
flow_num = if_stats.stats.flows,
|
|
host_num = if_stats.stats.hosts,
|
|
total_bytes = if_stats.stats.bytes,
|
|
local_host_num = if_stats.stats.local_hosts,
|
|
device_num = if_stats.stats.devices
|
|
}
|
|
return t
|
|
end
|
|
|
|
function network_state.check_devices_type()
|
|
local discover = require "discover_utils"
|
|
local res= {}
|
|
|
|
for i,v in pairs(interface.getMacDeviceTypes() ) do
|
|
res[discover.devtype2string(i)] = v
|
|
end
|
|
|
|
|
|
return res, if_stats.stats.devices
|
|
end
|
|
|
|
--return respectively: state of goodput, number of total flow, total number of bad goodput flow
|
|
function network_state.check_TCP_flow_goodput()
|
|
local bad_gp_client, bad_gp_server, flow_tot, prbl = 0,0,0,0
|
|
local seen, deadline = 0, os.time() + 3000
|
|
local group_of = 5
|
|
|
|
repeat
|
|
hoinfo = interface.getHostsInfo(true, "column_", group_of)
|
|
tot = hoinfo.numHosts
|
|
|
|
|
|
for i,v in pairs( hoinfo["hosts"] ) do
|
|
local afas, afac = hoinfo["hosts"][i]["active_flows.as_server"], hoinfo["hosts"][i]["active_flows.as_client"]
|
|
local bgc, bgs = hoinfo["hosts"][i]["low_goodput_flows.as_client"], hoinfo["hosts"][i]["low_goodput_flows.as_server"]
|
|
|
|
flow_tot = flow_tot + afac + afas
|
|
bad_gp_client = bad_gp_client + bgc
|
|
bad_gp_server = bad_gp_server + bgs
|
|
|
|
end
|
|
|
|
|
|
seen = seen + group_of
|
|
until (seen < tot) or (os.time() > deadline)
|
|
|
|
local perc, state = 100 - math.floor( (bad_gp_client + bad_gp_server) / flow_tot) * 100
|
|
if perc > 90 then
|
|
state = "complessivamente ottima"
|
|
elseif perc > 80 then
|
|
state = "complessivamente buona"
|
|
elseif perc > 70 then
|
|
state = "complessivamente mediocre"
|
|
else
|
|
state = "complessivamente bassa"
|
|
end
|
|
|
|
return state, flow_tot, (bad_gp_client + bad_gp_server)
|
|
end
|
|
|
|
--return a table with tot traffic, remote/local percentage and pkt drop
|
|
function network_state.check_net_communication()
|
|
|
|
local tot = if_stats.localstats.bytes.local2remote + if_stats.localstats.bytes.remote2local +
|
|
if_stats.localstats.bytes.remote2remote + if_stats.localstats.bytes.local2local
|
|
local t = {
|
|
total_traffic = tot,
|
|
prc_remote2local_traffic = math.floor((if_stats.localstats.bytes.remote2local / tot) * 100),
|
|
prc_local2remote_traffic = math.floor((if_stats.localstats.bytes.local2remote / tot) * 100),
|
|
prc_pkt_drop = math.floor( (if_stats.tcpPacketStats.lost / if_stats.stats.packets) * 100000 ) / 1000, --TODO: assicurarsi che "if_stats.stats.packets" si riferisca ai pacchetti tcp
|
|
num_pkt_drop = if_stats.tcpPacketStats.lost,
|
|
num_tot_pkt = if_stats.stats.packets
|
|
}
|
|
return t
|
|
|
|
end
|
|
|
|
--return a table ["breed_name" = "perentage of that breed"], number of blacklisted active host and a flag to report Dangerous traffic
|
|
function network_state.check_bad_hosts_and_app()
|
|
local blacklisted, danger_flag = 0, false
|
|
local callback = require "callback_utils"
|
|
|
|
local function mycallback( hostname, hoststats )
|
|
if hoststats.is_blacklisted then blacklisted = blacklisted + 1 end
|
|
end
|
|
callback.foreachHost(ifname, os.time()+5000, mycallback )
|
|
|
|
local j, breeds, tot, bytes = 1, {}, 0, 0
|
|
for i,v in pairs(if_stats["ndpi"]) do
|
|
bytes = if_stats["ndpi"][i]["bytes.sent"] + if_stats["ndpi"][i]["bytes.rcvd"]
|
|
breeds[j] ={ ["name"] = if_stats["ndpi"][i]["breed"], ["bytes"] = bytes }
|
|
tot = tot + bytes
|
|
j = j + 1
|
|
end
|
|
|
|
local res = {}
|
|
for i,v in ipairs(breeds) do
|
|
if res[ breeds[i]["name"] ] ~= nil then
|
|
res[breeds[i]["name"] ] = res[breeds[i]["name"] ] + breeds[i]["bytes"]
|
|
else
|
|
res[breeds[i]["name"] ] = breeds[i]["bytes"]
|
|
end
|
|
end
|
|
|
|
for i,v in pairs(res) do
|
|
|
|
if i == "Dangerous" then danger_flag = true end
|
|
|
|
res[i] = { perc = math.floor( (res[i] / tot) * 1000 ) / 10, bytes = v }
|
|
|
|
end
|
|
|
|
return res, blacklisted, danger_flag
|
|
end
|
|
|
|
|
|
|
|
function network_state.check_dangerous_traffic()
|
|
local res= {}
|
|
local tot_bytes = 0
|
|
|
|
for i,v in pairs(if_stats["ndpi"]) do
|
|
if v.breed == "Dangerous" then
|
|
|
|
tot_bytes = v["bytes.rcvd"] + v["bytes.sent"]
|
|
v["total_bytes"] = tot_bytes
|
|
v["name"] = i
|
|
table.insert( res, v )
|
|
end
|
|
end
|
|
|
|
if #res > 0 then
|
|
return res
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
|
|
|
|
------------------------ALERTS----------------------------
|
|
|
|
require "alert_utils"
|
|
|
|
function network_state.check_alerts()
|
|
local engaged_alerts = getAlerts("engaged", getTabParameters(_GET, "engaged"))
|
|
local past_alerts = getAlerts("historical", getTabParameters(_GET, "historical"))
|
|
local flow_alerts = getAlerts("historical-flows", getTabParameters(_GET, "historical-flows"))
|
|
|
|
return engaged_alerts, past_alerts, flow_alerts
|
|
end
|
|
|
|
|
|
function network_state.check_num_alerts_and_severity()
|
|
local num_engaged_alerts = getNumAlerts("engaged", getTabParameters(_GET, "engaged"))
|
|
local num_past_alerts = getNumAlerts("historical", getTabParameters(_GET, "historical"))
|
|
local num_flow_alerts = getNumAlerts("historical-flows", getTabParameters(_GET,"historical-flows"))
|
|
local engaged_alerts = getAlerts("engaged", getTabParameters(_GET, "engaged"))
|
|
local past_alerts = getAlerts("historical", getTabParameters(_GET, "historical"))
|
|
local flow_alerts = getAlerts("historical-flows", getTabParameters(_GET, "historical-flows"))
|
|
|
|
local severity = {} --severity: (none,) info, warning, error
|
|
local alert_num = num_engaged_alerts + num_past_alerts + num_flow_alerts
|
|
|
|
local function severity_cont(alerts, severity_table )
|
|
local severity_text = ""
|
|
|
|
for i,v in pairs(alerts) do
|
|
if v.alert_severity then
|
|
severity_text = alertSeverityLabel(v.alert_severity, true)
|
|
severity_table[severity_text] = (severity_table[severity_text] or 0) + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
if alert_num > 0 then
|
|
severity_cont(engaged_alerts, severity)
|
|
severity_cont( flow_alerts, severity)
|
|
severity_cont( past_alerts, severity)
|
|
end
|
|
|
|
return alert_num, severity
|
|
end
|
|
|
|
function network_state.alerts_details()
|
|
local engaged_alerts, past_alerts, flow_alerts = network_state.check_alerts()
|
|
local tmp_alerts, alerts = {}, {}
|
|
local limit= 3 --temporary limit, add effective selection criterion
|
|
|
|
j = 0
|
|
for i,v in pairs(engaged_alerts) do
|
|
if j < limit then
|
|
table.insert( tmp_alerts, v )
|
|
j = j+1
|
|
else break end
|
|
end
|
|
|
|
j = 0
|
|
for i,v in pairs(flow_alerts) do
|
|
if j < limit then
|
|
table.insert( tmp_alerts, v )
|
|
j = j+1
|
|
else break end
|
|
end
|
|
|
|
j = 0
|
|
for i,v in pairs(past_alerts) do
|
|
if j < limit then
|
|
table.insert( tmp_alerts, v )
|
|
j = j+1
|
|
else break end
|
|
end
|
|
|
|
local alert_type, rowid, t_stamp, srv_addr, srv_port, cli_addr, cli_port, severity, alert_json
|
|
|
|
for i,v in pairs(tmp_alerts) do
|
|
|
|
if v.alert_type then alert_type = alertTypeLabel( v.alert_type, true ) else alert_type = "Sconosciuto" end
|
|
if v.rowid then rowid = v.rowid else rowid = "Sconosciuto" end
|
|
if v.alert_tstamp then t_stamp = os.date( "%c", tonumber(v.alert_tstamp)) else t_stamp = "Sconosciuto" end
|
|
if v.srv_addr then srv_addr = v.srv_addr else srv_addr = "Sconosciuto" end
|
|
if v.srv_port then srv_port = v.srv_port else srv_port = "Sconosciuto" end
|
|
if v.cli_addr then cli_addr = v.cli_addr else cli_addr = "Sconosciuto" end
|
|
if v.cli_port then cli_port = v.cli_port else cli_port = "Sconosciuto" end
|
|
if v.alert_severity then severity = alertSeverityLabel(v.alert_severity, true) else severity = "Sconosciuto" end
|
|
if v.alert_json then alert_json = v.alert_json else alert_json = "Sconosciuto" end
|
|
|
|
local e = {
|
|
ID = rowid,
|
|
Tipo = alert_type,
|
|
Scattato = t_stamp,
|
|
Pericolosita = severity,
|
|
IP_Server = srv_addr,
|
|
Porta_Server = srv_port,
|
|
IP_Client = cli_addr,
|
|
Porta_Client = cli_port,
|
|
JSON_info = alert_json
|
|
}
|
|
|
|
table.insert( alerts, e )
|
|
end
|
|
|
|
if #alerts > 0 then
|
|
return alerts
|
|
else
|
|
return nil
|
|
end
|
|
|
|
end
|
|
|
|
------------------------------------------------------
|
|
|
|
|
|
return network_state
|