ntopng/scripts/lua/modules/lua_utils_get.lua
2025-07-01 18:14:17 +02:00

1269 lines
34 KiB
Lua

--
-- (C) 2014-25 - ntop.org
--
if(pragma_once_lua_utils_get == true) then
-- io.write(debug.traceback().."\n")
-- avoid multiple inclusions
return
end
pragma_once_lua_utils_get = true
require "ntop_utils"
require "label_utils"
require "check_redis_prefs"
local clock_start = os.clock()
-- ##############################################
function getInterfaceUrl(ifid)
if (not ifid) then
return ("")
end
return ntop.getHttpPrefix() .. "/lua/if_stats.lua?ifid=" .. ifid
end
-- ##############################################
function getFirstInterfaceId()
local ifid = interface.getFirstInterfaceId()
if ifid ~= nil then
return ifid, getInterfaceName(ifid)
end
return -1, ""
end
-- ##############################################
local function urlencode(str)
str = string.gsub(str, "\r?\n", "\r\n")
str = string.gsub(str, "([^%w%-%.%_%~ ])", function(c)
return string.format("%%%02X", string.byte(c))
end)
str = string.gsub(str, " ", "+")
return str
end
-- ##############################################
function getPageUrl(base_url, params)
if table.empty(params) then
return base_url
end
local encoded = {}
for k, v in pairs(params) do
encoded[k] = urlencode(v)
end
local delim = "&"
if not string.find(base_url, "?") then
delim = "?"
end
return base_url .. delim .. table.tconcat(encoded, "=", "&")
end
-- ##############################################
function getProbesName(flowdevs, show_vlan, shorten_len)
local probes_list = {}
for interface, devices in pairs(flowdevs or {}) do
local device_list = {}
if table.len(devices or {}) > 0 then
for id, device_info in pairsByKeys(devices or {}, asc) do
device_list[device_info.exporter_ip] = getProbeName(device_info.exporter_ip, show_vlan, shorten_len)
end
probes_list[interface] = device_list
end
end
return probes_list
end
-- ##############################################
function getProbeName(exporter_ip, show_vlan, shorten_len)
local cached_device_name
local snmp_cached_dev
local probe_alias = getFlowDevAlias(exporter_ip, true)
-- In case an alias is set to the flow exporter, directly use the alias
if not isEmptyString(probe_alias) and probe_alias ~= exporter_ip then
return probe_alias
end
-- No alias set, let's try with the SNMP
if ntop.isPro() then
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path
snmp_cached_dev = require "snmp_cached_dev"
end
if snmp_cached_dev then
cached_device_name = snmp_cached_dev:create(exporter_ip)
end
if cached_device_name then
cached_device_name = cached_device_name["name"]
else
local hinfo = hostkey2hostinfo(exporter_ip)
local exporter_label = hostinfo2label(hinfo, show_vlan, shorten_len)
if not isEmptyString(exporter_label) then
cached_device_name = exporter_label
end
end
return cached_device_name
end
-- ##############################################
function getCategoriesWithProtocols()
local protocol_categories = interface.getnDPICategories()
for k, v in pairsByKeys(protocol_categories) do
protocol_categories[k] = {
id = v,
protos = interface.getnDPIProtocols(tonumber(v)),
count = 0
}
for proto, _ in pairs(protocol_categories[k].protos) do
protocol_categories[k].count = protocol_categories[k].count + 1
end
end
return protocol_categories
end
-- ##############################################
-- Return the first 'howmany' hosts
function getTopInterfaceHosts(howmany, localHostsOnly)
hosts_stats = interface.getHostsInfo()
hosts_stats = hosts_stats["hosts"]
ret = {}
sortTable = {}
n = 0
for k, v in pairs(hosts_stats) do
if ((not localHostsOnly) or ((v["localhost"] == true) and (v["ip"] ~= nil))) then
sortTable[v["bytes.sent"] + v["bytes.rcvd"] + n] = k
n = n + 0.01
end
end
n = 0
for _v, k in pairsByKeys(sortTable, rev) do
if (n < howmany) then
ret[k] = hosts_stats[k]
n = n + 1
else
break
end
end
return (ret)
end
-- #################################
function getIpUrl(ip)
if isIPv6(ip) then
-- https://www.ietf.org/rfc/rfc2732.txt
return "[" .. ip .. "]"
end
return ip
end
-- #################################
function getApplicationIcon(name)
local icon = ""
if (name == nil) then
name = ""
end
if (findString(name, "Skype")) then
icon = '<i class=\'fab fa-skype\'></i>'
elseif (findString(name, "Unknown")) then
icon = '<i class=\'fas fa-question\'></i>'
elseif (findString(name, "Twitter")) then
icon = '<i class=\'fab fa-twitter\'></i>'
elseif (findString(name, "DropBox")) then
icon = '<i class=\'fab fa-dropbox\'></i>'
elseif (findString(name, "Spotify")) then
icon = '<i class=\'fab fa-spotify\'></i>'
elseif (findString(name, "Apple")) then
icon = '<i class=\'fab fa-apple\'></i>'
elseif (findString(name, "Google") or findString(name, "Chrome")) then
icon = '<i class=\'fab fa-google-plus-g\'></i>'
elseif (findString(name, "FaceBook")) then
icon = '<i class=\'fab fa-facebook\'></i>'
elseif (findString(name, "Youtube")) then
icon = '<i class=\'fab fa-youtube\'></i>'
elseif (findString(name, "thunderbird")) then
icon = '<i class=\'fas fa-paper-plane\'></i>'
end
return (icon)
end
-- #################################
function getApplicationLabel(name, maxlen)
local icon = getApplicationIcon(name)
if (maxlen == nil) then
maxlen = 12
end
-- Do not convert to upper case, keep the nDPI case
-- name = name:gsub("^%l", string.upper)
if (icon == "") then
return (shortenString(name, maxlen))
else
return (icon .. " " .. shortenString(name, maxlen))
end
end
-- #################################
function getCategoryLabel(cat_name, cat_id)
local categories_utils = require 'categories_utils'
return categories_utils.getCustomCategoryName(cat_id, cat_name)
end
-- ###########################################
function getItemsNumber(n)
tot = 0
for k, v in pairs(n) do
-- io.write(k.."\n")
tot = tot + 1
end
-- io.write(tot.."\n")
return (tot)
end
-- ###########################################
function getHostCommaSeparatedList(p_hosts)
hosts = {}
hosts_size = 0
for i, host in pairs(split(p_hosts, ",")) do
hosts[i] = host
hosts_size = hosts_size + 1
end
return hosts, hosts_size
end
-- ##############################################
function getFirstIpFromMac(host_addr)
local mac_resolved = host_addr
-- Transforming the MAC into the ip address
local mac_hosts = interface.getMacHosts(mac_resolved) or {}
-- Mapping mac with ip and setting up the right href
for _, h in pairsByKeys(mac_hosts, rev) do
if (h.broadcast_domain_host) or (table.len(mac_hosts) == 1) then
mac_resolved = h.ip
break
end
end
return mac_resolved
end
-- ##############################################
function getHostNotesKey(host_key)
if (host_key == nil) then
return (nil)
end
return "ntopng.cache.host_notes." .. host_key
end
-- ##############################################
function getHostNotes(host_info)
local host_key
if type(host_info) == "table" then
host_key = host_info["host"]
else
host_key = host_info
end
local notes = ntop.getCache(getHostNotesKey(host_key))
if isEmptyString(notes) and type(host_info) == "table" and host_info["vlan"] then
-- Check if there is an alias for the host@vlan
host_key = hostinfo2hostkey(host_info)
notes = ntop.getCache(getHostNotesKey(host_key))
end
if not isEmptyString(notes) then
notes = string.lower(notes)
end
return notes
end
-- ##############################################
-- A function to give a useful device name
function getDeviceName(device_mac, skip_manufacturer)
local name = mac2label(device_mac)
if name == device_mac then
-- Not found, try with first host
local info = interface.getHostsInfo(false, nil, 1, 0, nil, nil, nil, tonumber(vlan), nil, nil, device_mac)
if (info ~= nil) then
for x, host in pairs(info.hosts) do
-- Make sure the IP is in the broadcast domain to avoid setting up names to MACs such as the gateway
if host.broadcast_domain_host and not isEmptyString(host.name) and host.name ~= host.ip and host.name ~=
"NoIP" then
name = host.name
elseif host.ip ~= "0.0.0.0" then
name = ip2label(host.ip)
if name == host.ip then
name = nil
end
end
break
end
else
name = nil
end
end
if(isEmptyString(name) and (device_mac ~= nil)) then
if (not skip_manufacturer) then
name = get_symbolic_mac(device_mac, true)
else
-- last resort
name = device_mac
end
end
if isEmptyString(name) or name == device_mac then
return ''
end
return name
end
-- ############################################
-- Redis Utils
-- ############################################
-- Inpur: General prefix (i.e ntopng.pref)
-- Output: User based prefix, if it exists
--
-- Examples:
-- With user: ntopng.pref.user_name
-- Without: ntopng.pref
function getRedisPrefix(str)
if _SESSION and not (isEmptyString(_SESSION["user"])) then
-- Login enabled
return (str .. '.' .. _SESSION["user"])
else
-- Login disabled
return (str)
end
end
----- End of Redis Utils ------
-- ##############################################
-- Table preferences
function getDefaultTableSort(table_type)
local table_key = getRedisPrefix("ntopng.sort.table")
local value = nil
if (table_type ~= nil) then
value = ntop.getHashCache(table_key, "sort_" .. table_type)
end
if ((value == nil) or (value == "")) then
value = 'column_'
end
return (value)
end
-- ##############################################
function getDefaultTableSortOrder(table_type, force_get)
local table_key = getRedisPrefix("ntopng.sort.table")
local value = nil
if (table_type ~= nil) then
value = ntop.getHashCache(table_key, "sort_order_" .. table_type)
end
if ((value == nil) or (value == "")) and (force_get ~= true) then
value = 'desc'
end
return (value)
end
-- ##############################################
function getDefaultTableSize()
table_key = getRedisPrefix("ntopng.sort.table")
value = ntop.getHashCache(table_key, "rows_number")
if ((value == nil) or (value == "")) then
value = 10
end
return (tonumber(value))
end
-- ##############################################
function getInterfaceSpeed(ifid)
local ifname = getInterfaceName(ifid)
local ifspeed = ntop.getCache('ntopng.prefs.ifid_' .. tostring(ifid) .. '.speed')
if not isEmptyString(ifspeed) and tonumber(ifspeed) ~= nil then
ifspeed = tonumber(ifspeed)
else
ifspeed = interface.getMaxIfSpeed(ifid)
end
return ifspeed
end
-- ##############################################
function getCustomnDPIProtoCategoriesKey()
return "ntop.prefs.custom_nDPI_proto_categories"
end
-- ##############################################
function setCustomnDPIProtoCategory(app_id, new_cat_id)
ntop.setnDPIProtoCategory(app_id, new_cat_id)
local key = getCustomnDPIProtoCategoriesKey()
-- NOTE: when the ndpi struct changes, the custom associations are
-- reloaded by Ntop::loadProtocolsAssociations
ntop.setHashCache(key, tostring(app_id), tostring(new_cat_id));
end
-- ##############################################
function removeCustomnDPIProtoCategory(app_id)
local key = getCustomnDPIProtoCategoriesKey()
-- NOTE: when the ndpi struct changes, the custom associations are
-- reloaded by Ntop::loadProtocolsAssociations
ntop.delHashCache(key, tostring(app_id));
end
-- ##############################################
function getKeysSortedByValue(tbl, sortFunction)
local keys = {}
for key in pairs(tbl) do
table.insert(keys, key)
end
table.sort(keys, function(a, b)
return sortFunction(tbl[a], tbl[b])
end)
return keys
end
-- ##############################################
function getKeys(t, col)
local keys = {}
for k, v in pairs(t) do
keys[tonumber(v[col])] = k
end
return keys
end
-- ##############################################
function getFlag(country)
if ((country == nil) or (country == "")) then
return ("")
else
return (" <a href='" .. ntop.getHttpPrefix() .. "/lua/hosts_stats.lua?country=" .. country .. "'><img src='" ..
ntop.getHttpPrefix() .. "/dist/images/blank.gif' class='flag flag-" .. string.lower(country) ..
"'></a> ")
end
end
-- ##############################################
function getUsernameInputPattern()
-- maximum len must be kept in sync with MAX_PASSWORD_LEN
return [[^[a-zA-Z0-9._@!-?]{3,30}$]]
end
-- ##############################################
function getPasswordInputPattern()
-- maximum len must be kept in sync with MAX_PASSWORD_LEN
return [[^[\w\$\\!\/\(\)= \?\^\*@_\-\u0000-\u0019\u0021-\u00ff]{5,128}$]]
end
-- ##############################################
-- NOTE: keep in sync with validateLicense()
function getLicensePattern()
return [[^[a-zA-Z0-9\+/=]+$]]
end
-- ##############################################
function getIPv4Pattern()
return "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"
end
-- ##############################################
function getACLPattern()
local ipv4 =
"(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])"
local netmask = "(\\/([0-9]|[1-2][0-9]|3[0-2]))"
local cidr = ipv4 .. netmask
local yesorno_cidr = "[\\+\\-]" .. cidr
return "^" .. yesorno_cidr .. "(," .. yesorno_cidr .. ")*$"
end
-- ##############################################
function getMacPattern()
return "^([0-9a-fA-F][0-9a-fA-F]:){5}[0-9a-fA-F]{2}$"
end
-- ##############################################
function getURLPattern()
return "^https?://.+$"
end
-- ##############################################
function getURLPathPattern()
return "^\\/lua\\/(?:[^\\/]+\\/)*[^\\/]+\\.lua(/?.*)?$"
end
-- ##############################################
function getRestUrl(script, is_pro, is_enterprise)
if is_enterprise then
return (ntop.getHttpPrefix() .. "/lua/enterprise/rest/v2/get/" .. script)
elseif is_pro then
return (ntop.getHttpPrefix() .. "/lua/pro/rest/v2/get/" .. script)
else
return (ntop.getHttpPrefix() .. "/lua/rest/v2/get/" .. script)
end
end
-- ##############################################
-- get_mac_classification
function get_mac_classification(m, extended_name)
local short_extended = ntop.getMacManufacturer(m) or {}
if extended_name then
return short_extended.extended or short_extended.short or m
else
return short_extended.short or m
end
return m
end
-- ##############################################
local magic_macs = {
["00:00:00:00:00:00"] = "",
["FF:FF:FF:FF:FF:FF"] = "Broadcast",
["01:00:0C:CC:CC:CC"] = "CDP",
["01:00:0C:CC:CC:CD"] = "CiscoSTP",
["01:80:C2:00:00:00"] = "STP",
["01:80:C2:00:00:00"] = "LLDP",
["01:80:C2:00:00:03"] = "LLDP",
["01:80:C2:00:00:0E"] = "LLDP",
["01:80:C2:00:00:08"] = "STP",
["01:1B:19:00:00:00"] = "PTP",
["01:80:C2:00:00:0E"] = "PTP"
}
local magic_short_macs = {
["01:00:5E"] = "IPv4mcast",
["33:33:"] = "IPv6mcast"
}
-- ###############################################
-- get_symbolic_mac
function get_symbolic_mac_rev(mac_address)
if (magic_macs[mac_address] ~= nil) then
return (magic_macs[mac_address])
else
local m = string.sub(mac_address, 1, 8)
local s = get_mac_classification(m)
if ((s ~= nil) and (s ~= m)) then
return(mac_address.. " [".. trimSpace(s) .."]")
end
end
return(mac_address)
end
-- get_symbolic_mac
function get_symbolic_mac(mac_address, no_href, add_extra_info)
if (magic_macs[mac_address] ~= nil) then
return (magic_macs[mac_address])
else
local m = string.sub(mac_address, 1, 8)
local t = string.sub(mac_address, 10, 17)
if (magic_short_macs[m] ~= nil) then
if (add_extra_info == true) then
return (magic_short_macs[m] .. "_" .. t .. " (" .. macInfo(mac_address) .. ")")
else
if no_href then
return (magic_short_macs[m] .. "_" .. t)
else
return (macInfoWithSymbName(mac_address, magic_short_macs[m] .. "_" .. t))
end
end
else
local s = get_mac_classification(m)
if (m == s) then
if no_href then
return get_mac_classification(m) .. ":" .. t
else
return '<a href="' .. ntop.getHttpPrefix() .. '/lua/mac_details.lua?host=' .. mac_address .. '">' ..
get_mac_classification(m) .. ":" .. t .. '</a>'
end
else
local href = ""
local href_end = ""
if not no_href then
href = '<a href="' .. ntop.getHttpPrefix() .. '/lua/mac_details.lua?host=' .. mac_address .. '">'
href_end = "</a>"
end
if (add_extra_info == true) then
return (href .. get_mac_classification(m) .. "_" .. t .. " (" .. macInfo(mac_address) .. ")" ..
href_end)
else
return (href .. get_mac_classification(m) .. "_" .. t .. href_end)
end
end
end
end
end
-- ##############################################
function get_mac_url(mac)
local m = get_symbolic_mac(mac, true)
if isEmptyString(m) then
return ""
end
local url = ntop.getHttpPrefix() .. "/lua/mac_details.lua?host=" .. mac
return string.format('[ <a href=\"%s\">%s</a> ]', url, m)
end
-- ##############################################
function get_manufacturer_mac(mac_address)
local m = string.sub(mac_address, 1, 8)
local ret = get_mac_classification(m, true --[[ extended name --]] )
if ret == m then
ret = ""
end
if not isEmptyString(ret) then
ret = ret:gsub("'", " ")
end
return ret
end
-- ##############################################
-- getservbyport
function getservbyport(port_num, proto)
if not port_num then return '' end
port_num = tonumber(port_num)
if not port_num then return '' end
if not proto then proto = "TCP" end
proto = string.lower(proto)
-- io.write(port_num.."@"..proto.."\n")
return (ntop.getservbyport(port_num, proto))
end
-- ##############################################
function getFlowMaxRate(cli_max_rate, srv_max_rate)
cli_max_rate = tonumber(cli_max_rate)
srv_max_rate = tonumber(srv_max_rate)
if ((cli_max_rate == 0) or (srv_max_rate == 0)) then
max_rate = 0
elseif ((cli_max_rate == -1) and (srv_max_rate > 0)) then
max_rate = srv_max_rate
elseif ((cli_max_rate > 0) and (srv_max_rate == -1)) then
max_rate = cli_max_rate
else
max_rate = math.min(cli_max_rate, srv_max_rate)
end
return (max_rate)
end
-- ####################################################
-- Functions to set/get a device type of user choice
local function getCustomDeviceKey(mac)
return "ntopng.prefs.device_types." .. string.upper(mac)
end
-- ##############################################
function getCustomDeviceType(mac)
return tonumber(ntop.getPref(getCustomDeviceKey(mac)))
end
-- #############################################
function setCustomDeviceType(mac, device_type)
ntop.setPref(getCustomDeviceKey(mac), tostring(device_type))
end
-- ##############################################
-- @brief Compute and return the difference, in seconds, between the local time of this instance and GMT
-- @return A positive or negative number corresponding to the seconds between local time and GMT
local function get_server_timezone_diff_seconds()
if not server_timezone_diff_seconds then
local tmp_time = os.time()
local d1 = os.date("*t", tmp_time)
local d2 = os.date("!*t", tmp_time)
-- Forcefully set isdst to false otherwise difference won't work during DST
d1.isdst = false
-- Use a minus to have the difference between local time and GMT, rather than between GMT and loca ltime
server_timezone_diff_seconds = -os.difftime(os.time(d1), os.time(d2))
end
return server_timezone_diff_seconds
end
-- ####################################################
-- @brief Get the frontend timezone offset in seconds
-- @return The offset of the frontend timezone
function getFrontendTzSeconds()
local frontend_tz_offset = nil
if _COOKIE and _COOKIE.tzoffset then
-- The timezone offset can be passed from the client as a cookie.
-- This allows to format the dates in the frontend timezone.
frontend_tz_offset = tonumber(_COOKIE.tzoffset)
end
if frontend_tz_offset == nil then
-- If timezone is not available in the client _COOKIE,
-- server timezone is used as fallback
return -get_server_timezone_diff_seconds()
end
return frontend_tz_offset
end
-- ##############################################
function getTopFlowPeers(hostname_vlan, max_hits, detailed, other_options)
local detailed = detailed or false
local paginator_options = {
sortColumn = "column_thpt",
a2zSortOrder = false,
detailedResults = detailed,
maxHits = max_hits
}
if other_options ~= nil then
paginator_options = table.merge(paginator_options, other_options)
end
local res = interface.getFlowsInfo(hostname_vlan, paginator_options)
if ((res ~= nil) and (res.flows ~= nil)) then
return res.flows
else
return {}
end
end
-- ##############################################
function getSafeChildIcon()
return ("&nbsp;<font color='#5cb85c'><i class='fas fa-lg fa-child' aria-hidden='true'></i></font>")
end
-- ###########################################
function getNtopngRelease(ntopng_info, verbose)
local release
if ntopng_info.oem or ntopng_info["version.nedge_edition"] then
release = ""
elseif (ntopng_info["version.enterprise_xxl_edition"]) then
release = "Enterprise XXL"
elseif (ntopng_info["version.enterprise_xl_edition"]) then
release = "Enterprise XL"
elseif (ntopng_info["version.enterprise_l_edition"]) then
release = "Enterprise L"
elseif (ntopng_info["version.enterprise_m_edition"]) then
release = "Enterprise M"
elseif (ntopng_info["version.enterprise_edition"]) or (ntopng_info["version.nedge_enterprise_edition"]) then
release = "Enterprise"
elseif (ntopng_info["pro.release"]) then
release = "Professional"
else
release = "Community"
end
if not isEmptyString(release) and ntopng_info["version.embedded_edition"] then
release = release .. " (Embedded)"
end
-- E.g., ntopng edge v.4.3.210112 (Ubuntu 16.04.6 LTS)
local res = string.format("%s %s v.%s (%s)", ntopng_info.product, release, ntopng_info.version, ntopng_info.OS)
if verbose and ntopng_info.revision then
res = string.format("%s %s v.%s rev.%s (%s)", ntopng_info.product, release, ntopng_info.version,
ntopng_info.revision, ntopng_info.OS)
end
if not ntopng_info.oem then
local vers = string.split(ntopng_info["version.git"], ":")
if vers and vers[2] then
local ntopng_git_url = "<A HREF=\"https://github.com/ntop/ntopng/commit/" .. vers[2] ..
"\"><i class='fab fa-github'></i></A>"
res = string.format("%s | %s", res, ntopng_git_url)
end
end
return res
end
-- ###########################################
-- A redis hash mac -> first_seen
function getDevicesHashMapKey(ifid)
return "ntopng.checks.device_connection_disconnection.ifid_" .. ifid
end
-- ###########################################
function getHideFromTopSet(ifid)
return "ntopng.prefs.iface_" .. ifid .. ".hide_from_top"
end
-- ###########################################
function getGwMacsSet(ifid)
return "ntopng.prefs.iface_" .. ifid .. ".gw_macs"
end
-- ###########################################
function getDeviceProtocolPoliciesUrl(params_str)
local url, sep
if ntop.isnEdge() then
url = "/lua/pro/nedge/admin/nf_edit_user.lua?page=device_protocols"
sep = "&"
else
url = "/lua/admin/edit_device_protocols.lua"
sep = "?"
end
if not isEmptyString(params_str) then
return ntop.getHttpPrefix() .. url .. sep .. params_str
end
return ntop.getHttpPrefix() .. url
end
-- ###########################################
-- Returns the size of a folder (size is in bytes)
-- ! @param path the path to compute the size for
-- ! @param timeout the maxium time to compute the size. If nil, it defaults to 15 seconds.
function getFolderSize(path, timeout)
local os_utils = require "os_utils"
local folder_size_key = "ntopng.cache.folder_size"
local now = os.time()
local expiration = 30 -- sec
local size = nil
if ntop.isWindows() then
size = 0 -- TODO
else
local MAX_TIMEOUT = tonumber(timeout) or 15 -- default
-- Check if timeout is present on the system to cap the execution time of the subsequent du,
-- which may be very time consuming, especially when the number of files is high
local has_timeout = ntop.getCache("ntopng.cache.has_gnu_timeout")
if isEmptyString(has_timeout) then
-- Cache the timeout
-- Check timeout existence with which. If no timeout is found, command will return nil
has_timeout = (os_utils.execWithOutput("which timeout >/dev/null 2>&1") ~= nil)
ntop.setCache("ntopng.cache.has_gnu_timeout", tostring(has_timeout), 3600)
else
has_timeout = has_timeout == "true"
end
-- Check the cache for a recent value
local time_size = ntop.getHashCache(folder_size_key, path)
if not isEmptyString(time_size) then
local values = split(time_size, ',')
if #values >= 2 and tonumber(values[1]) >= (now - expiration) then
size = tonumber(values[2])
end
end
if size == nil then
size = 0
-- Read disk utilization
local periodic_activities_utils = require "periodic_activities_utils"
if ntop.isdir(path) and not periodic_activities_utils.have_degraded_performance() then
local du_cmd = string.format("du -s %s 2>/dev/null", path)
if has_timeout then
du_cmd = string.format("timeout %u%s %s", MAX_TIMEOUT, "s", du_cmd)
end
-- use POSIXLY_CORRECT=1 to guarantee results is returned in 512-byte blocks
-- both on BSD and Linux
local line = os_utils.execWithOutput(string.format("POSIXLY_CORRECT=1 %s", du_cmd))
local values = split(line, '\t')
if #values >= 1 then
local used = tonumber(values[1])
if used ~= nil then
size = math.ceil(used * 512)
-- Cache disk utilization
ntop.setHashCache("ntopng.cache.folder_size", path, now .. "," .. size)
end
end
end
end
end
return size
end
-- ###########################################
function getHttpUrlPrefix()
if starts(_SERVER["HTTP_HOST"], 'https://') then
return "https://"
else
return "http://"
end
end
-- ##############################################
function getPoolName(pool_id)
if isEmptyString(pool_id) or pool_id == "0" then
return "Default"
else
local key = "ntopng.prefs.host_pools.details." .. pool_id
return ntop.getHashCache(key, "name")
end
end
-- ##############################################
function get_version_update_msg(info, latest_version)
if info then
local version_elems = split(info["version"], " ")
local new_version = version2int(latest_version)
local this_version = version2int(version_elems[1])
if (new_version > this_version) then
return i18n("about.new_major_available", {
product = info["product"],
version = latest_version,
url = "http://www.ntop.org/get-started/download/"
})
end
end
return ""
end
-- ##############################################
function getFlowDevAliasKey()
return "ntopng.flow_dev_aliases"
end
-- ##############################################
function getFlowDevAlias(flowdev_ip, add_id)
local alias = ntop.getHashCache(getFlowDevAliasKey(), flowdev_ip)
local ret
if not isEmptyString(alias) then
if (add_id == true) then
ret = flowdev_ip .. " [" .. alias .. "]"
else
ret = alias
end
else
ret = tostring(flowdev_ip)
end
return ret
end
-- ##############################################
function getFullFlowDevName(flowdev_ip, compact, add_id)
local alias = getFlowDevAlias(flowdev_ip, add_id)
if not isEmptyString(flowdev_ip) then
if not isEmptyString(flowdev_ip) and alias ~= tostring(flowdev_ip) then
if compact then
alias = shortenString(alias)
return string.format("%s", alias)
else
return string.format("%s [%s]", flowdev_ip, alias)
end
end
end
return flowdev_ip
end
-- ##############################################
function getObsPointAliasKey()
return "ntopng.observation_point_aliases"
end
-- ##############################################
function getObsPointAlias(observation_point_id, add_id, add_href)
local alias = ntop.getHashCache(getObsPointAliasKey(), observation_point_id)
local ret
if not isEmptyString(alias) then
if (add_id == true) then
ret = observation_point_id .. " [" .. alias .. "]"
else
ret = alias
end
else
ret = tostring(observation_point_id)
end
if (add_href == true) then
ret = "<A HREF=\"" .. ntop.getHttpPrefix() .. "/lua/pro/enterprise/observation_points.lua\">" .. ret .. "</A>"
end
return ret
end
-- ##############################################
function getFullObsPointName(observation_point_id, compact, add_id)
local alias = getObsPointAlias(observation_point_id, add_id)
if not isEmptyString(observation_point_id) then
if not isEmptyString(observation_point_id) and alias ~= tostring(observation_point_id) then
if compact then
alias = shortenString(alias)
return string.format("%s", alias)
else
return string.format("%u [%s]", observation_point_id, alias)
end
end
end
return observation_point_id
end
-- ##############################################
function getExtraFlowInfoTLSIssuerDN(alert_json)
if alert_json and alert_json["proto"] and alert_json["proto"]["tls"] and
not isEmptyString(alert_json["proto"]["tls"]["issuerDN"]) then
return alert_json["proto"]["tls"]["issuerDN"]
end
return nil
end
-- ##############################################
function getExtraFlowInfoServerName(alert_json)
if alert_json then
if alert_json["proto"] and alert_json["proto"]["http"] and
not isEmptyString(alert_json["proto"]["http"]["server_name"]) then
return alert_json["proto"]["http"]["server_name"]
elseif alert_json["proto"] and alert_json["proto"]["dns"] and
not isEmptyString(alert_json["proto"]["dns"]["last_query"]) then
return alert_json["proto"]["dns"]["last_query"]
elseif alert_json["proto"] and alert_json["proto"]["tls"] and
not isEmptyString(alert_json["proto"]["tls"]["client_requested_server_name"]) then
return alert_json["proto"]["tls"]["client_requested_server_name"]
end
end
return nil
end
-- ##############################################
function getExtraFlowInfoURL(alert_json)
if alert_json then
if alert_json["proto"] and alert_json["proto"]["http"] and
not isEmptyString(alert_json["proto"]["http"]["last_url"]) then
return alert_json["proto"]["http"]["last_url"]
end
end
return getExtraFlowInfoServerName(alert_json)
end
-- ##############################################
function get_badge(info)
local badge = 'success'
if info ~= true and info ~= 0 then
badge = 'danger'
end
return badge
end
-- ##############################################
function get_confidence(confidence_id, shorten_string)
local tag_utils = require "tag_utils"
local confidence_name = confidence_id
if confidence_id and tonumber(confidence_id) then
confidence_id = tonumber(confidence_id)
for _, confidence in pairs(tag_utils.confidence or {}) do
if confidence.id == confidence_id then
confidence_name = confidence.label
break
end
end
end
return confidence_name
end
-- ##############################################
local services = nil
local function readServices()
if(services == nil) then
local file = io.open("/etc/services", "r")
if not file then return services end
services = {}
for line in file:lines() do
if((line ~= "") and (not(string.starts(line, "#")))) then
line = line:gsub("\t", " ")
line = line:gsub(" ", " ")
local elems = split(line, " ")
local label = elems[1]
local value
local i = 2
while(elems[i] ~= nil) do
if(elems[i] ~= "") then
value = elems[i]
break
end
i = i + 1
end
services[value] = label
-- print(label.." = "..value.."<br>\n")
end
end
file:close()
end
return(services)
end
-- Example mapServiceName(80, "tcp")
function mapServiceName(port, protocol)
readServices()
local key = tostring(port).."/"..protocol
return(services[key])
end
-- ##############################################
function getExporterList()
local flowdevs = interface.getFlowDevices()
local unified_exporters = {}
for interface_id, device_list in pairs(flowdevs or {}) do
for device_id, exporter_info in pairs(device_list, asc) do
local exporter_ip = exporter_info.exporter_ip
if not unified_exporters[exporter_ip] then
unified_exporters[exporter_ip] = exporter_info
end
end
end
return unified_exporters
end
-- ##############################################
if (trace_script_duration ~= nil) then
io.write(debug.getinfo(1, 'S').source .. " executed in " .. (os.clock() - clock_start) * 1000 .. " ms\n")
end