EVOLUTION-MANAGER
Edit File: hosts_stats.lua
-- -- (C) 2013-24 - 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 package.path = dirs.installdir .. "/scripts/lua/modules/vulnerability_scan/?.lua;" .. package.path require "lua_utils_generic" require "check_redis_prefs" local vs_utils = require "vs_utils" local host_pools_nedge if ntop.isnEdge() then host_pools_nedge = require "host_pools_nedge" end local host_pools = require "host_pools" -- Instantiate host pools local host_pools_instance = host_pools:create() local page_utils = require("page_utils") local custom_column_utils = require("custom_column_utils") local discover = require("discover_utils") local template_utils = require("template_utils") local inactive_hosts_utils = require("inactive_hosts_utils") local have_nedge = ntop.isnEdge() local wheel = nil local function generate_map_url(map, map_type, query, icon) local url = "" if (ntop.isPro()) then local map_available = table.len(map) > 0 if (map_available) then url = "<a class='ms-1' href='" .. ntop.getHttpPrefix() .. "/lua/pro/enterprise/network_maps.lua?" .. query .. "&map=" .. map_type .. "'><i class='" .. icon .. "'></i></a>" end end return url end sendHTTPContentTypeHeader('text/html') page_utils.print_header_and_set_active_menu_entry(page_utils.menu_entries.hosts) local protocol = _GET["protocol"] local asn = _GET["asn"] local vlan = _GET["vlan"] local network = _GET["network"] local cidr = _GET["network_cidr"] local country = _GET["country"] local mac = _GET["mac"] local os_ = _GET["os"] local community = _GET["community"] local pool = _GET["pool"] local ipversion = _GET["version"] local traffic_type = _GET["traffic_type"] local device_ip = _GET["deviceIP"] local page = _GET["page"] or 'active_hosts' local base_url = ntop.getHttpPrefix() .. "/lua/hosts_stats.lua" local page_params = {} local charts_icon = "" local mode = _GET["mode"] if isEmptyString(mode) then mode = "all" else page_params["mode"] = mode end local hosts_filter = '' if ((mode ~= "all") or (not isEmptyString(pool))) then hosts_filter = '<span class="fas fa-filter"></span>' end function getPageTitle(protocol_name, traffic_type_title, device_ip_title, network_name, cidr, ipver_title, os_, country, asninfo, mac, pool_, vlan_title, vlan_alias) local mode_label = "" if mode == "remote" then mode_label = i18n("hosts_stats.remote") elseif mode == "remote_no_tx" then mode_label = i18n("hosts_stats.remote_no_tx") elseif mode == "remote_no_tcp_tx" then mode_label = i18n("hosts_stats.remote_no_tcp_tx") elseif mode == "local" then mode_label = i18n("hosts_stats.local") elseif mode == "local_no_tx" then mode_label = i18n("hosts_stats.local_no_tx") elseif mode == "local_no_tcp_tx" then mode_label = i18n("hosts_stats.local_no_tcp_tx") elseif mode == "filtered" then mode_label = i18n("hosts_stats.filtered") elseif mode == "blacklisted" then mode_label = i18n("hosts_stats.blacklisted") elseif mode == "dhcp" then mode_label = i18n("nedge.network_conf_dhcp") elseif mode == "broadcast_multicast" then mode_label = i18n("hosts_stats.broadcast_and_multicast") end if (network == nil) then wheel = "" charts_icon = "" else wheel = '<A HREF="' .. ntop.getHttpPrefix() .. '/lua/network_details.lua?network=' .. network .. '&page=config' .. '"><i class="fas fa-cog fa-sm"></i></A>' charts_icon = charts_icon .. " <a href='" .. ntop.getHttpPrefix() .. "/lua/network_details.lua?network=" .. network .. "&page=historical'><i class='fas fa-sm fa-chart-area'></i></a>" end -- Note: we must use the empty string as fallback. Multiple spaces will be collapsed into one automatically. return i18n("hosts_stats.hosts_page_title", { all = isEmptyString(mode_label) and i18n("hosts_stats.all") or "", traffic_type = traffic_type_title or "", device_ip = device_ip_title or "", local_remote = mode_label, protocol = protocol_name or "", network = not isEmptyString(network_name) and i18n("hosts_stats.in_network", { network = network_name }) or "", network_cidr = not isEmptyString(cidr) and i18n("hosts_stats.in_network", { network = cidr }) or "", ip_version = ipver_title or "", ["os"] = discover.getOsName(os_), country_asn_or_mac = country or asninfo or mac or pool_ or "", vlan = vlan_title or "", vlan_name = vlan_alias or "", charts_icon = charts_icon, wheel = wheel }) end dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") local ifstats = interface.getStats() -- Parameters necessary for the page title local protocol_name = nil local network_name = nil local traffic_type_title = nil local device_ip_title = nil local ipver_title = nil local asninfo = nil local os_title = nil local country_title = nil local mac_title = nil local vlan_title = nil local pool_title = nil local vlan_alias = nil if ((protocol ~= nil) and (protocol ~= "")) then protocol_name = interface.getnDPIProtoName(tonumber(protocol)) end if (protocol_name == nil) then protocol_name = protocol end if not isEmptyString(traffic_type) then page_params["traffic_type"] = traffic_type if traffic_type == "one_way" then traffic_type_title = i18n("hosts_stats.traffic_type_one_way") elseif traffic_type == "bidirectional" then traffic_type_title = i18n("hosts_stats.traffic_type_two_ways") end else traffic_type_title = "" end if not isEmptyString(device_ip) then page_params["deviceIP"] = device_ip device_ip_title = i18n("hosts_stats.probe_traffic", { device_ip = device_ip }) end if (tonumber(network) ~= nil) then network_name = getLocalNetworkAlias(tonumber(network)) if isEmptyString(network_name) then network_name = i18n("hosts_stats.remote") end else network_name = "" end if not isEmptyString(ipversion) then ipver_title = i18n("hosts_stats.ipver_title", { version_num = ipversion }) else ipver_title = "" end if (asn ~= nil) then asninfo = " " .. i18n("hosts_stats.asn_title", { asn = asn }) .. "<small> <i class='fas fa-info-circle fa-sm' aria-hidden='true'></i> <A class='ntopng-external-link' href='https://stat.ripe.net/AS" .. asn .. "'><i class='fas fa-external-link-alt fa-sm' title=\\\"" .. i18n("hosts_stats.more_info_about_as_popup_msg") .. "\\\"></i></A> " .. charts_icon .. " <a href='" .. ntop.getHttpPrefix() .. "/lua/as_details.lua?asn=" .. asn .. "&page=historical'><i class='fas fa-sm fa-chart-area'></i></a> </small>" end if (os_ ~= nil) then os_title = " " .. os_ end if (country ~= nil and country ~= '') then country_title = " " .. i18n("hosts_stats.country_title", { country = country }) end if (mac ~= nil and mac ~= '') then mac_title = " " .. i18n("hosts_stats.mac_title", { mac = mac }) end if (vlan ~= nil and vlan ~= '') then local link_service_map = generate_map_url(interface.serviceMap(nil, tonumber(vlan)), "service_map", "vlan=" .. vlan, "fas fa-concierge-bell") local link_periodicity_map = generate_map_url(interface.periodicityMap(nil, tonumber(vlan)), "periodicity_map", "vlan=" .. vlan, "fas fa-clock") local vlan_label = i18n('untagged') if (vlan ~= 0 and vlan ~= '0') then vlan_label = i18n("hosts_stats.vlan_title", { vlan = vlan }) end vlan_title = " [" .. vlan_label .. "]" local config_button = " <A HREF='" .. ntop.getHttpPrefix() .. "/lua/vlan_details.lua?vlan=" .. vlan .. "&page=config" .. "'><i class='fas fa-cog fa-sm'></i></A>" -- in case of untagged traffic is not possible to set a vlan alias if (vlan ~= 0 and vlan ~= '0') then vlan_title = vlan_title .. config_button end vlan_title = vlan_title .. " " .. link_service_map .. " " .. link_periodicity_map if (vlan == getVlanAlias(vlan)) then vlan_alias = "" else vlan_alias = getVlanAlias(vlan) end end if (pool ~= nil and pool ~= '') then local link_service_map = "" local link_periodicity_map = "" local charts_available = areHostPoolsTimeseriesEnabled(ifstats.id) if (tonumber(pool) ~= host_pools_instance.DEFAULT_POOL_ID) then link_service_map = generate_map_url(interface.serviceMap(nil, nil, tonumber(pool)), "service_map", "host_pool_id=" .. pool, "fas fa-concierge-bell") link_periodicity_map = generate_map_url(interface.periodicityMap(nil, nil, tonumber(pool)), "periodicity_map", "host_pool_id=" .. pool, "fas fa-clock") end local pool_edit = "" local pool_link local title if (tonumber(pool) ~= host_pools_instance.DEFAULT_POOL_ID) or (have_nedge) then if have_nedge then pool_link = "/lua/pro/nedge/admin/nf_edit_user.lua?username=" .. ternary(tonumber(pool) == host_pools_nedge.DEFAULT_POOL_ID, "", host_pools_nedge.poolIdToUsername(pool)) title = i18n("nedge.edit_user") else pool_link = "/lua/admin/manage_host_members.lua?pool=" .. pool title = i18n("host_pools.manage_pools") end pool_edit = " <A HREF='" .. ntop.getHttpPrefix() .. pool_link .. "'><i class='fas fa-cog fa-sm' title='" .. title .. "'></i></A>" end pool_title = " " .. i18n(ternary(have_nedge, "hosts_stats.user_title", "hosts_stats.pool_title"), { poolname = host_pools_instance:get_pool_name(pool) }) .. "<small>" .. pool_edit .. ternary(charts_available, " <a href='" .. ntop.getHttpPrefix() .. "/lua/pool_details.lua?page=historical&pool=" .. pool .. "'><i class='fas fa-chart-area fa-sm' title='" .. i18n("chart") .. "'></i></a>", "") .. link_service_map .. link_periodicity_map .. "</small>" end page_utils.print_navbar(i18n("hosts"), base_url .. "?", {{ active = page == "active_hosts" or page == nil, page_name = "active_hosts", label = i18n('active_hosts') }, { active = page == "inactive_hosts" or page == nil, hidden = inactive_hosts_utils.getInactiveHostsNumber(ifstats.id) == 0, page_name = "inactive_hosts", label = i18n('inactive_hosts_navbar') .. '<span class="badge rounded-pill bg-dark" style="float: right; margin-top: -8px;">' .. inactive_hosts_utils.getInactiveHostsNumber(ifstats.id) .. '</span>' }}) if page == 'active_hosts' and ntop.isnEdge() then page_utils.print_page_title(getPageTitle(protocol_name, traffic_type_title, device_ip_title, network_name, cidr, ipver_title, os_title, country_title, asninfo, mac_title, pool_title, vlan_title, vlan_alias)) if (_GET["page"] ~= "historical") then if (asn ~= nil) then print [[ <div class='card'><div class='card-header'> <ul class="nav nav-tabs card-header-tabs"> <li class="nav-item" class="active"><a class="nav-link active" data-bs-toggle="tab" href="#home">]] print(i18n("hosts_stats.hosts")) print [[</a></li> ]] if (asn ~= "0") then print [[ <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#asinfo">]] print(i18n("hosts_stats.as_info")) print [[</a></li> <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#aspath">]] print(i18n("hosts_stats.as_path")) print [[</a></li> <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#prefix">]] print(i18n("hosts_stats.as_prefixes")) print [[</a></li> <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#bgp">]] print(i18n("hosts_stats.bgp_updates")) print [[</a></li> ]] end end print("</ul>") -- close .card-header if (asn ~= nil) then print("</div>") end if (asn ~= nil) then print [[ <div class='card-body'> <div class="tab-content"> <div id="home" class="tab-pane in active"> ]] end -- build the current filter url page_params["os"] = os_ page_params["asn"] = asn page_params["community"] = community page_params["vlan"] = vlan page_params["country"] = country page_params["mac"] = mac page_params["pool"] = pool page_params["network_cidr"] = cidr if (protocol ~= nil) then -- Example HTTP.Facebook dot = string.find(protocol, '%.') if (dot ~= nil) then protocol = string.sub(protocol, dot + 1) end page_params["protocol"] = protocol end if (network ~= nil) then page_params["network"] = network local network_key = ntop.getNetworkNameById(tonumber(network)) if not isEmptyString(network_name) then local charts_available = areInterfaceTimeseriesEnabled(ifstats.id) charts_icon = " <small><a href='" .. ntop.getHttpPrefix() .. "/lua/network_details.lua?network=" .. network .. "&page=config'><i class='fas fa-sm fa-cog'></i></a>" if charts_available then charts_icon = charts_icon .. " <a href='" .. ntop.getHttpPrefix() .. "/lua/network_details.lua?network=" .. network .. "&page=historical'><i class='fas fa-sm fa-chart-area'></i></a>" end charts_icon = charts_icon .. "</small>" end end if not isEmptyString(ipversion) then page_params["version"] = ipversion end custom_column_utils.updateCustomColumn() local custom_name, custom_key, custom_align = custom_column_utils.getCustomColumnName() print [[ <div id="table-hosts"></div> <script> var url_update = "]] print(getPageUrl(ntop.getHttpPrefix() .. "/lua/get_hosts_data.lua", page_params)) print [[";]] ntop.dumpFile(dirs.installdir .. "/httpdocs/inc/hosts_stats_id.inc") if ((ifstats.vlan)) then show_vlan = true else show_vlan = false end if (show_vlan) then print('host_rows_option["vlan"] = true;\n') end if ((custom_key == "") or (custom_key == nil)) then custom_key = "score" end print [[ host_rows_option["ip"] = true; host_rows_option["custom_column"] = "]] print(custom_key) print [["; $("#table-hosts").datatable({ title: "]] print(i18n("hosts_stats.hosts_list")) print [[", url: url_update , ]] if (protocol == nil) then protocol = "" end if not isEmptyString(protocol_name) then charts_icon = " <a href='" .. ntop.getHttpPrefix() .. "/lua/if_stats.lua?ifid=" .. ifstats.id .. "&page=historical&ts_schema=iface:ndpi&protocol=" .. protocol_name .. "'><i class='fas fa-sm fa-chart-area'></i></a>" end print('title: "",\n') print('rowCallback: function ( row ) { return host_table_setID(row); },') print [[ tableCallback: function() { $("#dt-bottom-details > .float-left > p").first().append('. ]] print(i18n('hosts_stats.idle_hosts_not_listed')) print [['); }, ]] -- Set the preference table preference = tablePreferences("rows_number", _GET["perPage"]) if (preference ~= "") then print('perPage: ' .. preference .. ",\n") end -- Automatic default sorted. NB: the column must exist. print('sort: [ ["' .. getDefaultTableSort("hosts") .. '","' .. getDefaultTableSortOrder("hosts") .. '"] ],') print [[ showPagination: true, ]] print('buttons: [ ') -- IP version selector print [['<div class="btn-group float-right">]] custom_column_utils.printCustomColumnDropdown(base_url, page_params) print [[</div>']] -- IP version selector print [[, '<div class="btn-group float-right">]] printIpVersionDropdown(base_url, page_params) print [[</div>']] -- VLAN selector if ifstats.vlan then print [[, '<div class="btn-group float-right">]] printVLANFilterDropdown(base_url, page_params) print [[</div>']] end print [[, '<div class="btn-group float-right">]] printTrafficTypeFilterDropdown(base_url, page_params) print [[</div>']] -- Hosts filter -- table.clone needed to modify some parameters while keeping the original unchanged local hosts_filter_params = table.clone(page_params) print(', \'<div class="btn-group"><button class="btn btn-link dropdown-toggle" data-bs-toggle="dropdown">' .. i18n("hosts_stats.filter_hosts") .. hosts_filter .. '<span class="caret"></span></button> <ul class="dropdown-menu scrollable-dropdown" role="menu" style="min-width: 90px;"><li"><a class="dropdown-item" href="') hosts_filter_params.mode = nil hosts_filter_params.pool = nil print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.all_hosts") .. '</a></li>') hosts_filter_params.mode = "blacklisted" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "blacklisted", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.blacklisted_hosts_only") .. '</a></li>') if interface.isPacketInterface() and not interface.isPcapDumpInterface() then hosts_filter_params.mode = "broadcast_domain" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "broadcast_domain", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.broadcast_domain_hosts_only") .. '</a></li>') end hosts_filter_params.mode = "broadcast_multicast" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "broadcast_multicast", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.broadcast_and_multicast") .. '</a></li>') if interface.isPacketInterface() and not interface.isPcapDumpInterface() then hosts_filter_params.mode = "dhcp" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "dhcp", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("mac_stats.dhcp_only") .. '</a></li>') end -- Host pools if (not ifstats.isView) then hosts_filter_params.mode = nil hosts_filter_params.pool = nil local pools = host_pools_instance:get_all_pools() if (table.len(pools) > 2) then -- Not only the default and jailed (host pools or nEdge users) print('<li role="separator" class="divider"></li>') for _, _pool in ipairs(pools) do hosts_filter_params.pool = _pool.pool_id print('<li ') print('"><a class="dropdown-item ' .. ternary((tonumber(pool) == _pool.pool_id), 'active', '') .. '" href="') print(getPageUrl(base_url, hosts_filter_params) .. '">' .. i18n(ternary(have_nedge, "hosts_stats.user", "hosts_stats.host_pool"), { pool_name = string.gsub(_pool.name, "'", "\\'") }) .. '</li>') end hosts_filter_params.pool = nil end end hosts_filter_params.mode = "local" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "local", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.local_hosts_only") .. '</a></li>') hosts_filter_params.mode = "local_no_tx" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "local_no_tx", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.local_no_tx") .. '</a></li>') hosts_filter_params.mode = "local_no_tcp_tx" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "local_no_tcp_tx", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.local_no_tcp_tx") .. '</a></li>') hosts_filter_params.mode = "remote" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "remote", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.remote_hosts_only") .. '</a></li>') hosts_filter_params.mode = "remote_no_tx" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "remote_no_tx", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.remote_no_tx") .. '</a></li>') hosts_filter_params.mode = "remote_no_tcp_tx" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "remote_no_tcp_tx", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.remote_no_tcp_tx") .. '</a></li>') if isBridgeInterface(ifstats) then hosts_filter_params.mode = "filtered" print('<li ') print('"><a class="dropdown-item ' .. ternary(mode == "filtered", "active", "") .. '" href="') print(getPageUrl(base_url, hosts_filter_params)) print('">' .. i18n("hosts_stats.filtered_hosts_only") .. '</a></li>') end print('</ul></div>\'') local alignment_c_info = 'center' if (ntop.isnEdge()) then alignment_c_info = 'nowrap' end print(' ],') print [[ columns: [ { title: "Key", field: "key", hidden: true, css: { textAlign: 'center' } },{ title: "", field: "column_info", sortable: false, css: { textAlign: ']]print(alignment_c_info)print[[', whiteSpace: 'nowrap' } },{ title: "]] print(i18n("ip_address")) print [[", field: "column_ip", sortable: true, css: { textAlign: 'left' } }, ]] if (show_vlan) then print('{ title: "' .. i18n("vlan") .. '",\n') print [[ field: "column_vlan", sortable: true, css: { textAlign: 'center' } }, ]] end print [[ { title: "]] print(i18n("flows")) print [[", field: "column_num_flows", sortable: true, css: { textAlign: 'center' } }, { title: "]] print(i18n("hosts_stats.page_scan_hosts.title_hosts_page") ) print [[", field: "column_num_vulnerabilities", sortable: false, css: { textAlign: 'center' }, hidden: ]] local scan_modules = vs_utils.list_scan_modules() print(#scan_modules == 0) print [[ }, { title: "]] print(i18n("if_stats_overview.blocked_flows")) print [[", field: "column_num_dropped_flows", sortable: true, hidden: ]] if isBridgeInterface(ifstats) then print("false") else print("true") end print [[, css: { textAlign: 'center' } }, { title: "]] -- tprint({custom_name = custom_name, custom_key = custom_key, custom_align = custom_align}) print(custom_name) print [[", field: "column_]] print(custom_key) print [[", sortable: true, css: { textAlign: ']] print(custom_align) print [[' } }, { title: "]] print(i18n("name")) print [[", field: "column_name", sortable: true, css: { textAlign: 'left' } }, { title: "]] print(i18n("seen_since")) print [[", field: "column_since", sortable: true, css: { textAlign: 'center' } }, { title: "]] print(i18n("score")) print [[", field: "column_score", sortable: true, css: { textAlign: 'center' } }, { title: "]] print(i18n("breakdown")) print [[", field: "column_breakdown", sortable: false, css: { textAlign: 'center' } }, { title: "]] print(i18n("throughput")) print [[", field: "column_thpt", sortable: true, css: { textAlign: 'right' } }, { title: "]] print(i18n("flows_page.total_bytes")) print [[", field: "column_traffic", sortable: true, css: { textAlign: 'right' } } ] }); </script> ]] if (have_nedge) then print [[ <script> const block_host_csrf = "]] print(ntop.getRandomCSRFValue()) print [["; function block_host(host_key, host_url) { var url = "]] print(ntop.getHttpPrefix()) print [[/lua/pro/nedge/toggle_block_host.lua?" + host_url; $.ajax({ type: 'GET', url: url, cache: false, data: { csrf: block_host_csrf }, success: function(content) { var data = jQuery.parseJSON(content); if (data.status == "BLOCKED") { $('#'+host_key+'_info').find('.block-badge') .removeClass('btn-secondary').addClass('btn-danger'); $('#'+host_key+'_ip').find('a').css("text-decoration", "line-through"); } else if (data.status == "UNBLOCKED") { $('#'+host_key+'_info').find('.block-badge') .removeClass('btn-danger').addClass('btn-secondary'); $('#'+host_key+'_ip').find('a').css("text-decoration", "none"); } }, error: function(content) { console.log("error"); } }); } </script> ]] end if (asn ~= nil) then print [[ </div> <script> let STAT_WIDGET_API_URL = 'https://stat.ripe.net/widgets/'; let STAT_DATA_API_URL = 'https://stat.ripe.net/data/'; let STAT_OTHER_API_URL = 'https://stat.ripe.net/api/'; let STAT_HOME = "https://stat.ripe.net/"; // DOM class for auto linking to div element let STAT_DOM_CLASS_NAME = 'statwdgtauto'; // how many seconds to wait for scripts to load // 0 ... disables the timeout let STAT_REQUIRE_TIMEOUT = 120; </script> <script src="https://stat.ripe.net/widget-api-config"></script> <script src="https://stat.ripe.net/widgets/js/version.js"></script> <script src="https://stat.ripe.net/widgets/js/widget_api_main.js"></script> <div id="asinfo" class="tab-pane"></div> <div id="aspath" class="tab-pane"></div> <div id="prefix" class="tab-pane"></div> <div id="bgp" class="tab-pane"></div> ]] if (asn ~= nil) then print("</div>") print("</div>") print("</div>") end print [[ <script> $(document).ready(function() { var tab_id_to_widget = { "#asinfo": "iana-registry-info", "#aspath": "as-path-length", "#prefix": "announced-prefixes", "#bgp": "bgp-update-activity", }; var loaded_widgets = {}; function load_widget(tab_id) { var widget = tab_id_to_widget[tab_id]; if((typeof(widget) === "undefined") || loaded_widgets[widget]) return; var tab = $(tab_id); var script = $("<script>") var div = $('<div class="statwdgtauto"></div>'); script.text('ripestat.init("' + widget + '",{"resource":"AS]] print(asn) print [["},null,{"disable":["controls"]});'); script.appendTo(div); div.appendTo(tab); loaded_widgets[widget] = true; } $('a[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) { var target = $(e.target).attr("href") // activated tab load_widget(target); }); }); </script> ]] end -- if(asn ~= nil) end elseif page == "active_hosts" then local json = require "dkjson" local vlans = interface.getVLANsList() local json_context = json.encode({ ifid = ifstats.id, has_vlans = (vlans ~= nil), csrf = ntop.getRandomCSRFValue() }) template_utils.render("pages/vue_page.template", { vue_page_name = "PageHostsList", page_context = json_context }) elseif page == "inactive_hosts" then template_utils.render("pages/inactive_hosts.template", { ifid = ifstats.id, csrf = ntop.getRandomCSRFValue(), show_historical = ntop.isEnterpriseM() and hasClickHouseSupport() }) end dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")