mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-02 00:40:10 +00:00
265 lines
7.7 KiB
Lua
265 lines
7.7 KiB
Lua
--
|
|
-- (C) 2020 - ntop.org
|
|
--
|
|
local dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/toasts/?.lua;" .. package.path
|
|
|
|
require "lua_utils"
|
|
require "flow_utils"
|
|
|
|
local page_utils = require("page_utils")
|
|
local ui_utils = require("ui_utils")
|
|
local template = require "template_utils"
|
|
local json = require "dkjson"
|
|
local ifs = interface.getStats()
|
|
|
|
sendHTTPContentTypeHeader('text/html')
|
|
|
|
local is_admin = isAdministrator()
|
|
local service_map = interface.serviceMap() or {}
|
|
|
|
if is_admin and (_GET["action"] == "reset") then
|
|
interface.flushServiceMap()
|
|
end
|
|
|
|
local function generate_graph(service_map, host_ip)
|
|
|
|
local nodes = {}
|
|
local proto_number = {}
|
|
local num_services = 0
|
|
|
|
for k,v in pairs(service_map) do
|
|
|
|
local key = ""
|
|
if ((host_ip == nil) or (v.client == host_ip) or (v.server == host_ip)) then
|
|
|
|
num_services = num_services + 1
|
|
nodes[v["client"]] = true
|
|
nodes[v["server"]] = true
|
|
|
|
if v["client"] > v["server"] then
|
|
key = v["client"] .. "," .. v["server"]
|
|
if proto_number[key] == nil then
|
|
proto_number[key] = { 1, false , v["client"], v["server"], v.l7_proto} -- { num_recurrencies, bidirection true | monodirectional false, client_ip, server_ip, l7_proto}
|
|
else
|
|
proto_number[key][1] = proto_number[key][1] + 1
|
|
|
|
-- Don't show more then 3 l7 protocols
|
|
if proto_number[key][1] <= 3 then
|
|
proto_number[key][5] = proto_number[key][5] .. ", " .. v.l7_proto
|
|
end
|
|
|
|
-- Checking direction of the service, false monodirectional and true bidirectional
|
|
if v["server"] ~= proto_number[key][4] then
|
|
proto_number[key][2] = true
|
|
end
|
|
end
|
|
else
|
|
key = v["server"] .. "," .. v["client"]
|
|
if proto_number[key] == nil then
|
|
proto_number[key] = { 1, false , v["client"], v["server"], v.l7_proto} -- { num_recurrencies, bidirection true | monodirectional false, client_ip, server_ip, l7_proto}
|
|
else
|
|
proto_number[key][1] = proto_number[key][1] + 1
|
|
|
|
-- Don't show more then 3 l7 protocols
|
|
if proto_number[key][1] <= 3 then
|
|
proto_number[key][5] = proto_number[key][5] .. ", " .. v.l7_proto
|
|
end
|
|
|
|
-- Checking direction of the service, false monodirectional and true bidirectional
|
|
if v["server"] ~= proto_number[key][4] then
|
|
proto_number[key][2] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
return nodes, proto_number, num_services
|
|
end
|
|
|
|
--- Generate nodes to be used by the js plugin
|
|
local function generate_ui_graph(map_nodes, saved_positions, proto_number)
|
|
|
|
local nodes_id = {}
|
|
local nodes = {}
|
|
local edges = {}
|
|
|
|
local i = 1
|
|
|
|
for k, _ in pairs(map_nodes) do
|
|
|
|
local hinfo = hostkey2hostinfo(k)
|
|
local label = shortenString(hostinfo2label(hinfo), 16)
|
|
local ainfo = interface.getAddressInfo(k)
|
|
local node = {id = k, value = k, label = label}
|
|
|
|
if (ainfo.is_multicast or ainfo.is_broadcast) then
|
|
node.color = "#7BE141"
|
|
end
|
|
|
|
if (saved_positions[node.id] ~= nil) then
|
|
node.x = saved_positions[node.id].x
|
|
node.y = saved_positions[node.id].y
|
|
end
|
|
|
|
nodes_id[k] = node.id
|
|
nodes[#nodes+1] = node
|
|
i = i + 1
|
|
end
|
|
|
|
for k, v in pairs(proto_number) do
|
|
|
|
local title = v[5]
|
|
local arrow = ""
|
|
|
|
if v[1] > 3 then
|
|
title = title .. ", other " .. v[1] - 3 .. "..."
|
|
end
|
|
|
|
if v[2] == true then
|
|
arrow = "to;from"
|
|
else
|
|
arrow = "to"
|
|
end
|
|
|
|
edges[#edges+1] = {
|
|
from = nodes_id[v[3]],
|
|
to = nodes_id[v[4]],
|
|
value = 1,
|
|
title = title,
|
|
arrows = arrow
|
|
}
|
|
end
|
|
|
|
return nodes, edges
|
|
end
|
|
|
|
local function generate_filters(service_map)
|
|
|
|
local filters = {}
|
|
local keys = {}
|
|
local keys_regex = {}
|
|
|
|
for k,v in pairs(service_map) do
|
|
if ((host_ip == nil)
|
|
or (v.client == host_ip)
|
|
or (v.server == host_ip) ) then
|
|
local k = "^".. getL4ProtoName(v.l4_proto) .. ":" .. v.l7_proto .."$"
|
|
|
|
keys_regex[v.l7_proto] = k
|
|
|
|
k = v.l7_proto
|
|
if(keys[k] == nil) then
|
|
keys[k] = 0
|
|
end
|
|
keys[k] = keys[k] + 1
|
|
end
|
|
end
|
|
|
|
local id = 0
|
|
for k, v in pairsByKeys(keys, asc) do
|
|
filters[#filters+1] = {
|
|
key = "filter_"..id,
|
|
regex = keys_regex[k],
|
|
label = string.format("%s (%s)", k, v),
|
|
countable = false,
|
|
}
|
|
id = id + 1
|
|
end
|
|
|
|
return filters
|
|
end
|
|
|
|
local function get_saved_graph_view()
|
|
|
|
-- If a graph view hasn't been saved yet, then use the default View
|
|
local GRAPH_VIEW_DEFAULT = {scale = 1, position = {x = 0, y = 0}}
|
|
local ifid = ifs.id
|
|
local GRAPH_VIEW_REDIS_KEY = string.format("ntopng.prefs.service_map.%d.graph", ifid)
|
|
|
|
local network_info = json.decode(ntop.getPref(GRAPH_VIEW_REDIS_KEY))
|
|
if (network_info == nil) then
|
|
return {}, GRAPH_VIEW_DEFAULT
|
|
end
|
|
|
|
local nodes_position = network_info.positions or {}
|
|
local network_layout = network_info.network or GRAPH_VIEW_DEFAULT
|
|
|
|
return nodes_position, network_layout
|
|
end
|
|
|
|
local host_ip = _GET["host"]
|
|
local page = _GET["page"] or "graph"
|
|
|
|
local nodes, proto_number, num_services = generate_graph(service_map, host_ip)
|
|
local saved_nodes_position, view_layout = get_saved_graph_view()
|
|
local ui_nodes, ui_edges = generate_ui_graph(nodes, saved_nodes_position, proto_number)
|
|
|
|
page_utils.set_active_menu_entry(page_utils.menu_entries.service_map)
|
|
|
|
-- append the menu above the page
|
|
dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")
|
|
|
|
local title = i18n("service_map")
|
|
local host_label = ""
|
|
|
|
if host_ip ~= nil then
|
|
local hinfo = hostkey2hostinfo(host_ip)
|
|
local label = shortenString(hostinfo2label(hinfo), 16)
|
|
host_label = label
|
|
end
|
|
|
|
local navbar_title = ui_utils.create_navbar_title(title, host_label, "/lua/service_map.lua")
|
|
|
|
local graph_url = ntop.getHttpPrefix() .. "/lua/service_map.lua?page=graph"
|
|
local table_url = ntop.getHttpPrefix() .. "/lua/service_map.lua?page=table"
|
|
if (host_ip ~= nil) then
|
|
table_url = table_url .. "&host=" .. host_ip
|
|
graph_url = graph_url .. "&host=" .. host_ip
|
|
end
|
|
|
|
page_utils.print_navbar(navbar_title, url, {
|
|
{
|
|
active = page == nil or page == "graph",
|
|
page_name = "graph",
|
|
label = '<i class="fas fa-lg fa-project-diagram"></i>',
|
|
url = graph_url
|
|
},
|
|
{
|
|
active = page == "table",
|
|
hidden = (num_services == 0),
|
|
page_name = "table",
|
|
label = '<i class="fas fa-lg fa-table"></i>',
|
|
url = table_url
|
|
}
|
|
})
|
|
|
|
local context = {
|
|
json = json,
|
|
is_admin = is_admin,
|
|
page = page,
|
|
ifid = ifs.id,
|
|
service_map = {
|
|
host = host_ip,
|
|
num_services = num_services,
|
|
graph_ui = {
|
|
nodes = ui_nodes,
|
|
edges = ui_edges,
|
|
saved = {
|
|
layout = view_layout
|
|
}
|
|
},
|
|
table = {
|
|
filters = generate_filters(service_map)
|
|
}
|
|
}
|
|
}
|
|
|
|
-- print service_map.template template
|
|
print(template.gen("pages/service_map.template", context))
|
|
|
|
-- append the menu below the page
|
|
dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")
|