Adds new REST API v2/

Addresses #5269
This commit is contained in:
Simone Mainardi 2021-07-08 09:57:46 +02:00
parent 1f24dec3e3
commit b117e8a23a
178 changed files with 6639 additions and 124 deletions

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local active_monitoring_pools = require "active_monitoring_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(active_monitoring_pools)

View file

@ -0,0 +1,31 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require "dkjson"
local alert_severities = require "alert_severities"
local rest_utils = require "rest_utils"
--
-- Read all the defined alert severity constants
-- Example: curl -u admin:admin -H "Content-Type: application/json" http://localhost:3000/lua/rest/v2/get/alert/severity/consts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
for severity, severity_descr in pairs(alert_severities) do
res[#res + 1] = {
severity = severity,
id = severity_descr.severity_id,
}
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,33 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require "dkjson"
local alert_consts = require "alert_consts"
local rest_utils = require "rest_utils"
--
-- Read all the defined alert type constants
-- Example: curl -u admin:admin -H "Content-Type: application/json" http://localhost:3000/lua/rest/v2/get/alert/type/consts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
sendHTTPHeader('application/json')
local rc = rest_utils.consts.success.ok
local res = {}
for alert_type, alert in pairs(alert_consts.alert_types) do
res[#res + 1] = {
type = alert_type,
key = alert.meta.alert_key,
}
end
print(rest_utils.rc(rc, res))

View file

