Fixes asn message label (#9322)

This commit is contained in:
Matteo Biscosi 2025-07-02 10:36:11 +02:00
parent 79b3a92d87
commit 705050938f
7 changed files with 217 additions and 183 deletions

View file

@ -1,7 +1,6 @@
--
-- (C) 2013-25 - ntop.org
--
--
-- Logic implemented.
-- Example for a given router 1.2.3.4 the flows below are rcvd
@ -18,8 +17,6 @@
-- ASN 34978 = { rcvd = 594, sent = 60 }
-- ASN 12337 = { rcvd = 60, sent = 594 }
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
@ -41,31 +38,26 @@ local rsp = {}
local edges = {}
local nodes = {}
local traffic_criteria = {
INGRESS = 0,
EGRESS = 1,
TOTAL = 2,
ING_EGR = 3,
}
local traffic_criteria = {INGRESS = 0, EGRESS = 1, TOTAL = 2, ING_EGR = 3}
local criteria
if criteria_as == "egress_traffic_criteria" then
criteria = traffic_criteria.EGRESS
criteria = traffic_criteria.EGRESS
elseif criteria_as == "total_traffic_criteria" then
criteria = traffic_criteria.TOTAL
criteria = traffic_criteria.TOTAL
elseif criteria_as == "ingress_traffic_criteria" then
criteria = traffic_criteria.INGRESS
criteria = traffic_criteria.INGRESS
else
criteria = traffic_criteria.ING_EGR
criteria = traffic_criteria.ING_EGR
end
-- ################################################
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
-- ################################################
@ -75,21 +67,19 @@ local last_node_id = 0
local debug = false
function find_node_id(node)
local rc = node_ids[node]
local rc = node_ids[node]
if (rc == nil) then
rc = last_node_id .. ""
last_node_id = last_node_id + 1
node_ids[node] = rc
if (rc == nil) then
rc = last_node_id .. ""
last_node_id = last_node_id + 1
node_ids[node] = rc
if (debug) then
tprint("Adding " .. node .. " as " .. rc)
end
if (debug) then tprint("Adding " .. node .. " as " .. rc) end
return (rc)
else
return (rc)
end
return (rc)
else
return (rc)
end
end
-- ################################################
@ -102,24 +92,21 @@ local as_root_key = "root";
local max_len = 32
table.insert(nodes, {
link = "/",
node_id = as_root_key,
label = "ASN "..asn.." ("..shortenString(interface.getASInfo(asn).asname, max_len)..")"
link = "/",
node_id = as_root_key,
label = format_utils.formatASN(asn)
})
-- ####################
local function add_unique_node(node_id, label, link)
if not node_set[node_id] then
table.insert(nodes, { node_id = node_id, label = label, link = link })
node_set[node_id] = true
end
if not node_set[node_id] then
table.insert(nodes, {node_id = node_id, label = label, link = link})
node_set[node_id] = true
end
end
local function reset_nodes()
node_set={}
end
local function reset_nodes() node_set = {} end
-- ####################
@ -128,185 +115,206 @@ end
local tot_bytes_exporter = {}
local function init_exporter(device_ip)
local key = device_ip
if not tot_bytes_exporter[key] then
tot_bytes_exporter[key] = { sent = 0, rcvd = 0 }
end
local key = device_ip
if not tot_bytes_exporter[key] then
tot_bytes_exporter[key] = {sent = 0, rcvd = 0}
end
end
local function inc_exporter_sent(key, bytes)
tot_bytes_exporter[key].sent = tot_bytes_exporter[key].sent + bytes
end
tot_bytes_exporter[key].sent = tot_bytes_exporter[key].sent + bytes
end
local function inc_exporter_rcvd(key, bytes)
tot_bytes_exporter[key].rcvd = tot_bytes_exporter[key].rcvd + bytes
end
tot_bytes_exporter[key].rcvd = tot_bytes_exporter[key].rcvd + bytes
end
-- Total bytes sent/rcvd per exporter/interface (key = <device ip>@<if index>)
local tot_bytes_exp_if = {}
local function get_interface_key(device_ip, interface_index)
return device_ip .. "@" .. interface_index
return device_ip .. "@" .. interface_index
end
local function init_interface(device_ip, interface_index)
local key = get_interface_key(device_ip, interface_index)
if not tot_bytes_exp_if[key] then
tot_bytes_exp_if[key] = { sent = 0, rcvd = 0, exporter_ip = device_ip, port_index = interface_index }
end
local key = get_interface_key(device_ip, interface_index)
if not tot_bytes_exp_if[key] then
tot_bytes_exp_if[key] = {
sent = 0,
rcvd = 0,
exporter_ip = device_ip,
port_index = interface_index
}
end
end
local function inc_interface_sent(key, bytes)
tot_bytes_exp_if[key].sent = tot_bytes_exp_if[key].sent + bytes
tot_bytes_exp_if[key].sent = tot_bytes_exp_if[key].sent + bytes
end
local function inc_interface_rcvd(key, bytes)
tot_bytes_exp_if[key].rcvd = tot_bytes_exp_if[key].rcvd + bytes
tot_bytes_exp_if[key].rcvd = tot_bytes_exp_if[key].rcvd + bytes
end
local function build_interface_exporter(criteria, tot_bytes_exp_if, exporter_nodes)
for n_id, data in pairs(tot_bytes_exp_if) do
if (criteria == traffic_criteria.INGRESS and data.sent > 0) or
(criteria == traffic_criteria.EGRESS and data.rcvd > 0) or
(criteria == traffic_criteria.TOTAL and (data.rcvd + data.sent) > 0) then
--tprint(n_id .. " " .. criteria .. " " .. data.sent .. " " .. data.rcvd)
local exporter_ip = getProbeName(data.exporter_ip)
local port_index = format_portidx_name(data.exporter_ip, data.port_index, true) or "?"
local exporter_node_id = find_node_id(exporter_ip)
local port_node_id = find_node_id(n_id)
if criteria == traffic_criteria.EGRESS then
exporter_node_id = "egress".."_"..exporter_node_id
port_node_id = "egress".."_"..port_node_id
else
exporter_node_id = "ingress".."_"..exporter_node_id
port_node_id = "ingress".."_"..port_node_id
end
if(exporter_nodes[data.exporter_ip] == nil) then exporter_nodes[data.exporter_ip] = exporter_node_id end
add_unique_node(exporter_node_id, exporter_ip, "#")
add_unique_node(port_node_id, port_index, "#")
local function build_interface_exporter(criteria, tot_bytes_exp_if,
exporter_nodes)
for n_id, data in pairs(tot_bytes_exp_if) do
if (criteria == traffic_criteria.INGRESS and data.sent > 0) or
(criteria == traffic_criteria.EGRESS and data.rcvd > 0) or
(criteria == traffic_criteria.TOTAL and (data.rcvd + data.sent) > 0) then
-- tprint(n_id .. " " .. criteria .. " " .. data.sent .. " " .. data.rcvd)
local exporter_ip = getProbeName(data.exporter_ip)
local port_index = format_portidx_name(data.exporter_ip,
data.port_index, true) or "?"
local exporter_node_id = find_node_id(exporter_ip)
local port_node_id = find_node_id(n_id)
if criteria == traffic_criteria.INGRESS then
-- Interface -> Exporter
table.insert(links, {
source_node_id = port_node_id,
target_node_id = exporter_node_id,
label = bytesToSize(data.sent),
value = data.sent
})
elseif criteria == traffic_criteria.EGRESS then
-- Exporter -> Interface
table.insert(links, {
source_node_id = exporter_node_id,
target_node_id = port_node_id,
label = bytesToSize(data.rcvd),
value = data.rcvd
})
elseif criteria == traffic_criteria.TOTAL then
-- Interface -> Exporter
table.insert(links, {
source_node_id = port_node_id,
target_node_id = exporter_node_id,
label = bytesToSize(data.rcvd+data.sent),
value = data.rcvd + data.sent
})
end
if criteria == traffic_criteria.EGRESS then
exporter_node_id = "egress" .. "_" .. exporter_node_id
port_node_id = "egress" .. "_" .. port_node_id
else
exporter_node_id = "ingress" .. "_" .. exporter_node_id
port_node_id = "ingress" .. "_" .. port_node_id
end
end
end
if (exporter_nodes[data.exporter_ip] == nil) then
exporter_nodes[data.exporter_ip] = exporter_node_id
end
add_unique_node(exporter_node_id, exporter_ip, "#")
add_unique_node(port_node_id, port_index, "#")
if criteria == traffic_criteria.INGRESS then
-- Interface -> Exporter
table.insert(links, {
source_node_id = port_node_id,
target_node_id = exporter_node_id,
label = bytesToSize(data.sent),
value = data.sent
})
elseif criteria == traffic_criteria.EGRESS then
-- Exporter -> Interface
table.insert(links, {
source_node_id = exporter_node_id,
target_node_id = port_node_id,
label = bytesToSize(data.rcvd),
value = data.rcvd
})
elseif criteria == traffic_criteria.TOTAL then
-- Interface -> Exporter
table.insert(links, {
source_node_id = port_node_id,
target_node_id = exporter_node_id,
label = bytesToSize(data.rcvd + data.sent),
value = data.rcvd + data.sent
})
end
end
end
end
local function build_exporter_as(criteria, exporter_nodes)
for exporter_ip, exporter_node_id in pairs(exporter_nodes) do
local sent = tot_bytes_exporter[exporter_ip].sent
local rcvd = tot_bytes_exporter[exporter_ip].rcvd
for exporter_ip, exporter_node_id in pairs(exporter_nodes) do
local sent = tot_bytes_exporter[exporter_ip].sent
local rcvd = tot_bytes_exporter[exporter_ip].rcvd
if criteria == traffic_criteria.INGRESS and sent > 0 then
-- Exporter -> AS
table.insert(links, {
source_node_id = exporter_node_id,
target_node_id = as_root_key,
label = bytesToSize(sent),
value = sent
})
elseif criteria == traffic_criteria.EGRESS and rcvd > 0 then
-- AS -> Exporter
table.insert(links, {
source_node_id = as_root_key,
target_node_id = exporter_node_id,
label = bytesToSize(rcvd),
value = rcvd
})
elseif criteria == traffic_criteria.TOTAL then
-- Exporter -> AS
table.insert(links, {
source_node_id = exporter_node_id,
target_node_id = as_root_key,
label = bytesToSize(rcvd+sent),
value1 = rcvd + sent
})
end
end
if criteria == traffic_criteria.INGRESS and sent > 0 then
-- Exporter -> AS
table.insert(links, {
source_node_id = exporter_node_id,
target_node_id = as_root_key,
label = bytesToSize(sent),
value = sent
})
elseif criteria == traffic_criteria.EGRESS and rcvd > 0 then
-- AS -> Exporter
table.insert(links, {
source_node_id = as_root_key,
target_node_id = exporter_node_id,
label = bytesToSize(rcvd),
value = rcvd
})
elseif criteria == traffic_criteria.TOTAL then
-- Exporter -> AS
table.insert(links, {
source_node_id = exporter_node_id,
target_node_id = as_root_key,
label = bytesToSize(rcvd + sent),
value1 = rcvd + sent
})
end
end
end
-- Flow iterator callback
function callback (_, flow)
if(debug) then
-- tprint(flow.bytes_sent .. " / " .. flow.bytes_rcvd)
tprint("[AS] "..flow.src_as .. " -> " .. flow.dst_as.. " | [IDX] ".. flow.in_index .. " -> " .. flow.out_index .. " | ".. flow.bytes_sent .. " / " .. flow.bytes_rcvd)
end
function callback(_, flow)
if (debug) then
-- tprint(flow.bytes_sent .. " / " .. flow.bytes_rcvd)
tprint("[AS] " .. flow.src_as .. " -> " .. flow.dst_as .. " | [IDX] " ..
flow.in_index .. " -> " .. flow.out_index .. " | " ..
flow.bytes_sent .. " / " .. flow.bytes_rcvd)
end
-- Initialize hash entries if not yet popupated
init_exporter(flow.device_ip)
init_interface(flow.device_ip, flow.in_index)
init_interface(flow.device_ip, flow.out_index)
-- Initialize hash entries if not yet popupated
init_exporter(flow.device_ip)
init_interface(flow.device_ip, flow.in_index)
init_interface(flow.device_ip, flow.out_index)
if(flow.src_as == asn) then
inc_interface_sent(get_interface_key(flow.device_ip, flow.in_index), flow.bytes_rcvd)
inc_interface_rcvd(get_interface_key(flow.device_ip, flow.in_index), flow.bytes_sent)
inc_exporter_sent(flow.device_ip, flow.bytes_rcvd)
inc_exporter_rcvd(flow.device_ip, flow.bytes_sent)
elseif(flow.dst_as == asn) then
inc_interface_sent(get_interface_key(flow.device_ip, flow.out_index), flow.bytes_sent)
inc_interface_rcvd(get_interface_key(flow.device_ip, flow.out_index), flow.bytes_rcvd)
inc_exporter_sent(flow.device_ip, flow.bytes_sent)
inc_exporter_rcvd(flow.device_ip, flow.bytes_rcvd)
end
if (flow.src_as == asn) then
inc_interface_sent(get_interface_key(flow.device_ip, flow.in_index),
flow.bytes_rcvd)
inc_interface_rcvd(get_interface_key(flow.device_ip, flow.in_index),
flow.bytes_sent)
inc_exporter_sent(flow.device_ip, flow.bytes_rcvd)
inc_exporter_rcvd(flow.device_ip, flow.bytes_sent)
elseif (flow.dst_as == asn) then
inc_interface_sent(get_interface_key(flow.device_ip, flow.out_index),
flow.bytes_sent)
inc_interface_rcvd(get_interface_key(flow.device_ip, flow.out_index),
flow.bytes_rcvd)
inc_exporter_sent(flow.device_ip, flow.bytes_sent)
inc_exporter_rcvd(flow.device_ip, flow.bytes_rcvd)
end
end
local flows_filter = { asnFilter = asn, detailsLevel = "normal", maxHits = 10000, perPage = 10000 }
local flows_filter = {
asnFilter = asn,
detailsLevel = "normal",
maxHits = 10000,
perPage = 10000
}
callback_utils.foreachFlow(ifid,
os.time()+30, -- deadline
callback, flows_filter)
callback_utils.foreachFlow(ifid, os.time() + 30, -- deadline
callback, flows_filter)
-- ###################################################
if(debug) then
tprint(tot_bytes_exp_if)
tprint(tot_bytes_exporter)
if (debug) then
tprint(tot_bytes_exp_if)
tprint(tot_bytes_exporter)
end
local exporter_nodes = {}
if(criteria ~= traffic_criteria.ING_EGR) then
-- Build Interface <-> Exporter links
build_interface_exporter(criteria, tot_bytes_exp_if, exporter_nodes)
-- Build Exporter <-> AS links
build_exporter_as(criteria, exporter_nodes)
if (criteria ~= traffic_criteria.ING_EGR) then
-- Build Interface <-> Exporter links
build_interface_exporter(criteria, tot_bytes_exp_if, exporter_nodes)
-- Build Exporter <-> AS links
build_exporter_as(criteria, exporter_nodes)
else
-- Ingress
build_interface_exporter(traffic_criteria.INGRESS, tot_bytes_exp_if, exporter_nodes)
build_exporter_as(traffic_criteria.INGRESS, exporter_nodes)
reset_nodes()
exporter_nodes = {}
-- Ingress
build_interface_exporter(traffic_criteria.INGRESS, tot_bytes_exp_if,
exporter_nodes)
build_exporter_as(traffic_criteria.INGRESS, exporter_nodes)
-- Egress
build_interface_exporter(traffic_criteria.EGRESS, tot_bytes_exp_if, exporter_nodes)
build_exporter_as(traffic_criteria.EGRESS, exporter_nodes)
reset_nodes()
exporter_nodes = {}
-- Egress
build_interface_exporter(traffic_criteria.EGRESS, tot_bytes_exp_if,
exporter_nodes)
build_exporter_as(traffic_criteria.EGRESS, exporter_nodes)
end
rsp["nodes"] = nodes
rsp["links"] = links