@ -0,0 +1,56 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local rest_utils = require("rest_utils")
local all_alert_store = require "all_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/host/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
-- Fetch the results
local alerts, recordsFiltered = all_alert_store:select_request()
for _, _value in ipairs(alerts or {}) do
res[#res + 1] = all_alert_store:format_record(_value, no_html)
end
if no_html then
res = all_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,59 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local all_alert_store = require "all_alert_store".new()
local alert_severities = require "alert_severities"
local auth = require "auth"
--
-- Read alerts count by time
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/host/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local ifid = _GET["ifid"]
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local res = {
series = {},
colors = {}
}
local count_data = all_alert_store:count_by_severity_and_time(true)
for _, severity in pairsByField(alert_severities, "severity_id", rev) do
if(count_data[severity.severity_id] ~= nil) then
res.series[#res.series + 1] = {
name = i18n(severity.i18n_title),
data = count_data[severity.severity_id],
}
res.colors[#res.colors + 1] = severity.color
end
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,50 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local rest_utils = require("rest_utils")
local am_alert_store = require "am_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{ }' http://localhost:3000/lua/rest/v2/get/am/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local format = _GET["format"] or "json"
local no_html = (format == "txt")
local rc = rest_utils.consts.success.ok
local res = {}
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
-- Active monitoring stay in the system interface
interface.select(getSystemInterfaceId())
-- Fetch the results
local alerts, recordsFiltered = am_alert_store:select_request()
for _key,_value in ipairs(alerts or {}) do
local record = am_alert_store:format_record(_value, no_html)
res[#res + 1] = record
end -- for
if no_html then
res = am_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,34 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local am_alert_store = require "am_alert_store".new()
local auth = require "auth"
--
-- Read alerts count by time
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{ }' http://localhost:3000/lua/rest/v2/get/active_monitoring/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
interface.select(getSystemInterfaceId())
local res = am_alert_store:count_by_severity_and_time_request()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,41 @@
--
-- (C) 2019-21 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/import_export/?.lua;" .. package.path
require "lua_utils"
local info = ntop.getInfo()
local checks_import_export = require "checks_import_export"
local json = require ("dkjson")
local page_utils = require("page_utils")
local format_utils = require("format_utils")
local os_utils = require "os_utils"
local rest_utils = require("rest_utils")
--
-- Read checks configuration
-- Example: curl -u admin:admin -H "Content-Type: application/json" http://localhost:3000/lua/rest/v2/get/scripts/config.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local download = _GET["download"]
if not isAdministratorOrPrintErr() then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
local checks_import_export = checks_import_export:create()
local res = checks_import_export:export()
if isEmptyString(download) then
rest_utils.answer(rest_utils.consts.success.ok, res)
else
sendHTTPContentTypeHeader('application/json', 'attachment; filename="scripts_configuration.json"')
print(json.encode(res, nil))
end

View file

@ -0,0 +1,155 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/datasources/?.lua;" .. package.path
local json = require "dkjson"
local rest_utils = require "rest_utils"
local template = require "resty.template"
-- Import the classes library.
local classes = require "classes"
-- ##############################################
local datasource = classes.class()
-- ##############################################
-- This is the base REST prefix for all the available datasources
datasource.BASE_REST_PREFIX = "/lua/rest/v2/get/datasource/"
-- ##############################################
-- @brief Base class constructor
function datasource:init()
self._dataset_params = {} -- Holds per-dataset params
self._datamodel_instance = nil -- Instance of the datamodel holding data for each dataset
end
-- ##############################################
-- @brief Parses params
-- @param params_table A table with submitted params
-- @return True if parameters parsing is successful, false otherwise
function datasource:read_params(params_table)
if not params_table then
self.parsed_params = nil
return false
end
self.parsed_params = {}
for _, param in pairs(self.meta.params or {}) do
local parsed_param = params_table[param]
-- Assumes all params mandatory and not empty
-- May override this behavior in subclasses
if isEmptyString(parsed_param) then
-- Reset any possibly set param
self.parsed_params = nil
return false
end
self.parsed_params[param] = parsed_param
end
-- Ok, parsin has been successful
return true
end
-- ##############################################
-- @brief Parses params submitted along with the REST endpoint request. If parsing fails, a REST error is sent.
-- @param params_table A table with submitted params, either _POST or _GET
-- @return True if parameters parsing is successful, false otherwise
function datasource:_rest_read_params(params_table)
if not self:read_params(params_table) then
rest_utils.answer(rest_utils.consts.err.widgets_missing_datasource_params)
return false
end
return true
end
-- ##############################################
-- @brief Send datasource data via REST
function datasource:rest_send_response()
-- Make sure this is a direct REST request and not just a require() that needs this class
if not _SERVER -- Not executing a Lua script initiated from the web server (i.e., backend execution)
or not _SERVER["URI"] -- Cannot reliably determine if this is a REST request
or not _SERVER["URI"]:starts(datasource.BASE_REST_PREFIX) -- Web Lua script execution but not for this REST endpoint
then
-- Don't send any REST response
return
end
if not self:_rest_read_params(_POST) then
-- Params parsing has failed, error response already sent by the caller
return
end
self:fetch()
rest_utils.answer(
rest_utils.consts.success.ok,
self.datamodel_instance:get_data()
)
end
-- ##############################################
-- @brief Deserializes REST endpoint response into an internal datamodel
-- @param rest_response_data Response data as obtained from the REST call
function datasource:deserialize(rest_response_data)
if rest_response_data and rest_response_data.RESPONSE_CODE == 200 then
local data = json.decode(rest_response_data.CONTENT)
local when = os.time()
if data and data.rc == rest_utils.consts.success.ok.rc then
self.datamodel_instance = self.meta.datamodel:new(data.rsp.header)
for _, row in ipairs(data.rsp.rows) do
self.datamodel_instance:appendRow(when, data.rsp.header, row)
end
end
end
end
-- ##############################################
-- @brief Returns instance metadata, which depends on the current instance and parsed_params
function datasource:get_metadata()
local res = {}
-- Render a url with submitted parsed_params
if self.meta.url then
local url_func = template.compile(self.meta.url, nil, true)
local url_rendered = url_func({
params = self.parsed_params,
})
res["url"] = url_rendered
end
return res
end
-- ##############################################
-- @brief Transform data according to the specified transformation
-- @param data The data to be transformed
-- @param transformation The transformation to be applied
-- @return transformed data
function datasource:transform(transformation)
return self.datamodel_instance:transform(transformation)
end
-- ##############################################
return datasource
-- ##############################################

View file

@ -0,0 +1,81 @@
--
-- (C) 2019-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/datamodel/?.lua;" .. package.path
-- ##############################################
-- Import the classes library.
local classes = require "classes"
-- This is the datamodel used to represent data associated with this datasource
local slices = require "slices"
-- Rest utilities
local rest_utils = require "rest_utils"
-- ##############################################
local packet_distro = classes.class(slices)
-- ##############################################
packet_distro.meta = {
params = {
-- NOTE: Specify all the parameter keys that must be passed in the request
"ifid" -- validated according to http_lint.lua
},
}
-- ##############################################
-- Human-friendly labels for the distribution
local available_bins = {
{ key = 'upTo64', label = '<= 64' },
{ key = 'upTo128', label = '64 <= 128' },
{ key = 'upTo256', label = '128 <= 256' },
{ key = 'upTo512', label = '256 <= 512' },
{ key = 'upTo1024', label = '512 <= 1024' },
{ key = 'upTo1518', label = '1024 <= 1518' },
{ key = 'upTo2500', label = '1518 <= 2500' },
{ key = 'upTo6500', label = '2500 <= 6500' },
{ key = 'upTo9000', label = '6500 <= 9000' },
{ key = 'above9000', label = '> 9000' },
}
-- ##############################################
-- @brief Datasource constructor
function packet_distro:init()
-- Initializes parent class slices
self.super:init(10 --[[ Maximum number of slices ]],
3 --[[ Percentage under which the slice is ignored and added to other --]])
end
-- #######################################################
function packet_distro:fetch()
-- Assumes all parameters listed in self.meta.params have been parsed successfully
-- and are available in self.parsed_params
interface.select(tostring(self.parsed_params.ifid))
local ifstats = interface.getStats()
local size_bins = ifstats["pktSizeDistribution"]["size"]
self:set_label(getHumanReadableInterfaceName(getInterfaceName(ifstats.id)))
for _, bin in ipairs(available_bins) do
self:append(bin.label, size_bins[bin.key] or 0)
end
end
-- #######################################################
-- Checks if this module is being loaded as part of a REST request to this endpoint or not.
-- If the module is being loaded as part of a REST request, then a response is sent, otherwise nothing is done.
-- Must call this to ensure REST responses are sent when necessary
packet_distro:new():rest_send_response()
-- #######################################################
return packet_distro

View file

@ -0,0 +1,57 @@
--
-- (C) 2013-21 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local rest_utils = require("rest_utils")
--
-- Resolve a name
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"hostname" : "www.google.com"}' http://localhost:3000/lua/rest/v2/get/dns/resolve.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local hostname = _GET["hostname"]
if isEmptyString(hostname) then
rest_utils.answer(rest_utils.consts.err.invalid_args)
return
end
if string.find(hostname, '://') then
-- Looks like an URI, strip the scheme
local uri_info = string.split(hostname, "://")
if #uri_info == 2 then
hostname = uri_info[2]
end
end
if string.find(hostname, ':') then
local host_port_info = string.split(hostname, ":")
if #host_port_info == 2 then
-- Looks like host:port, strip the port
hostname = host_port_info[1]
end
end
local resolved = ntop.resolveHost(hostname, true --[[ IPv4 --]])
if not resolved then
resolved = ntop.resolveHost(hostname, false --[[ IPv6 --]])
end
if not resolved then
rest_utils.answer(rest_utils.consts.err.resolution_failed)
return
end
res = resolved
rest_utils.answer(rc, res)

View file

@ -0,0 +1,184 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
require "flow_utils"
local format_utils = require("format_utils")
local flow_utils = require "flow_utils"
local icmp_utils = require "icmp_utils"
local json = require "dkjson"
local rest_utils = require("rest_utils")
--
-- Read list of active flows
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/flow/active.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local verbose = (_GET["verbose"] == "true")
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
if not isEmptyString(_GET["sortColumn"]) then
-- Backward compatibility
_GET["sortColumn"] = "column_" .. _GET["sortColumn"]
end
-- This is using GET parameters to handle:
--
-- Pagination:
-- - sortColumn
-- - sortOrder
-- - currentPage
-- - perPage
--
-- Filtering, including:
-- - application
-- - l4proto
-- - host
-- - vlan
--
local flows_filter = getFlowsFilter()
local flows_stats = interface.getFlowsInfo(flows_filter["hostFilter"], flows_filter)
if flows_stats == nil then
rest_utils.answer(rest_utils.consts.err.not_found)
return
end
local total = flows_stats["numFlows"]
flows_stats = flows_stats["flows"]
if flows_stats == nil then
rest_utils.answer(rest_utils.consts.err.internal_error)
return
end
local data = {}
for _key, value in ipairs(flows_stats) do
local record = {}
local key = value["ntopng.key"]
record["key"] = string.format("%u", value["ntopng.key"])
record["hash_id"] = string.format("%u", value["hash_entry_id"])
record["first_seen"] = value["seen.first"]
record["last_seen"] = value["seen.last"]
local client = {}
local cli_name = flowinfo2hostname(value, "cli")
client["name"] = stripVlan(cli_name)
client["ip"] = value["cli.ip"]
client["port"] = value["cli.port"]
local info = interface.getHostInfo(value["cli.ip"], value["cli.vlan"])
if info then
client["is_broadcast_domain"] = info.broadcast_domain_host
client["is_dhcp"] = info.dhcpHost
client["is_blacklisted"] = info.is_blacklisted
end
record["client"] = client
local server = {}
local srv_name = flowinfo2hostname(value, "srv")
server["name"] = stripVlan(srv_name)
server["ip"] = value["srv.ip"]
server["port"] = value["srv.port"]
info = interface.getHostInfo(value["srv.ip"], value["srv.vlan"])
local info = interface.getHostInfo(value["cli.ip"], value["cli.vlan"])
if info then
server["is_broadcast"] = info.broadcast_domain_host
server["is_dhcp"] = info.dhcpHost
server["is_blacklisted"] = info.is_blacklisted
end
record["server"] = server
record["vlan"] = value["vlan"]
record["protocol"] = {}
record["protocol"]["l4"] = value["proto.l4"]
record["protocol"]["l7"] = value["proto.ndpi"]
record["duration"] = value["duration"]
record["bytes"] = value["bytes"]
record["thpt"] = {}
record["thpt"]["pps"] = value["throughput_pps"]
record["thpt"]["bps"] = value["throughput_bps"]*8
local cli2srv = round((value["cli2srv.bytes"] * 100) / value["bytes"], 0)
record["breakdown"] = {}
record["breakdown"]["cli2srv"] = cli2srv
record["breakdown"]["srv2cli"] = (100-cli2srv)
if isScoreEnabled() then
record["score"] = format_utils.formatValue(value["score"]["flow_score"])
end
if verbose then
record["packets"] = value["cli2srv.packets"] + value["srv2cli.packets"]
record["tcp"] = {}
record["tcp"]["appl_latency"] = value["tcp.appl_latency"]
record["tcp"]["nw_latency"] = {}
record["tcp"]["nw_latency"]["cli"] = value["tcp.nw_latency.client"]
record["tcp"]["nw_latency"]["srv"] = value["tcp.nw_latency.server"]
record["tcp"]["retransmissions"] = {}
record["tcp"]["retransmissions"]["cli2srv"] = value["cli2srv.retransmissions"]
record["tcp"]["retransmissions"]["srv2cli"] = value["srv2cli.retransmissions"]
record["tcp"]["out_of_order"] = {}
record["tcp"]["out_of_order"]["cli2srv"] = value["cli2srv.out_of_order"]
record["tcp"]["out_of_order"]["srv2cli"] = value["srv2cli.out_of_order"]
record["tcp"]["lost"] = {}
record["tcp"]["lost"]["cli2srv"] = value["cli2srv.lost"]
record["tcp"]["lost"]["srv2cli"] = value["srv2cli.lost"]
end
data[#data + 1] = record
end -- for
res = {
perPage = flows_filter["perPage"],
currentPage = flows_filter["currentPage"],
totalRows = total,
data = data,
sort = {
{
flows_filter["sortColumn"],
flows_filter["sortOrder"]
}
},
}
rest_utils.answer(rc, res)

View file

@ -0,0 +1,10 @@
--
-- (C) 2019-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
local alert_rest_utils = require "alert_rest_utils"
alert_rest_utils.get_alert_exclusions("flow", _GET["host"])

View file

@ -0,0 +1,56 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local rest_utils = require("rest_utils")
local flow_alert_store = require "flow_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/flow/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
-- Fetch the results
local alerts, recordsFiltered = flow_alert_store:select_request(nil, "*, hex(alerts_map) alerts_map")
for _, _value in ipairs(alerts or {}) do
res[#res + 1] = flow_alert_store:format_record(_value, no_html)
end
if no_html then
res = flow_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,43 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local flow_alert_store = require "flow_alert_store".new()
local alert_severities = require "alert_severities"
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/flow/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local ifid = _GET["ifid"]
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local res = flow_alert_store:count_by_severity_and_time_request(true)
rest_utils.answer(rc, res)

View file

@ -0,0 +1,43 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local tracker = require("tracker")
local rest_utils = require("rest_utils")
--
-- Read number of active flows per protocol
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/flow/l4/counters.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
if isEmptyString(ifid) then
rest_utils.answer(rest_utils.consts.err.invalid_interface)
return
end
interface.select(ifid)
local flowstats = interface.getActiveFlowsStats()
local l4_proto = flowstats["l4_protocols"]
for k,v in pairs(l4_proto, asc) do
res[#res + 1] = {
id = k,
count = v.count,
}
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,43 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local tracker = require("tracker")
local rest_utils = require("rest_utils")
--
-- Read number of active flows per protocol
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/flow/l7/counters.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
if isEmptyString(ifid) then
rest_utils.answer(rest_utils.consts.err.invalid_interface)
return
end
interface.select(ifid)
local flowstats = interface.getActiveFlowsStats()
local l7_proto = flowstats["ndpi"]
for k,v in pairsByKeys(l7_proto, asc) do
res[#res + 1] = {
name = k,
count = v.num_flows,
}
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local flow_pools = require "flow_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(flow_pools)

View file

@ -0,0 +1,35 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "flow_utils"
require "lua_utils"
local rest_utils = require("rest_utils")
--
-- Read list of active flows
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/flow/traffic_stats.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local flows_filter = getFlowsFilter()
local rc = rest_utils.consts.success.ok
local res
local ifid = _GET["ifid"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
-- This is used to get the current bytes rcvd and sent by these specific filters
res = interface.getActiveFlowsStats(flows_filter["hostFilter"], flows_filter, true)
rest_utils.answer(rc, res)

View file

@ -0,0 +1,270 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
require "flow_utils"
local format_utils = require("format_utils")
local json = require "dkjson"
local rest_utils = require("rest_utils")
--
-- Read list of active hosts
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/host/active.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
-- Pagination:
local all = _GET["all"]
local currentPage = _GET["currentPage"]
local perPage = _GET["perPage"]
local sortColumn = _GET["sortColumn"] -- ip, name, since, last, alerts, country, vlan, num_flows, traffic, thpt
local sortOrder = _GET["sortOrder"]
-- Filters
local mode = _GET["mode"] -- all local remote broadcast_domain filtered blacklisted dhcp
local ipversion = _GET["version"]
local protocol = _GET["protocol"]
local traffic_type = _GET["traffic_type"]
local asn = _GET["asn"]
local vlan = _GET["vlan"]
local network = _GET["network"]
local cidr = _GET["network_cidr"]
local pool = _GET["pool"]
local country = _GET["country"]
local os_ = tonumber(_GET["os"])
local mac = _GET["mac"]
local top_hidden = ternary(_GET["top_hidden"] == "1", true, nil)
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
if not isEmptyString(_GET["sortColumn"]) then
-- Backward compatibility
_GET["sortColumn"] = "column_" .. _GET["sortColumn"]
sortColumn = _GET["sortColumn"]
end
if(currentPage == nil) then
currentPage = 1
else
currentPage = tonumber(currentPage)
end
if(perPage == nil) then
perPage = getDefaultTableSize()
else
perPage = tonumber(perPage)
tablePreferences("rows_number",perPage)
end
local traffic_type_filter
if traffic_type == "one_way" then
traffic_type_filter = 1 -- ntop_typedefs.h TrafficType traffic_type_one_way
elseif traffic_type == "bidirectional" then
traffic_type_filter = 2 -- ntop_typedefs.h TrafficType traffic_type_bidirectional
end
if isEmptyString(mode) then
mode = "all"
end
interface.select(ifname)
local to_skip = (currentPage-1) * perPage
if(sortOrder == "desc") then sOrder = false else sOrder = true end
local filtered_hosts = false
local blacklisted = false
local anomalous = false
local dhcp_hosts = false
local hosts_retrv_function = interface.getHostsInfo
if mode == "local" then
hosts_retrv_function = interface.getLocalHostsInfo
elseif mode == "remote" then
hosts_retrv_function = interface.getRemoteHostsInfo
elseif mode == "broadcast_domain" then
hosts_retrv_function = interface.getBroadcastDomainHostsInfo
elseif mode == "filtered" then
filtered_hosts = true
elseif mode == "blacklisted" then
blacklisted_hosts = true
elseif mode == "dhcp" then
dhcp_hosts = true
end
local hosts_stats = hosts_retrv_function(false, sortColumn, perPage, to_skip, sOrder,
country, os_, tonumber(vlan), tonumber(asn),
tonumber(network), mac,
tonumber(pool), tonumber(ipversion),
tonumber(protocol), traffic_type_filter,
filtered_hosts, blacklisted_hosts, top_hidden, anomalous, dhcp_hosts, cidr)
if hosts_stats == nil then
rest_utils.answer(rest_utils.consts.err.not_found)
return
end
hosts_stats = hosts_stats["hosts"]
if hosts_stats == nil then
rest_utils.answer(rest_utils.consts.err.internal_error)
return
end
if all ~= nil then
perPage = 0
currentPage = 0
end
function get_host_name(h)
if h["name"] == nil then
if h["ip"] ~= nil then
h["name"] = ip2label(h["ip"])
else
h["name"] = h["mac"]
end
end
return(h["name"])
end
local vals = {}
local num = 0
for key, value in pairs(hosts_stats) do
num = num + 1
postfix = string.format("0.%04u", num)
if(isEmptyString(sortColumn)) then
vals[key] = key
elseif(sortColumn == "column_name") then
hosts_stats[key]["name"] = get_host_name(hosts_stats[key])
vals[hosts_stats[key]["name"]..postfix] = key
elseif(sortColumn == "column_since") then
vals[hosts_stats[key]["seen.first"]+postfix] = key
elseif(sortColumn == "column_alerts") then
vals[hosts_stats[key]["num_alerts"]+postfix] = key
elseif(sortColumn == "column_last") then
vals[hosts_stats[key]["seen.last"]+postfix] = key
elseif(sortColumn == "column_country") then
vals[hosts_stats[key]["country"]..postfix] = key
elseif(sortColumn == "column_vlan") then
vals[hosts_stats[key]["vlan"]..postfix] = key
elseif(sortColumn == "column_num_flows") then
local t = hosts_stats[key]["active_flows.as_client"]+hosts_stats[key]["active_flows.as_server"]
vals[t+postfix] = key
elseif(sortColumn == "column_num_dropped_flows") then
local t = hosts_stats[key]["flows.dropped"] or 0
vals[t+postfix] = key
elseif(sortColumn == "column_traffic") then
vals[hosts_stats[key]["bytes.sent"]+hosts_stats[key]["bytes.rcvd"]+postfix] = key
elseif(sortColumn == "column_thpt") then
vals[hosts_stats[key]["throughput_bps"]+postfix] = key
elseif(sortColumn == "column_queries") then
vals[hosts_stats[key]["queries.rcvd"]+postfix] = key
elseif(sortColumn == "column_ip") then
vals[hosts_stats[key]["ipkey"]+postfix] = key
else
vals[key] = key
end
end
if sortOrder == "asc" then
funct = asc
else
funct = rev
end
local data = {}
for _key, _value in pairsByKeys(vals, funct) do
local record = {}
local key = vals[_key]
local value = hosts_stats[key]
local symkey = hostinfo2jqueryid(hosts_stats[key])
record["key"] = symkey
record["first_seen"] = value["seen.first"]
record["last_seen"] = value["seen.last"]
record["vlan"] = value["vlan"]
record["ip"] = stripVlan(key)
record["os"] = value["os"]
record["num_alerts"] = value["num_alerts"]
local host = interface.getHostInfo(hosts_stats[key].ip, hosts_stats[key].vlan)
if host ~= nil then
record["country"] = host["country"]
record["is_blacklisted"] = host["is_blacklisted"]
end
local name = value["name"]
if isEmptyString(name) then
local hinfo = hostkey2hostinfo(key)
name = hostinfo2label(hinfo)
end
if isEmptyString(name) then
name = key
end
if value["ip"] ~= nil then
local label = hostinfo2label(value)
if label ~= value["ip"] and name ~= label then
name = name .. " ["..label.."]"
end
end
record["name"] = name
record["thpt"] = {}
record["thpt"]["pps"] = value["throughput_pps"]
record["thpt"]["bps"] = value["throughput_bps"]*8
record["bytes"] = {}
record["bytes"]["total"] = (value["bytes.sent"]+value["bytes.rcvd"])
record["bytes"]["sent"] = value["bytes.sent"]
record["bytes"]["recvd"] = value["bytes.rcvd"]
record["is_localhost"] = value["localhost"]
record["is_multicast"] = value["is_multicast"]
record["is_broadcast"] = value["is_broadcast"]
record["is_broadcast_domain"] = value["broadcast_domain_host"]
record["num_flows"] = {}
record["num_flows"]["total"] = (value["active_flows.as_client"] + value["active_flows.as_server"])
record["num_flows"]["as_client"] = (value["active_flows.as_client"])
record["num_flows"]["as_server"] = (value["active_flows.as_server"])
data[#data + 1] = record
end -- for
res = {
perPage = perPage,
currentPage = currentPage,
totalRows = total,
data = data,
sort = {
{
sortColumn,
sortOrder
}
},
}
rest_utils.answer(rc, res)

View file

@ -0,0 +1,10 @@
--
-- (C) 2019-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
local alert_rest_utils = require "alert_rest_utils"
alert_rest_utils.get_alert_exclusions("host", _GET["host"])

View file

@ -0,0 +1,57 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local auth = require "auth"
local rest_utils = require("rest_utils")
local host_alert_store = require "host_alert_store".new()
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/host/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
-- Fetch the results
local alerts, recordsFiltered = host_alert_store:select_request()
for _, _value in ipairs(alerts or {}) do
res[#res + 1] = host_alert_store:format_record(_value, no_html)
end
if no_html then
res = host_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,43 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local auth = require "auth"
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local host_alert_store = require "host_alert_store".new()
local alert_severities = require "alert_severities"
--
-- Read alerts count by time
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/host/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
local ifid = _GET["ifid"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local res = host_alert_store:count_by_severity_and_time_request()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,128 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local tracker = require("tracker")
local rest_utils = require("rest_utils")
--
-- Read information about a host and maps host fields into custom fields
-- Example: curl -s -u admin:admin -H "Content-Type: application/json" -H "Content-Type: application/json" -d '{"host": "192.168.2.222", "ifid":"0"}' http://localhost:3000/lua/rest/v2/get/host/custom_data.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local field_aliases = {}
local ifid = _GET["ifid"]
local fields = _GET["field_alias"]
if isEmptyString(ifid) then
rest_utils.answer(rest_utils.consts.err.invalid_interface)
return
end
interface.select(ifid)
-- Valid fields:
-- 1) All: {"field_alias": "all"} - Dump all host stats.
-- -- Or --
-- All: Omit the "field_alias" parameter.
-- 2) Aliases: {"field_alias": "bytes.sent=tdb,packets.sent=tdp"}
-- 3) Mixed: {"field_alias": "bytes.sent=tdb,packets.sent,ndpi=dpi"}
--
-- If the 'fields' parameter is missing 'all' host stat
-- fields will be dumped...
if (fields == nil) then
field_aliases[#field_aliases + 1] = "all=all"
else
--
-- Invalid field alias...
if isEmptyString(fields) then
rest_utils.answer(rest_utils.consts.err.invalid_args)
return
end
--
-- Build host stats fields to use with potential aliases...
local field = fields:split(",") or {fields}
for _, fa in pairs(field) do
local comp = fa:split("=")
if (comp ~= nil) then
--
-- Field and alias...
field_aliases[#field_aliases + 1] = comp[1] .. "=" .. comp[2]
else
--
-- Alias same as field...
field_aliases[#field_aliases + 1] = fa .. "=" .. fa
end
end
end
local hostparam = _GET["host"]
if ((hostparam ~= nil) or (not isEmptyString(hostparam))) then
--
-- Single host:
local host_info = url2hostinfo(_GET)
local host = interface.getHostInfo(host_info["host"], host_info["vlan"])
if not host then
rest_utils.answer(rest_utils.consts.err.not_found)
return
else
--
-- Check for 'all' host stat fields...
if (field_aliases[1] == "all=all") then
res = host
else
--
-- Process selective host stat fields...
for _, fa in pairs(field_aliases) do
local comp = fa:split("=")
local field = comp[1]
local alias = comp[2]
if (host[field] ~= nil) then
--
-- Add host field stat with potential alias name...
res[alias] = host[field]
end
end
end
tracker.log("get_host_custom_data_json", {ifid, host_info["host"], host_info["vlan"], field_aliases})
rest_utils.answer(rc, res)
return
end
else
--
-- All hosts:
local hosts_stats = interface.getHostsInfo()
hosts_stats = hosts_stats["hosts"]
for key, value in pairs(hosts_stats) do
local host = interface.getHostInfo(key)
if (host ~= nil) then
local hdata = {}
if (field_aliases[1] == "all=all") then
hdata = host
else
for _, fa in pairs(field_aliases) do
local comp = fa:split("=")
local field = comp[1]
local alias = comp[2]
if (host[field] ~= nil) then
hdata[alias] = host[field]
end
end
end
res[#res + 1] = hdata
end
end
tracker.log("get_host_custom_data_json", {ifid, "All Hosts", field_aliases})
rest_utils.answer(rc, res)
return
end

View file

@ -0,0 +1,131 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local tracker = require("tracker")
local rest_utils = require("rest_utils")
--
-- Read information about a host
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1", "host" : "192.168.1.1"}' http://localhost:3000/lua/rest/v2/get/host/data.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local host_info = url2hostinfo(_GET)
-- whether to return host statistics: on by default
local host_stats = _GET["host_stats"]
-- whether to return statistics regarding host flows: off by default
local host_stats_flows = _GET["host_stats_flows"]
local host_stats_flows_num = _GET["limit"]
if isEmptyString(ifid) then
rest_utils.answer(rest_utils.consts.err.invalid_interface)
return
end
if isEmptyString(host_info["host"]) then
rest_utils.answer(rest_utils.consts.err.invalid_args)
return
end
interface.select(ifid)
local host = interface.getHostInfo(host_info["host"], host_info["vlan"])
if not host then
rest_utils.answer(rest_utils.consts.err.not_found)
return
end
local function flows2protocolthpt(flows)
local protocol_thpt = {}
for _, flow in pairs(flows) do
local proto_ndpi = ""
if flow["proto.ndpi"] == nil or flow["proto.ndpi"] == "" then
goto continue
else
proto_ndpi = flow["proto.ndpi"]
end
if protocol_thpt[proto_ndpi] == nil then
protocol_thpt[proto_ndpi] =
{["cli2srv"]={["throughput_bps"]=0, ["throughput_pps"]=0},
["srv2cli"]={["throughput_bps"]=0, ["throughput_pps"]=0}}
end
for _, dir in pairs({"cli2srv", "srv2cli"}) do
for _, dim in pairs({"bps", "pps"}) do
protocol_thpt[proto_ndpi][dir]["throughput_"..dim] =
protocol_thpt[proto_ndpi][dir]["throughput_"..dim] + flow[dir..".throughput_"..dim]
end
end
::continue::
end
return protocol_thpt
end
-- hosts stats are on by default, one must explicitly disable them
if not (host_stats == nil or host_stats == "" or host_stats == "true" or host_stats == "1") then
host = {}
end
-- host flow stats are off by default and must be explicitly enabled
if host_stats_flows ~= nil and host_stats_flows ~= "" then
if host_stats_flows_num == nil or tonumber(host_stats_flows_num) == nil then
-- default: do not limit the number of flows
host_stats_flows_num = 99999
else
-- ... unless otherwise specified
host_stats_flows_num = tonumber(host_stats_flows_num)
end
local total = 0
local pageinfo = {["sortColumn"]="column_bytes", ["a2zSortOrder"]=false,
["maxHits"]=host_stats_flows_num, ["toSkip"]=0, ["detailedResults"]=true}
--local flows = interface.getFlowsInfo(host_info["host"], nil, "column_bytes", host_stats_flows_num, 0, false)
local flows = interface.getFlowsInfo(host_info["host"], pageinfo)
flows = flows["flows"]
for i, fl in ipairs(flows) do
flows[i] = {
["srv.ip"] = fl["srv.ip"], ["cli.ip"] = fl["cli.ip"],
["srv.port"] = fl["srv.port"], ["cli.port"] = fl["cli.port"],
["proto.ndpi_id"] = fl["proto.ndpi_id"], ["proto.ndpi"] = fl["proto.ndpi"],
["bytes"] = fl["bytes"],
["cli2srv.throughput_bps"] = round(fl["throughput_cli2srv_bps"], 2),
["srv2cli.throughput_bps"] = round(fl["throughput_srv2cli_bps"], 2),
["cli2srv.throughput_pps"] = round(fl["throughput_cli2srv_pps"], 2),
["srv2cli.throughput_pps"] = round(fl["throughput_srv2cli_pps"], 2),
}
if fl["proto.l4"] == "TCP" then
flows[i]["cli2srv.tcp_flags"] = TCPFlags2table(fl["cli2srv.tcp_flags"])
flows[i]["srv2cli.tcp_flags"] = TCPFlags2table(fl["srv2cli.tcp_flags"])
flows[i]["tcp_established"] = fl["tcp_established"]
end
end
host["ndpiThroughputStats"] = flows2protocolthpt(flows)
host["flows"] = flows
host["flows_count"] = total
end
res = host
tracker.log("host_get_json", {host_info["host"], host_info["vlan"]})
rest_utils.answer(rc, res)

View file

@ -0,0 +1,58 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local stats_utils = require("stats_utils")
local rest_utils = require("rest_utils")
local dscp_consts = require "dscp_consts"
--
-- Read DSCP statistics for a hsot
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1", "host" : "192.168.56.103", "direction": "recv"}' http://localhost:3000/lua/rest/v2/get/host/dscp/stats.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local ifid = _GET["ifid"]
local host_info = url2hostinfo(_GET)
local direction = _GET["direction"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
local received_stats = false
if direction == "recv" then
received_stats = true
end
interface.select(ifid)
local res = {}
local tot = 0
local stats = interface.getHostInfo(host_info["host"], host_info["vlan"])
if stats == nil then
rest_utils.answer(rest_utils.consts.err.not_found)
return
end
for key, value in pairsByKeys(stats.dscp, asc) do
res[#res + 1] = {
label = dscp_consts.ds_class_descr(key),
value = ternary(received_stats, value['packets.rcvd'], value['packets.sent'])
}
end
local collapsed = stats_utils.collapse_stats(res, 1)
rest_utils.answer(rc, collapsed)

View file

@ -0,0 +1,76 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local graph_utils = require "graph_utils"
require "flow_utils"
require "historical_utils"
local fingerprint_utils = require "fingerprint_utils"
local rest_utils = require("rest_utils")
local available_fingerprints = {
ja3 = {
stats_key = "ja3_fingerprint",
href = function(fp) return '<A HREF="https://sslbl.abuse.ch/ja3-fingerprints/'..fp..'" target="_blank">'..fp..'</A> <i class="fas fa-external-link-alt"></i>' end
},
hassh = {
stats_key = "hassh_fingerprint",
href = function(fp) return fp end
}
}
-- Parameters used for the rest answer --
local rc
local res = {}
local ifid = _GET["ifid"]
local host_info = url2hostinfo(_GET)
local fingerprint_type = _GET["fingerprint_type"]
-- #####################################################################
local stats
if isEmptyString(fingerprint_type) then
rc = rest_utils.consts.err.invalid_args
rest_utils.answer(rc)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
if isEmptyString(host_info["host"]) then
rc = rest_utils.consts.err.invalid_args
rest_utils.answer(rc)
return
end
if(host_info["host"] ~= nil) then
stats = interface.getHostInfo(host_info["host"], host_info["vlan"])
end
stats = stats or {}
if fingerprint_type == "ja3" then
stats = stats and stats.ja3_fingerprint or {}
elseif fingerprint_type == "hassh" then
stats = stats and stats.hassh_fingerprint or {}
end
for key, value in pairs(stats) do
res[#res + 1] = value
res[#res][fingerprint_type] = key
end
rc = rest_utils.consts.success.ok
rest_utils.answer(rc, res)

View file

@ -0,0 +1,77 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local graph_utils = require "graph_utils"
require "flow_utils"
require "historical_utils"
local fingerprint_utils = require "fingerprint_utils"
local rest_utils = require("rest_utils")
local available_fingerprints = {
ja3 = {
stats_key = "ja3_fingerprint",
href = function(fp) return '<A HREF="https://sslbl.abuse.ch/ja3-fingerprints/'..fp..'" target="_blank">'..fp..'</A> <i class="fas fa-external-link-alt"></i>' end
},
hassh = {
stats_key = "hassh_fingerprint",
href = function(fp) return fp end
}
}
-- Parameters used for the rest answer --
local rc
local res = {}
local ifid = _GET["ifid"]
local host_info = url2hostinfo(_GET)
local fingerprint_type = _GET["fingerprint_type"]
-- #####################################################################
local stats
if isEmptyString(fingerprint_type) then
rc = rest_utils.consts.err.invalid_args
rest_utils.answer(rc)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
if isEmptyString(host_info["host"]) then
rc = rest_utils.consts.err.invalid_args
rest_utils.answer(rc)
return
end
if(host_info["host"] ~= nil) then
stats = interface.getHostInfo(host_info["host"], host_info["vlan"])
end
stats = stats or {}
if fingerprint_type == "ja3" then
stats = stats and stats.ja3_fingerprint
elseif fingerprint_type == "hassh" then
stats = stats and stats.hassh_fingerprint
end
tprint(stats)
for key, value in pairs(stats) do
res[#res + 1] = value
res[#res]["ja3_fingerprint"] = key
end
rc = rest_utils.consts.success.ok
rest_utils.answer(rc, res)

View file

@ -0,0 +1,46 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local rest_utils = require("rest_utils")
--
-- Retrieves all ntopng interfaces of a given host
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"host" : "192.168.1.1"}' http://localhost:3000/lua/rest/v2/get/host/interfaces.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local host_info = url2hostinfo(_GET)
if isEmptyString(host_info["host"]) then
rest_utils.answer(rest_utils.consts.err.invalid_args)
return
end
local host_key = hostinfo2hostkey(host_info)
-- Use the host as key in the response so it will be easier to extend
-- this endpoint with multiple hosts if necessary
res[host_key] = {}
for ifid, _ in pairs(interface.getIfNames()) do
-- Possibly allowerd interface already enforced by iterator
interface.select(ifid)
local cur_host_info = interface.getHostInfo(host_key)
if cur_host_info then
-- Host found on the given interface
res[host_key][#res[host_key] + 1] = {ifid = interface.getId()}
end
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,85 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local rest_utils = require("rest_utils")
local stats_utils = require("stats_utils")
--
-- Read statistics about nDPI application protocols for a hsot
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1", "host": "192.168.1.1"}' http://localhost:3000/lua/rest/v2/get/host/l7/stats.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local host_info = url2hostinfo(_GET)
local breed = _GET["breed"]
local ndpi_category = _GET["ndpi_category"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
local show_breed = false
if breed == "true" then
show_breed = true
end
local show_ndpi_category = false
if ndpi_category == "true" then
show_ndpi_category = true
end
interface.select(ifid)
local ndpi_protos = interface.getnDPIProtocols()
local function getAppUrl(app)
if ndpi_protos[app] ~= nil then
return ntop.getHttpPrefix().."/lua/flows_stats.lua?application="..app
end
return nil
end
local tot = 0
local stats = interface.getHostInfo(host_info["host"], host_info["vlan"])
if stats == nil then
rest_utils.answer(rest_utils.consts.err.not_found)
return
end
tot = stats["bytes.sent"] + stats["bytes.rcvd"]
local _ifstats = computeL7Stats(stats, show_breed, show_ndpi_category)
for key, value in pairsByValues(_ifstats, rev) do
local duration = 0
if(stats["ndpi"][key] ~= nil) then
duration = stats["ndpi"][key]["duration"]
end
res[#res + 1] = {
label = key,
value = value,
duration = duration,
}
end
local collapsed = stats_utils.collapse_stats(res, 1, 3 --[[ threshold ]])
rest_utils.answer(rc, collapsed)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local host_pools = require "host_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pool_members(host_pools)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local host_pools = require "host_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pool_by_member(host_pools)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local host_pools = require "host_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(host_pools)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local host_pool_pools = require "host_pool_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(host_pool_pools)

View file

@ -0,0 +1,50 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local alert_utils = require "alert_utils"
local json = require("dkjson")
local rest_utils = require("rest_utils")
--
-- Read the IP address(es) for an interface
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/interface/address.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local ifstats = interface.getStats()
local addresses = {}
if not isEmptyString(ifstats.ip_addresses) then
local tokens = split(ifstats.ip_addresses, ",")
if tokens ~= nil then
for _,s in pairs(tokens) do
addresses[#addresses+1] = s
end
end
end
res.addresses = addresses;
rest_utils.answer(rc, res)

View file

@ -0,0 +1,56 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local auth = require "auth"
local rest_utils = require("rest_utils")
local interface_alert_store = require "interface_alert_store".new()
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/interface/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
-- Fetch the results
local alerts, recordsFiltered = interface_alert_store:select_request()
for _, _value in ipairs(alerts or {}) do
res[#res + 1] = interface_alert_store:format_record(_value, no_html)
end
if no_html then
res = interface_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,43 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local auth = require "auth"
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local interface_alert_store = require "interface_alert_store".new()
--
-- Read alerts count by time
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/interface/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local res = interface_alert_store:count_by_severity_and_time_request()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,67 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local rest_utils = require("rest_utils")
local json = require("dkjson")
-- Parameters used for the rest answer --
local rc
local res = {}
--interface.select(ifname)
local ifid = _GET["ifid"]
local host_info = url2hostinfo(_GET)
-- #####################################################################
local is_host
local stats
local table = {}
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
if(host_info["host"] ~= nil) then
local breakdown = {}
-- Show ARP sent/recv breakdown
stats = interface.getMacInfo(host_info["host"])
if stats ~= nil then
local arp_sent = stats["arp_requests.sent"] + stats["arp_replies.sent"]
local arp_rcvd = stats["arp_requests.rcvd"] + stats["arp_replies.rcvd"]
breakdown[#breakdown + 1] = {label=i18n("sent"), value=arp_sent}
breakdown[#breakdown + 1] = {label=i18n("received"), value=arp_rcvd}
end
print(json.encode(breakdown, nil))
else
-- Show ARP stats for interface
stats = interface.getStats()
for k,v in pairs(stats) do
if k == "arp.requests" then
res[#res + 1] = {}
res[#res]["type"] = i18n("details.arp_requests")
res[#res]["packets"] = v
end
if k == "arp.replies" then
res[#res + 1] = {}
res[#res]["type"] = i18n("details.arp_replies")
res[#res]["packets"] = v
end
end
rc = rest_utils.consts.success.ok
rest_utils.answer(rc, res)
end

View file

@ -0,0 +1,38 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local alert_utils = require "alert_utils"
local json = require("dkjson")
local rest_utils = require("rest_utils")
--
-- Read the broadcast domains discovered for an interface
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/interface/bcast_domains.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local ifstats = interface.getStats()
res.bcast_domains = ifstats.bcast_domains;
rest_utils.answer(rc, res)

View file

@ -0,0 +1,275 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local alert_utils = require "alert_utils"
local json = require("dkjson")
local ts_utils = require("ts_utils_core")
local plugins_utils = require("plugins_utils")
local periodic_activities_utils = require "periodic_activities_utils"
local cpu_utils = require("cpu_utils")
local callback_utils = require("callback_utils")
local recording_utils = require("recording_utils")
local alert_consts = require("alert_consts")
local rest_utils = require("rest_utils")
local auth = require "auth"
--
-- Read information about an interface
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/interface/data.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local iffilter = _GET["iffilter"]
if isEmptyString(ifid) and isEmptyString(iffilter) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
local function userHasRestrictions()
local allowed_nets = ntop.getPref("ntopng.user." .. (_SESSION["user"] or "") .. ".allowed_nets")
for _, net in pairs(split(allowed_nets, ",")) do
if not isEmptyString(net) and net ~= "0.0.0.0/0" and net ~= "::/0" then
return true
end
end
return false
end
local function countHosts()
local res = {
local_hosts = 0,
hosts = 0,
}
for host, info in callback_utils.getHostsIterator(false --[[no details]]) do
if info.localhost then
res.local_hosts = res.local_hosts + 1
end
res.hosts = res.hosts + 1
end
return res
end
function dumpInterfaceStats(ifid)
local interface_name = getInterfaceName(ifid)
interface.select(ifid..'')
local ifstats = interface.getStats()
local res = {}
if(ifstats ~= nil) then
local uptime = ntop.getUptime()
local prefs = ntop.getPrefs()
-- Round up
local hosts_pctg = math.floor(1+((ifstats.stats.hosts*100)/prefs.max_num_hosts))
local flows_pctg = math.floor(1+((ifstats.stats.flows*100)/prefs.max_num_flows))
local macs_pctg = math.floor(1+((ifstats.stats.current_macs*100)/prefs.max_num_hosts))
res["ifid"] = ifid
res["ifname"] = interface_name
res["speed"] = getInterfaceSpeed(ifstats.id)
res["periodic_stats_update_frequency_secs"] = ifstats.periodic_stats_update_frequency_secs
-- network load is used by web pages that are shown to the user
-- so we must return statistics since the latest (possible) reset
res["packets"] = ifstats.stats_since_reset.packets
res["bytes"] = ifstats.stats_since_reset.bytes
res["drops"] = ifstats.stats_since_reset.drops
if ifstats.stats_since_reset.discarded_probing_packets then
res["discarded_probing_packets"] = ifstats.stats_since_reset.discarded_probing_packets
res["discarded_probing_bytes"] = ifstats.stats_since_reset.discarded_probing_bytes
end
res["throughput_bps"] = ifstats.stats.throughput_bps;
res["throughput_pps"] = ifstats.stats.throughput_pps;
if prefs.is_dump_flows_enabled == true then
res["flow_export_drops"] = ifstats.stats_since_reset.flow_export_drops
res["flow_export_rate"] = ifstats.stats_since_reset.flow_export_rate
res["flow_export_count"] = ifstats.stats_since_reset.flow_export_count
end
if auth.has_capability(auth.capabilities.alerts) then
res["engaged_alerts"] = ifstats["num_alerts_engaged"] or 0
res["dropped_alerts"] = ifstats["num_dropped_alerts"] or 0
res["host_dropped_alerts"] = ifstats["num_host_dropped_alerts"] or 0
res["flow_dropped_alerts"] = ifstats["num_flow_dropped_alerts"] or 0
res["other_dropped_alerts"] = ifstats["num_other_dropped_alerts"] or 0
-- Active flow alerts: total
res["alerted_flows"] = ifstats["num_alerted_flows"] or 0
-- Active flow alerts: breakdown
res["alerted_flows_notice"] = ifstats["num_alerted_flows_notice"] or 0
res["alerted_flows_warning"] = ifstats["num_alerted_flows_warning"] or 0
res["alerted_flows_error"] = ifstats["num_alerted_flows_error"] or 0
end
if periodic_activities_utils.have_degraded_performance() then
res["degraded_performance"] = true
end
if not userHasRestrictions() then
res["num_flows"] = ifstats.stats.flows
res["num_hosts"] = ifstats.stats.hosts
res["num_local_hosts"] = ifstats.stats.local_hosts
res["num_devices"] = ifstats.stats.devices
else
local num_hosts = countHosts()
res["num_hosts"] = num_hosts.hosts
res["num_local_hosts"] = num_hosts.local_hosts
end
res["epoch"] = os.time()
res["localtime"] = os.date("%H:%M:%S %z", res["epoch"])
res["uptime"] = secondsToTime(uptime)
if ntop.isPro() then
local product_info = ntop.getInfo(true)
if product_info["pro.out_of_maintenance"] then
res["out_of_maintenance"] = true
end
end
res["system_host_stats"] = cpu_utils.systemHostStats()
res["hosts_pctg"] = hosts_pctg
res["flows_pctg"] = flows_pctg
res["macs_pctg"] = macs_pctg
res["remote_pps"] = ifstats.remote_pps
res["remote_bps"] = ifstats.remote_bps
res["is_view"] = ifstats.isView
if isAdministrator() then
res["num_live_captures"] = ifstats.stats.num_live_captures
end
res["local2remote"] = ifstats["localstats"]["bytes"]["local2remote"]
res["remote2local"] = ifstats["localstats"]["bytes"]["remote2local"]
res["bytes_upload"] = ifstats["eth"]["egress"]["bytes"]
res["bytes_download"] = ifstats["eth"]["ingress"]["bytes"]
res["packets_upload"] = ifstats["eth"]["egress"]["packets"]
res["packets_download"] = ifstats["eth"]["ingress"]["packets"]
res["num_local_hosts_anomalies"] = ifstats.anomalies.num_local_hosts_anomalies
res["num_remote_hosts_anomalies"] = ifstats.anomalies.num_remote_hosts_anomalies
local ingress_thpt = ifstats["eth"]["ingress"]["throughput"]
local egress_thpt = ifstats["eth"]["egress"]["throughput"]
res["throughput"] = {
download = {
bps = ingress_thpt["bps"], bps_trend = ingress_thpt["bps_trend"],
pps = ingress_thpt["pps"], pps_trend = ingress_thpt["pps_trend"]
},
upload = {
bps = egress_thpt["bps"], bps_trend = egress_thpt["bps_trend"],
pps = egress_thpt["pps"], pps_trend = egress_thpt["pps_trend"]
},
}
if ntop.isnEdge() and ifstats.type == "netfilter" and ifstats.netfilter then
res["netfilter"] = ifstats.netfilter
end
if(ifstats.zmqRecvStats ~= nil) then
if ifstats.zmqRecvStats_since_reset then
-- override stats with the values calculated from the latest user reset
-- for consistency with if_stats.lua
for k, v in pairs(ifstats.zmqRecvStats_since_reset) do
ifstats.zmqRecvStats[k] = v
end
end
res["zmqRecvStats"] = {}
res["zmqRecvStats"]["flows"] = ifstats.zmqRecvStats.flows
res["zmqRecvStats"]["dropped_flows"] = ifstats.zmqRecvStats.dropped_flows
res["zmqRecvStats"]["events"] = ifstats.zmqRecvStats.events
res["zmqRecvStats"]["counters"] = ifstats.zmqRecvStats.counters
res["zmqRecvStats"]["zmq_msg_rcvd"] = ifstats.zmqRecvStats.zmq_msg_rcvd
res["zmqRecvStats"]["zmq_msg_drops"] = ifstats.zmqRecvStats.zmq_msg_drops
res["zmqRecvStats"]["zmq_avg_msg_flows"] = math.max(1, ifstats.zmqRecvStats.flows / (ifstats.zmqRecvStats.zmq_msg_rcvd + 1))
res["zmq.num_flow_exports"] = ifstats["zmq.num_flow_exports"] or 0
res["zmq.num_exporters"] = ifstats["zmq.num_exporters"] or 0
res["zmq.drops.export_queue_full"] = ifstats["zmq.drops.export_queue_full"] or 0
res["zmq.drops.flow_collection_drops"] = ifstats["zmq.drops.flow_collection_drops"] or 0
res["zmq.drops.flow_collection_udp_socket_drops"] = ifstats["zmq.drops.flow_collection_udp_socket_drops"] or 0
end
res["tcpPacketStats"] = {}
res["tcpPacketStats"]["retransmissions"] = ifstats.tcpPacketStats.retransmissions
res["tcpPacketStats"]["out_of_order"] = ifstats.tcpPacketStats.out_of_order
res["tcpPacketStats"]["lost"] = ifstats.tcpPacketStats.lost
if interface.isSyslogInterface() then
res["syslog"] = {}
res["syslog"]["tot_events"] = ifstats.syslog.tot_events
res["syslog"]["malformed"] = ifstats.syslog.malformed
res["syslog"]["dispatched"] = ifstats.syslog.dispatched
res["syslog"]["unhandled"] = ifstats.syslog.unhandled
res["syslog"]["alerts"] = ifstats.syslog.alerts
res["syslog"]["host_correlations"] = ifstats.syslog.host_correlations
res["syslog"]["flows"] = ifstats.syslog.flows
end
if(ifstats["profiles"] ~= nil) then
res["profiles"] = ifstats["profiles"]
end
if recording_utils.isAvailable() then
if recording_utils.isEnabled(ifstats.id) then
if recording_utils.isActive(ifstats.id) then
res["traffic_recording"] = "recording"
else
res["traffic_recording"] = "failed"
end
end
if recording_utils.isEnabled(ifstats.id) then
local jobs_info = recording_utils.extractionJobsInfo(ifstats.id)
if jobs_info.ready > 0 then
res["traffic_extraction"] = "ready"
elseif jobs_info.total > 0 then
res["traffic_extraction"] = jobs_info.total
end
res["traffic_extraction_num_tasks"] = jobs_info.total
end
end
end
return res
end
-- ###############################
if(iffilter == "all") then
for cur_ifid, ifname in pairs(interface.getIfNames()) do
-- ifid in the key must be a string or json.encode will think
-- its a lua array and will look for integers starting at one
res[cur_ifid..""] = dumpInterfaceStats(cur_ifid)
end
elseif not isEmptyString(iffilter) then
res = dumpInterfaceStats(iffilter)
else
res = dumpInterfaceStats(ifid)
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,49 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local rest_utils = require("rest_utils")
local stats_utils = require("stats_utils")
local dscp_consts = require "dscp_consts"
--
-- Read DSCP statistics on an interface
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/interface/dscp/stats.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local stats = interface.getStats()
if stats == nil then
rest_utils.answer(rest_utils.consts.err.internal_error)
return
end
for key, value in pairsByKeys(stats.dscp, asc) do
res[#res + 1] = {
label = dscp_consts.ds_class_descr(key),
value = value['packets.rcvd'] + value['packets.sent']
}
end
local collapsed = stats_utils.collapse_stats(res, 1)
rest_utils.answer(rc, collapsed)

View file

@ -0,0 +1,124 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local rest_utils = require("rest_utils")
local stats_utils = require("stats_utils")
--
-- Read statistics about nDPI application protocols on an interface
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1", "ndpistats_mode": "count"}' http://localhost:3000/lua/rest/v2/get/interface/l7/stats.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local ndpistats_mode = _GET["ndpistats_mode"]
local breed = _GET["breed"]
local ndpi_category = _GET["ndpi_category"]
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
local show_breed = false
if breed == "true" then
show_breed = true
end
local show_ndpi_category = false
if ndpi_category == "true" then
show_ndpi_category = true
end
interface.select(ifid)
local ndpi_protos = interface.getnDPIProtocols()
local function getAppUrl(app)
if ndpi_protos[app] ~= nil then
return ntop.getHttpPrefix().."/lua/flows_stats.lua?application="..app
end
return nil
end
local stats
local tot = 0
if ndpistats_mode == "sinceStartup" then
stats = interface.getStats()
tot = stats.stats.bytes
elseif ndpistats_mode == "count" then
stats = interface.getnDPIFlowsCount()
else
rest_utils.answer(rest_utils.consts.err.invalid_args)
return
end
if stats == nil then
rest_utils.answer(rest_utils.consts.err.internal_error)
return
end
if(ndpistats_mode == "count") then
tot = 0
for k, v in pairs(stats) do
tot = tot + v
stats[k] = tonumber(v)
end
local threshold = (tot * 3) / 100
local num = 0
for k, v in pairsByValues(stats, rev) do
if((num < 5) and (v > threshold)) then
res[#res + 1] = {
label = k,
value = v,
url = getAppUrl(k),
}
num = num + 1
tot = tot - v
else
break
end
end
if(tot > 0) then
res[#res + 1] = {
label = i18n("other"),
value = tot,
}
elseif(num == 0) then
res[#res + 1] = {
label = i18n("no_flows"),
value = 0,
}
end
rest_utils.answer(rc, res)
return
end
local _ifstats = computeL7Stats(stats, show_breed, show_ndpi_category)
for key, value in pairsByValues(_ifstats, rev) do
res[#res + 1] = {
label = key,
value = value,
url = getAppUrl(key),
}
end
local collapsed = stats_utils.collapse_stats(res, 1, 3 --[[ threshold ]])
rest_utils.answer(rc, collapsed)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local interface_pools = require "interface_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(interface_pools)

View file

@ -0,0 +1,41 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require "dkjson"
local rest_utils = require "rest_utils"
--
-- Read all the L4 protocols
-- Example: curl -u admin:admin -H "Content-Type: application/json" http://localhost:3000/lua/rest/v2/get/l4/protocol/consts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
for _, l4_key in pairs(l4_keys) do
-- l4_keys example structure
-- table
-- 1 table
-- 1.1 string IP
-- 1.2 string ip
-- 1.3 number 0
-- 2 table
-- 2.1 string ICMP
-- 2.2 string icmp
-- 2.3 number 1
res[#res + 1] = {
name = l4_key[1],
other = l4_key[2],
id = l4_key[3],
}
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,36 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require "dkjson"
local rest_utils = require "rest_utils"
--
-- Read all the defined L7 application protocols
-- Example: curl -u admin:admin -H "Content-Type: application/json" http://localhost:3000/lua/rest/v2/get/l7/application/consts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local applications = interface.getnDPIProtocols()
for application, appl_id in pairs(applications) do
appl_id = tonumber(appl_id)
local cat = ntop.getnDPIProtoCategory(appl_id)
res[#res + 1] = {
name = application,
appl_id = appl_id,
cat_id = cat.id,
}
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,48 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require "dkjson"
local rest_utils = require "rest_utils"
--
-- Read all the defined L7 application categories
-- Example: curl -u admin:admin -H "Content-Type: application/json" http://localhost:3000/lua/rest/v2/get/l7/category/consts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local app_list = {}
local categories = interface.getnDPICategories()
local applications = interface.getnDPIProtocols()
for category, cat_id in pairs(categories) do
local tmp_app_list = {}
-- Get the list of the current cat_id
for tmp_proto_name, tmp_proto_id in pairsByKeys(interface.getnDPIProtocols(tonumber(cat_id)), asc_insensitive) do
tmp_app_list[#tmp_app_list + 1] = {
name = tmp_proto_name,
id = tmp_proto_id,
}
end
-- Create the record for the cat_id
res[#res + 1] = {
name = category,
cat_id = tonumber(cat_id),
app_list = tmp_app_list,
}
end
rest_utils.answer(rc, res)

View file

@ -0,0 +1,56 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local rest_utils = require("rest_utils")
local mac_alert_store = require "mac_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/mac/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
-- Fetch the results
local alerts, recordsFiltered = mac_alert_store:select_request()
for _, _value in ipairs(alerts or {}) do
res[#res + 1] = mac_alert_store:format_record(_value, no_html)
end
if no_html then
res = mac_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,42 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local mac_alert_store = require "mac_alert_store".new()
local auth = require "auth"
--
-- Read alerts count by time
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/mac/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local ifid = _GET["ifid"]
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local res = mac_alert_store:count_by_severity_and_time_request()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local mac_pools = require "mac_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(mac_pools)

View file

@ -0,0 +1,56 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local rest_utils = require("rest_utils")
local network_alert_store = require "network_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/network/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
-- Fetch the results
local alerts, recordsFiltered = network_alert_store:select_request()
for _, _value in ipairs(alerts or {}) do
res[#res + 1] = network_alert_store:format_record(_value, no_html)
end
if no_html then
res = network_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,42 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local network_alert_store = require "network_alert_store".new()
local auth = require "auth"
--
-- Read alerts count by time
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/network/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local ifid = _GET["ifid"]
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
interface.select(ifid)
local res = network_alert_store:count_by_severity_and_time_request()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local local_network_pools = require "local_network_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(local_network_pools)

View file

@ -0,0 +1,59 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require("dkjson")
local recording_utils = require "recording_utils"
local rest_utils = require("rest_utils")
--
-- Run a traffic extraction
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1", "epoch_begin": 1589822000, "epoch_end": 15898221000 }' http://localhost:3000/lua/rest/v2/get/pcap/live_extraction.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local ifid = tonumber(_GET["ifid"])
local filter = _GET["bpf_filter"]
local time_from = tonumber(_GET["epoch_begin"])
local time_to = tonumber(_GET["epoch_end"])
local rc = rest_utils.consts.success.ok
if not recording_utils.isExtractionAvailable() then
rc = rest_utils.consts.err.not_granted
rest_utils.answer(rc)
return
end
if isEmptyString(ifid) then
rc = rest_utils.consts.err.invalid_interface
rest_utils.answer(rc)
return
end
if _GET["epoch_begin"] == nil or _GET["epoch_end"] == nil then
rc = rest_utils.consts.err.invalid_arguments
rest_utils.answer(rc)
return
end
interface.select(ifid)
if filter == nil then
filter = ""
end
local timeline_path
if recording_utils.getCurrentTrafficRecordingProvider(ifid) ~= "ntopng" then
timeline_path = recording_utils.getCurrentTrafficRecordingProviderTimelinePath(ifid)
end
local fname = time_from.."-"..time_to..".pcap"
sendHTTPContentTypeHeader('application/vnd.tcpdump.pcap', 'attachment; filename="'..fname..'"')
ntop.runLiveExtraction(ifid, time_from, time_to, filter, timeline_path)

View file

@ -0,0 +1,48 @@
--
-- (C) 2019-21 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local info = ntop.getInfo()
local json = require ("dkjson")
local page_utils = require("page_utils")
local format_utils = require("format_utils")
local os_utils = require "os_utils"
local host_pools_nedge = require "host_pools_nedge"
local rest_utils = require("rest_utils")
--
-- Read host pools configuration
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/pool/config.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local ifid = _GET["ifid"]
local download = _GET["download"]
if not isAdministratorOrPrintErr() then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
if isEmptyString(ifid) then
rest_utils.answer(rest_utils.consts.err.invalid_interface)
return
end
local res = host_pools_nedge.export()
if isEmptyString(download) then
rest_utils.answer(rc, res)
else
sendHTTPContentTypeHeader('application/json', 'attachment; filename="pools_configuration.json"')
print(json.encode(res, nil))
end

View file

@ -0,0 +1,11 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_all_instances_pools()

View file

@ -0,0 +1,10 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_all_instances_pools_by_recipient(tonumber(_GET["recipient_id"]))

View file

@ -0,0 +1,54 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local format_utils = require "format_utils"
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local system_alert_store = require "system_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/system/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
interface.select(getSystemInterfaceId())
-- Fetch the results
local alerts, recordsFiltered = system_alert_store:select_request()
for _key,_value in ipairs(alerts or {}) do
local record = system_alert_store:format_record(_value, no_html)
res[#res + 1] = record
end -- for
if no_html then
res = system_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,34 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local system_alert_store = require "system_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/system/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
interface.select(getSystemInterfaceId())
local res = system_alert_store:count_by_severity_and_time_request()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,12 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path
local system_pools = require "system_pools"
local pools_rest_utils = require "pools_rest_utils"
pools_rest_utils.get_pools(system_pools)

View file

@ -0,0 +1,34 @@
--
-- (C) 2013-21 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local page_utils = require("page_utils")
local tracker = require("tracker")
local storage_utils = require("storage_utils")
local cpu_utils = require("cpu_utils")
local rest_utils = require("rest_utils")
--
-- Read system statistics
-- Example: curl -u admin:admin -H "Content-Type: application/json" http://localhost:3000/lua/rest/v2/get/system/stats.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
if not isAllowedSystemInterface() then
rc = rest_utils.consts.err.not_granted
rest_utils.answer(rc)
return
end
local rc = rest_utils.consts.success.ok
local res = cpu_utils.systemHostStats()
res.epoch = os.time()
res.storage = storage_utils.storageInfo()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,38 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local rest_utils = require("rest_utils")
local begin_epoch = tonumber(_GET["begin_epoch"])
local end_epoch = tonumber(_GET["end_epoch"])
local num_records = tonumber(_GET["totalRows"]) or 24
local curr = begin_epoch
local records = {}
-- 1 hour is 60*60=3600
local start = os.time()
for i = 1, num_records, 1 do
if (curr < end_epoch) then
records[#records+1] = {index = i, date = os.date("%c", curr)}
curr = curr + 3600
else
break
end
end
rest_utils.answer(rest_utils.consts.success.ok, {
time = os.time() - start,
records = records
})

View file

@ -0,0 +1,232 @@
--
-- (C) 2013-21 - ntop.org
--
--
-- Example of REST call
--
-- curl -u admin:admin -X POST -d '{"ts_schema":"host:traffic", "ts_query": "ifid:3,host:192.168.1.98", "epoch_begin": "1532180495", "epoch_end": "1548839346"}' -H "Content-Type: application/json" "http://127.0.0.1:3000/lua/rest/get/timeseries/ts.lua"
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local graph_common = require "graph_common"
local graph_utils = require "graph_utils"
local ts_utils = require("ts_utils")
local ts_common = require("ts_common")
local json = require("dkjson")
local rest_utils = require("rest_utils")
local ts_schema = _GET["ts_schema"]
local query = _GET["ts_query"]
local tstart = _GET["epoch_begin"]
local tend = _GET["epoch_end"]
local compare_backward = _GET["ts_compare"]
local tags = _GET["ts_query"]
local extended_times = _GET["extended"]
local ts_aggregation = _GET["ts_aggregation"]
local no_fill = tonumber(_GET["no_fill"])
-- Epochs in _GET are assumed to be adjusted to UTC. This is always the case when the browser submits epoch using a
-- datetimepicker (e.g., from any chart page).
-- This is what happens for example when drawing a chart from firefox set on three different timezones
-- TZ=UTC firefox. 12 May 2020 11:00:00 -> 1589281200 (sent by browser in _GET)
-- TZ=Europe/Rome. 12 May 2020 11:00:00 -> 1589274000 (sent by browser in _GET)
-- TZ=America/Sao_Paulo 12 May 2020 11:00:00 -> 1589292000 (sent by browser in _GET)
-- Basically, timestamps are adjusted to UTC before being sent in _GET:
-- - 1589274000 (Rome) - 1589281200 (UTC) = -7200: As Rome (CEST) is at +2 from UTC, then UTC is 2 hours ahead Rome
-- - 12 May 2020 11:00:00 in Rome (UTC) is 12 May 2020 09:00:00 UTC (-2)
-- - 1589292000 (Sao Paulo) - 1589281200 (UTC) = +10800: As Sao Paulo is at -3 from UTC, then UTC is 3 hours after UTC
-- - 12 May 2020 11:00:00 in Sao Paolo is 12 May 2020 14:00:00 UTC (+3)
-- As timeseries epochs are always written adjusted to UTC, there is no need to do any extra processing to the received epochs.
-- They are valid from any timezone, provided they are sent in the _GET as UTC adjusted.
tstart = tonumber(tstart) or (os.time() - 3600)
tend = tonumber(tend) or os.time()
tags = tsQueryToTags(tags)
if _GET["tskey"] then
-- This can contain a MAC address for local broadcast domain hosts
local tskey = _GET["tskey"]
-- Setting host_ip (check that the provided IP matches the provided
-- mac address as safety check and to avoid security issues)
if tags.host then
local host = hostkey2hostinfo(tags.host)
if not isEmptyString(host["host"]) then
local host_info = interface.getHostInfo(host["host"], host["vlan"])
local mac_info = split(tskey, "_")
if host_info.mac == mac_info[1] then
tags.host_ip = tags.host;
end
end
end
tags.host = tskey
end
local driver = ts_utils.getQueryDriver()
local options = {
max_num_points = tonumber(_GET["limit"]) or 60,
initial_point = toboolean(_GET["initial_point"]),
with_series = true,
target_aggregation = ts_aggregation,
}
if(no_fill == 1) then
options.fill_value = 0/0 -- NaN
end
-- Not necessary anymore as the influxdb driver:query method uses the
-- series last timestamp to avoid going in the future
--[[
-- Check end time bound and realign if necessary
local latest_tstamp = driver:getLatestTimestamp(tags.ifid or -1)
if (tend > latest_tstamp) and ((tend - latest_tstamp) <= ts_utils.MAX_EXPORT_TIME) then
local delta = tend - latest_tstamp
local alignment = (tend - tstart) / options.max_num_points
delta = delta + (alignment - delta % alignment)
tend = math.floor(tend - delta)
tstart = math.floor(tstart - delta)
end
]]
if tags.ifid then
interface.select(tags.ifid)
end
if((ts_schema == "top:flow_check:duration")
or (ts_schema == "top:elem_check:duration")
or (ts_schema == "custom:flow_check:total_stats")
or (ts_schema == "custom:elem_check:total_stats")) then
-- NOTE: Temporary fix for top checks page
tags.check = nil
end
local function performQuery(tstart, tend, keep_total, additional_options)
local res
additional_options = additional_options or {}
local options = table.merge(options, additional_options)
if starts(ts_schema, "top:") then
local ts_schema = split(ts_schema, "top:")[2]
res = ts_utils.queryTopk(ts_schema, tags, tstart, tend, options)
else
res = ts_utils.query(ts_schema, tags, tstart, tend, options)
if(not keep_total) and (res) and (res.additional_series) then
-- no need for total serie in normal queries
res.additional_series.total = nil
end
end
return res
end
local res
if(ntop.getPref("ntopng.prefs.ndpi_flows_rrd_creation") == "1") then
if(ts_schema == "host:ndpi") then
ts_schema = "custom:host_ndpi_and_flows"
elseif(ts_schema == "iface:ndpi") then
ts_schema = "custom:iface_ndpi_and_flows"
end
end
if starts(ts_schema, "custom:") and graph_utils.performCustomQuery then
res = graph_utils.performCustomQuery(ts_schema, tags, tstart, tend, options)
compare_backward = nil
else
res = performQuery(tstart, tend)
end
if res == nil then
res = {}
if(ts_utils.getLastError() ~= nil) then
res["tsLastError"] = ts_utils.getLastError()
res["error"] = ts_utils.getLastErrorMessage()
rest_utils.answer(rest_utils.consts.err.internal_error, res)
else
rest_utils.answer(rest_utils.consts.success.ok, res)
end
return
end
-- Add metadata
res.schema = ts_schema
res.query = tags
res.max_points = options.max_num_points
if not isEmptyString(compare_backward) and compare_backward ~= "1Y" and (res.step ~= nil) then
local backward_sec = graph_common.getZoomDuration(compare_backward)
local tstart_cmp = res.start - backward_sec
local tend_cmp = tstart_cmp + res.step * (res.count - 1)
-- Try to use the same aggregation as the original query
local res_cmp = performQuery(tstart_cmp, tend_cmp, true, {target_aggregation=res.source_aggregation})
local total_cmp_serie = nil
if res_cmp and res_cmp.additional_series and res_cmp.additional_series.total and (res_cmp.step) and res_cmp.step >= res.step then
total_cmp_serie = res_cmp.additional_series.total
if res_cmp.step > res.step then
-- The steps may not still correspond if the past query overlaps a retention policy
-- bound (it will have less points, but with an higher step), upscale to solve this
total_cmp_serie = ts_common.upsampleSerie(total_cmp_serie, res.count)
end
end
if total_cmp_serie then
res.additional_series = res.additional_series or {}
res.additional_series[compare_backward.. " " ..i18n("details.ago")] = total_cmp_serie
end
end
-- TODO make a script parameter?
local extend_labels = true
if extend_labels and graph_utils.extendLabels then
graph_utils.extendLabels(res)
end
-- Add layout information
local layout = graph_utils.get_timeseries_layout(ts_schema)
for _, serie in pairs(res.series) do
if not serie.type then
if layout[serie.label] then
serie.type = layout[serie.label]
end
end
end
if extended_times then
if res.series and res.step then
for k, serie in pairs(res.series) do
serie.data = ts_common.serieWithTimestamp(serie.data, tstart, res.step)
end
end
if res.additional_series and res.step then
for k, serie in pairs(res.additional_series) do
res.additional_series[k] = ts_common.serieWithTimestamp(serie, tstart, res.step)
end
end
end
rest_utils.answer(rest_utils.consts.success.ok, res)

View file

@ -0,0 +1,50 @@
--
-- (C) 2021-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local rest_utils = require("rest_utils")
local user_alert_store = require "user_alert_store".new()
local auth = require "auth"
--
-- Read alerts data
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/user/alert/list.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
local res = {}
local format = _GET["format"] or "json"
local no_html = (format == "txt")
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
interface.select(getSystemInterfaceId())
-- Fetch the results
local alerts, recordsFiltered = user_alert_store:select_request()
for _key,_value in ipairs(alerts or {}) do
local record = user_alert_store:format_record(_value, no_html)
res[#res + 1] = record
end -- for
if no_html then
res = user_alert_store:to_csv(res)
rest_utils.vanilla_payload_response(rc, res, "text/csv")
else
rest_utils.extended_answer(rc, {records = res}, {
["draw"] = tonumber(_GET["draw"]),
["recordsFiltered"] = recordsFiltered,
["recordsTotal"] = #res
}, format)
end

View file

@ -0,0 +1,34 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/alert_store/?.lua;" .. package.path
local alert_utils = require "alert_utils"
local alert_consts = require "alert_consts"
local alert_entities = require "alert_entities"
local rest_utils = require("rest_utils")
local user_alert_store = require "user_alert_store".new()
local auth = require "auth"
--
-- Read alerts count by time
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/user/alert/ts.lua
--
-- NOTE: in case of invalid login, no error is returned but redirected to login
--
local rc = rest_utils.consts.success.ok
if not auth.has_capability(auth.capabilities.alerts) then
rest_utils.answer(rest_utils.consts.err.not_granted)
return
end
interface.select(getSystemInterfaceId())
local res = user_alert_store:count_by_severity_and_time_request()
rest_utils.answer(rc, res)

View file

@ -0,0 +1,11 @@
--
-- (C) 2013-21 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/datasources/?.lua;" .. package.path
local widgets_utils = require "widgets_utils"
widgets_utils.rest_response()