-- -- (C) 2013-17 - ntop.org -- dirs = ntop.getDirs() package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path if((dirs.scriptdir ~= nil) and (dirs.scriptdir ~= "")) then package.path = dirs.scriptdir .. "/lua/modules/?.lua;" .. package.path end if ntop.isPro() then package.path = dirs.installdir .. "/scripts/lua/pro/modules/?.lua;" .. package.path package.path = dirs.installdir .. "/pro/scripts/callbacks/?.lua;" .. package.path require "common" end local json = require "dkjson" local host_pools_utils = require "host_pools_utils" local template = require "template_utils" require "lua_utils" require "prefs_utils" require "graph_utils" require "alert_utils" require "db_utils" if ntop.isPro() then shaper_utils = require("shaper_utils") end sendHTTPHeader('text/html; charset=iso-8859-1') page = _GET["page"] ifid = _GET["ifid"] ifname_clean = "iface_"..tostring(ifid) msg = "" function inline_input_form(name, placeholder, tooltip, value, can_edit, input_opts, input_clss) print [[
]] print('\n') if(can_edit) then print('  ]] else if(value ~= nil) then print(value) end end print("
\n") end if(_POST["switch_interface"] ~= nil) then -- First switch interfaces so the new cookie will have effect ifname = interface.setActiveInterfaceId(tonumber(ifid)) --print("@"..ifname.."="..id.."@") if((ifname ~= nil) and (_SESSION["session"] ~= nil)) then key = getRedisPrefix("ntopng.prefs") .. ".ifname" ntop.setCache(key, ifname) msg = "
The selected interface " .. getHumanReadableInterfaceName(ifid) msg = msg .. " [ifid: ".. ifid .."] is now active
" ntop.setCache(getRedisPrefix("ntopng.prefs")..'.iface', ifid) else msg = "
Error while switching interfaces
" if(_SESSION["session"] == nil) then msg = msg .."
Empty session
" end end end -- parse interface names and possibly fall back to the selected interface: -- priority goes to the interface id if ifid ~= nil and ifid ~= "" then if_name = getInterfaceName(ifid) else -- fall-back to the default interface if_name = ifname ifid = interface.name2id(ifname) end interface.select(if_name) -- local pcap dump is disabled if the nbox integration is enabled or -- if the user is not an administrator or if the interface: -- is a view -- is not a packet interface (i.e., it is zmq) is_packetdump_enabled = isLocalPacketdumpEnabled() is_packet_interface = interface.isPacketInterface() ifstats = interface.getStats() -- this is a user-browseable page, so we must return counters from -- the latest reset as the user may have chosen to reset statistics at some point if ifstats.stats and ifstats.stats_since_reset then -- override stats with the values calculated from the latest user reset for k, v in pairs(ifstats.stats_since_reset) do ifstats.stats[k] = v end end if (isAdministrator()) then if(_POST["custom_name"] ~=nil) then -- TODO move keys to new schema: replace ifstats.name with ifid ntop.setCache('ntopng.prefs.'..ifstats.name..'.name',_POST["custom_name"]) end if(_POST["scaling_factor"] ~= nil) then local sf = tonumber(_POST["scaling_factor"]) if(sf == nil) then sf = 1 end ntop.setCache(getRedisIfacePrefix(ifid)..'.scaling_factor',tostring(sf)) interface.loadScalingFactorPrefs() end if is_packetdump_enabled then if(_POST["dump_all_traffic"] ~= nil) then page = "packetdump" ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_all_traffic',_POST["dump_all_traffic"]) end if(_POST["dump_traffic_to_tap"] ~= nil) then page = "packetdump" ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_tap',_POST["dump_traffic_to_tap"]) end if(_POST["dump_traffic_to_disk"] ~= nil) then page = "packetdump" ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_disk',_POST["dump_traffic_to_disk"]) end if(_POST["dump_unknown_to_disk"] ~= nil) then page = "packetdump" ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_unknown_disk',_POST["dump_unknown_to_disk"]) end if(_POST["dump_security_to_disk"] ~= nil) then page = "packetdump" ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_security_disk',_POST["dump_security_to_disk"]) end if(_POST["sampling_rate"] ~= nil) then if(tonumber(_POST["sampling_rate"]) ~= nil) then page = "packetdump" val = ternary(_POST["sampling_rate"] ~= "0", _POST["sampling_rate"], "1") ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_sampling_rate', val) end end if(_POST["max_pkts_file"] ~= nil) then if(tonumber(_POST["max_pkts_file"]) ~= nil) then page = "packetdump" ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_max_pkts_file',_POST["max_pkts_file"]) end end if(_POST["max_sec_file"] ~= nil) then if(tonumber(_POST["max_sec_file"]) ~= nil) then page = "packetdump" ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_max_sec_file',_POST["max_sec_file"]) end end if(_POST["max_files"] ~= nil) then if(tonumber(_POST["max_files"]) ~= nil) then page = "packetdump" local max_files_size = tonumber(_POST["max_files"]) max_files_size = max_files_size * 1000000 ntop.setCache('ntopng.prefs.'..ifstats.name..'.dump_max_files', tostring(max_files_size)) end end interface.loadDumpPrefs() end end ntop.dumpFile(dirs.installdir .. "/httpdocs/inc/header.inc") print("") active_page = "if_stats" dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") print(msg) rrdname = fixPath(dirs.workingdir .. "/" .. ifstats.id .. "/rrd/bytes.rrd") url = ntop.getHttpPrefix()..'/lua/if_stats.lua?ifid=' .. ifid -- Added global javascript variable, in order to disable the refresh of pie chart in case -- of historical interface print('\n\n') print [[ ]] if((page == "overview") or (page == nil)) then print("\n") print("\n") if interface.isPcapDumpInterface() == false then print("\n") end if(ifstats["remote.name"] ~= nil) then print("") if(ifstats["remote.if_addr"] ~= "") then print("") end if(ifstats["probe.ip"] ~= "") then print("") end if(ifstats["probe.public_ip"] ~= "") then print("\n") else print("\n") end print("\n") end local is_physical_iface = (interface.isPacketInterface()) and (interface.isPcapDumpInterface() == false) local is_bridge_iface = (ifstats["bridge.device_a"] ~= nil) and (ifstats["bridge.device_b"] ~= nil) if not is_bridge_iface then local label = getInterfaceNameAlias(ifstats.name) local s if ((not isEmptyString(label)) and (label ~= ifstats.name)) then s = label .. " (" .. ifstats.name .. ")" else s = ifstats.name end print('\n') else print("") end print("") if not is_bridge_iface then if(ifstats.ip_addresses ~= "") then tokens = split(ifstats.ip_addresses, ",") end if(tokens ~= nil) then print("") end end if is_physical_iface then print("") print("\n") if (not is_bridge_iface) then local speed_key = 'ntopng.prefs.'..ifname..'.speed' local speed = ntop.getCache(speed_key) if (tonumber(speed) == nil) then speed = ifstats.speed end print("") else print("") end print("") end if(ifstats["pkt_dumper"] ~= nil) then print("\n") print("") print("\n") end label = "Pkts" print[[ ]] if(ifstats.type ~= "zmq") then print [[ ]] else print [[ ]] end print [[ \n") if(ifstats.zmqRecvStats ~= nil) then print("\n") print("") print("") end print("\n") print("\n") if(prefs.is_dump_flows_enabled and ifstats.isView == false) then local dump_to = "MySQL" if prefs.is_dump_flows_to_es_enabled == true then dump_to = "ElasticSearch" end local export_count = ifstats.stats.flow_export_count local export_rate = ifstats.stats.flow_export_rate local export_drops = ifstats.stats.flow_export_drops local export_drops_pct = 0 if export_drops > 0 and export_count > 0 then export_drops_pct = export_drops / export_count * 100 end print("\n") print("") print("") print("") print("") local span_danger = "" if(export_drops > 0) then span_danger = ' class="label label-danger"' end print("") print("") print("") end if (isAdministrator() and ifstats.isView == false) then print("") print("") print("\n") end if((ifstats["bridge.device_a"] ~= nil) and (ifstats["bridge.device_b"] ~= nil)) then print("\n") print("\n") print("") print("") print("") print("") print("") print("\n") print("") print("") print("") print("") print("") print("\n") end print [[ ]] print("
Id" .. ifstats.id .. " ") print("
State") state = toggleTableButton("", "", "Active", "1","primary", "Paused", "0","primary", "toggle_local", "ntopng.prefs."..if_name.."_not_idle") if(state == "0") then on_state = true else on_state = false end interface.setInterfaceIdleState(on_state) print("
Remote ProbeInterface Name: "..ifstats["remote.name"].." [ ".. maxRateToString(ifstats.speed*1000) .." ]Interface IP: "..ifstats["remote.if_addr"].."Probe IP: "..ifstats["probe.ip"].."Public Probe IP: "..ifstats["probe.public_ip"].."  
Name' .. s ..'
Bridge"..ifstats["bridge.device_a"].." "..ifstats["bridge.device_b"].."Family") print(ifstats.type) if(ifstats.inline) then print(" In-Path Interface (Bump in the Wire)") end print("
IP Address") local addresses = {} for _,s in pairs(tokens) do t = string.split(s, "/") host = interface.getHostInfo(t[1]) if(host ~= nil) then addresses[#addresses+1] = "".. t[1].."" else addresses[#addresses+1] = t[1] end end print(table.concat(addresses, ", ")) print("
MTU"..ifstats.mtu.." bytesSpeed" .. maxRateToString(speed*1000) .. "
Packet DumperDumped PacketsDumped Files
".. formatValue(ifstats["pkt_dumper"]["num_dumped_pkts"]) .."
".. formatValue(ifstats["pkt_dumper"]["num_dumped_files"]) .."
Traffic Breakdown
ZMQ RX Statistics
Collected Flows"..formatValue(ifstats.zmqRecvStats.flows).."") print("Interface RX Updates"..formatValue(ifstats.zmqRecvStats.events).."") -- print("sFlow Counter Updates"..formatValue(ifstats.zmqRecvStats.counters).."
ZMQ Message Drops"..formatValue(ifstats.zmqRecvStats.zmq_msg_drops).."
Ingress Traffic
Received Traffic"..bytesToSize(ifstats.stats.bytes).." [".. formatValue(ifstats.stats.packets) .. " ".. label .."] ") print("Dropped Packets") if(ifstats.stats.drops > 0) then print('') end print(formatValue(ifstats.stats.drops).. " " .. label) if((ifstats.stats.packets+ifstats.stats.drops) > 0) then local pctg = round((ifstats.stats.drops*100)/(ifstats.stats.packets+ifstats.stats.drops), 2) if(pctg > 0) then print(" [ " .. pctg .. " % ] ") end end if(ifstats.stats.drops > 0) then print('') end print(" ") print("
"..dump_to.." Flows Export Statistics
Exported Flows"..formatValue(export_count).."") print(" ["..formatValue(round(export_rate, 2)).." Flows/s]Dropped Flows"..formatValue(export_drops).." ") print("[" ..formatValue(round(export_drops_pct, 2)).."%] 
Reset Counters") local cls = "" local tot = ifstats.stats.bytes + ifstats.stats.packets + ifstats.stats.drops if(ifstats.stats.flow_export_count ~= nil) then tot = tot + ifstats.stats.flow_export_count + ifstats.stats.flow_export_drops end if tot == 0 then cls = " disabled" end print(' ') cls = "" if(ifstats.stats.flow_export_count ~= nil) then if ifstats.stats.drops + ifstats.stats.flow_export_drops == 0 then cls = " disabled" end end print('') print("
Bridged Traffic
Interface DirectionIngress PacketsEgress PacketsShaped/Filtered PacketsSend ErrorBuffer Full
".. ifstats["bridge.device_a"] .. " ".. ifstats["bridge.device_b"] .."".. formatPackets(ifstats["bridge.a_to_b.in_pkts"]) .." ".. formatPackets(ifstats["bridge.a_to_b.out_pkts"]) .." ".. formatPackets(ifstats["bridge.a_to_b.filtered_pkts"]) .."".. formatPackets(ifstats["bridge.a_to_b.num_pkts_send_error"]) .."".. formatPackets(ifstats["bridge.a_to_b.num_pkts_send_buffer_full"]) .."
".. ifstats["bridge.device_b"] .. " ".. ifstats["bridge.device_a"] .."".. formatPackets(ifstats["bridge.b_to_a.in_pkts"]) .." "..formatPackets( ifstats["bridge.b_to_a.out_pkts"]) .." ".. formatPackets(ifstats["bridge.b_to_a.filtered_pkts"]) .."".. formatPackets(ifstats["bridge.b_to_a.num_pkts_send_error"]) .."".. formatPackets(ifstats["bridge.b_to_a.num_pkts_send_buffer_full"]) .."
NOTE:

In ethernet networks, each packet has an overhead of 24 bytes [preamble (7 bytes), start of frame (1 byte), CRC (4 bytes), and IFG (12 bytes)]. Such overhead needs to be accounted to the interface traffic, but it is not added to the traffic being exchanged between IP addresses. This is because such data contributes to interface load, but it cannot be accounted in the traffic being exchanged by hosts, and thus expect little discrepancies between host and interface traffic values.

\n") elseif((page == "packets")) then print [[ ]] print("\n") print("\n") print("\n") print [[
TCP Packets AnalysisRetransmissions".. formatPackets(ifstats.tcpPacketStats.retransmissions) .."
Out of Order".. formatPackets(ifstats.tcpPacketStats.out_of_order) .."
Lost".. formatPackets(ifstats.tcpPacketStats.lost) .."
Size Distribution

]] elseif(page == "ndpi") then --fc = interface.getnDPIFlowsCount() --for k,v in pairs(fc) do -- io.write(k.."="..v.."\n") --end print [[

Cumulative Protocol Stats
Live Flows Count

NOTE: This chart depicts only TCP connections.
]] print [[ ]] print("\n") print ('\n') print ("") print("
Application ProtocolTotal (Since Startup)Percentage
\n") print [[ ]] elseif(page == "historical") then rrd_file = _GET["rrd_file"] selected_epoch = _GET["epoch"] if(selected_epoch == nil) then selected_epoch = "" end topArray = makeTopStatsScriptsArray() if(rrd_file == nil) then rrd_file = "bytes.rrd" end drawRRD(ifstats.id, nil, rrd_file, _GET["zoom"], url.."&page=historical", 1, _GET["epoch"], selected_epoch, topArray) --drawRRD(ifstats.id, nil, rrd_file, _GET["zoom"], url.."&page=historical", 1, _GET["epoch"], selected_epoch, topArray, _GET["comparison_period"]) elseif(page == "trafficprofiles") then print("\n") print("\n") for pname,pbytes in pairs(ifstats.profiles) do local trimmed = trimSpace(pname) local rrdname = fixPath(dirs.workingdir .. "/" .. ifid .. "/profilestats/" .. getPathFromKey(trimmed) .. "/bytes.rrd") local statschart_icon = '' if ntop.exists(rrdname) then statschart_icon = '' end print("\n") end print [[
Profile NameChartTraffic
"..pname..""..statschart_icon..""..bytesToSize(pbytes).."
]] elseif(page == "packetdump") then if is_packetdump_enabled then dump_all_traffic = ntop.getCache('ntopng.prefs.'..ifstats.name..'.dump_all_traffic') dump_status_tap = ntop.getCache('ntopng.prefs.'..ifstats.name..'.dump_tap') dump_status_disk = ntop.getCache('ntopng.prefs.'..ifstats.name..'.dump_disk') dump_unknown_disk = ntop.getCache('ntopng.prefs.'..ifstats.name..'.dump_unknown_disk') dump_security_disk = ntop.getCache('ntopng.prefs.'..ifstats.name..'.dump_security_disk') if(dump_all_traffic == "true") then dump_all_traffic_checked = 'checked="checked"' dump_all_traffic_value = "false" -- Opposite else dump_all_traffic_checked = "" dump_all_traffic_value = "true" -- Opposite end if(dump_status_disk == "true") then dump_traffic_checked = 'checked="checked"' dump_traffic_value = "false" -- Opposite else dump_traffic_checked = "" dump_traffic_value = "true" -- Opposite end if(dump_unknown_disk == "true") then dump_unknown_checked = 'checked="checked"' dump_unknown_value = "false" -- Opposite else dump_unknown_checked = "" dump_unknown_value = "true" -- Opposite end if(dump_security_disk == "true") then dump_security_checked = 'checked="checked"' dump_security_value = "false" -- Opposite else dump_security_checked = "" dump_security_value = "true" -- Opposite end if(dump_status_tap == "true") then dump_traffic_tap_checked = 'checked="checked"' dump_traffic_tap_value = "false" -- Opposite else dump_traffic_tap_checked = "" dump_traffic_tap_value = "true" -- Opposite end print("\n") print("\n") print("\n") print("\n") print("\n") print("\n") print("\n") print [[ ]] print("") print("\n") print("\n") print [[ ]] print("\n") print [[ ]] print("\n") print [[ ]] print("
Packet Dump") print [[
]] print(' Dump All Traffic') print('') print('\n') print('
') print("
Packet Dump To Disk") print [[
]] print(' Dump Traffic To Disk') if(dump_traffic_checked ~= "") then dumped = interface.getInterfacePacketsDumpedFile() print(" - "..ternary(dumped, dumped, 0).." packets dumped") end print('') print('\n') print('
') print("
") print [[
]] print(' Dump Unknown Traffic To Disk ') print('\n') print('
') print("
") print [[
]] print(' Dump Traffic To Disk On Security Alert ') print('\n') print('
') print("
Packet Dump To Tap") if(interface.getInterfaceDumpTapName() ~= "") then print [[
]] print('> Dump Traffic To Tap ') print('('..interface.getInterfaceDumpTapName()..')') if(dump_traffic_tap_checked ~= "") then dumped = interface.getInterfacePacketsDumpedTap() print(" - "..ternary(dumped, dumped, 0).." packets dumped") end print(' ') print('\n') print('
') else print("Disabled. Please restart ntopng with --enable-taps") end print("
Sampling Rate]] if(dump_security_checked ~= "") then print[[
]] print('\n') print [[  
NOTE: Sampling rate is applied only when dumping packets caused by a security alert
(e.g. a volumetric DDoS attack) and not to those hosts/flows that have been marked explicitly for dump.
]] else print('Disabled. Enable packet dump on security alert.') end print[[
Dump To Disk Parameters
Pcap Dump Directory") pcapdir = dirs.workingdir .."/"..ifstats.id.."/pcap/" print(pcapdir.."
Max Packets per File
]] print('\n') print [[ pkts  
Maximum number of packets to store on a pcap file before creating a new file.
Max Duration of File
]] print('\n') print [[  sec  
Maximum pcap file duration before creating a new file.
NOTE: a dump file is closed when it reaches first the maximum size or duration specified.
Max Size of Dump Files
]] print('\n') print [[   MB    
Maximum size of created pcap files.
NOTE: total file size is checked daily and old dump files are automatically overwritten after reaching the threshold.
") end elseif(page == "alerts") then drawAlertSourceSettings(ifname_clean, i18n("show_alerts.iface_delete_config_btn"), i18n("show_alerts.iface_delete_config_confirm"), "if_stats.lua", {ifid=ifid}, if_name) elseif(page == "config") then if(not isAdministrator()) then return end print[[ ]] -- Custom name if ((not interface.isPcapDumpInterface()) and (ifstats.name ~= nil) and (ifstats.name ~= "dummy")) then print[[ ]] end -- Scaling factor if interface.isPacketInterface() then local label = ntop.getCache(getRedisIfacePrefix(ifid)..".scaling_factor") if((label == nil) or (label == "")) then label = "1" end print[[ ]] end print[[
Custom Name ]] local label = getInterfaceNameAlias(ifstats.name) inline_input_form("custom_name", "Custom Name", "Specify an alias for the interface", label, isAdministrator(), 'autocorrect="off" spellcheck="false" pattern="^[_\\-a-zA-Z0-9 ]*$"') print[[
Scaling Factor ]] inline_input_form("scaling_factor", "Scaling Factor", "This should match your capture interface sampling rate", label, isAdministrator(), 'type="number" min="1" step="1"', 'no-spinner') print[[
]] elseif(page == "pools") then dofile(dirs.installdir .. "/scripts/lua/admin/host_pools.lua") elseif(page == "filtering") then if not isAdministrator() then error() end -- ==================================== -- possibly decode parameters pairs local _POST = paramsPairsDecode(_POST) function get_shapers_from_parameters(callback) local done = {} for option,value in pairs(_POST) do local sp = split(option, "ishaper_") local k = nil if #sp == 2 then k = sp[2] else sp = split(option, "eshaper_") if #sp == 2 then k = sp[2] end end if k ~= nil then if not done[k] then done[k] = true; callback(k, _POST["ishaper_"..k], _POST["eshaper_"..k]) end end end end local perPageProtos if tonumber(tablePreferences("protocolShapers")) == nil then perPageProtos = "10" else perPageProtos = tablePreferences("protocolShapers") end -- TODO refactor view_network logic local selected_pool_id = _GET["pool"] or _POST["target_pool"] local selected_pool = nil local available_pools = host_pools_utils.getPoolsList(ifId) for _, pool in ipairs(available_pools) do if pool.id == selected_pool_id then selected_pool = pool end end if selected_pool == nil then selected_pool = available_pools[1] end local SHAPERS_MAX_RATE_KPBS = 100*1000*1000 -- 100 Gbit/s if(_POST["add_shapers"] ~= nil) then local num_added = 0 local last_added = nil for shaper,mrate in pairs(_POST) do local sp = split(shaper, "shaper_") if #sp == 2 then local shaper_id = tonumber(sp[2]) local max_rate = tonumber(mrate) --~ tprint(shaper_id.." "..max_rate) if(max_rate > SHAPERS_MAX_RATE_KPBS) then max_rate = -1 end if(max_rate < -1) then max_rate = -1 end shaper_utils.setShaperMaxRate(ifid, shaper_id, max_rate) num_added = num_added + 1 last_added = shaper_id end end if num_added == 1 then print("") end interface.reloadShapers() end if(_POST["delete_shaper"] ~= nil) then local shaper_id = _POST["delete_shaper"] shaper_utils.deleteShaper(ifid, shaper_id) end if(_POST["target_pool"] ~= nil) then local target_pool = _POST["target_pool"] if (_POST["del_l7_proto"] ~= nil) then local protocol_id = _POST["del_l7_proto"] shaper_utils.deleteProtocol(ifid, target_pool, protocol_id) else -- set protocols policy for the pool get_shapers_from_parameters(function(proto_id, ingress_shaper, egress_shaper) shaper_utils.setProtocolShapers(ifid, target_pool, proto_id, ingress_shaper, egress_shaper, false) end) if (_POST["blocked_categories"] ~= nil) then local sites_categories = split(_POST["blocked_categories"], ",") shaper_utils.setBlockedSitesCategories(ifid, target_pool, sites_categories) end end interface.reloadL7Rules(tonumber(selected_pool.id)) end print [[

]] -- ****************************************** local shapers = shaper_utils.getSortedShapers(ifid) function print_shapers(shapers, curshaper_id, terminator) terminator = terminator or "\n" if(curshaper_id == "") then curshaper_id = "0" else curshaper_id = tostring(curshaper_id) end for _,shaper in ipairs(shapers) do print(""..terminator) end end -- ****************************************** -- Create delete dialogs print( template.gen("modal_confirm_dialog.html", { dialog={ id = "delete_policy_dialog", action = "deleteShapedProtocol(delete_protocol_id)", title = i18n("shaping.delete_policy"), message = i18n("shaping.confirm_delete_policy") .. ' ' .. i18n("shaping.policy_from_pool") .. " \"" .. selected_pool.name .. "\"", confirm = i18n("delete"), } }) ) print( template.gen("modal_confirm_dialog.html", { dialog={ id = "delete_shaper_dialog", action = "deleteShaper(delete_shaper_id)", title = i18n("shaping.delete_shaper"), message = i18n("shaping.confirm_delete_shaper") .. ' ', confirm = i18n("delete"), } }) ) -- ****************************************** -- ==== Manage policies tab ==== print [[

]] print(i18n("host_pools.pool")..":") print[[ ') if selected_pool.id ~= host_pools_utils.DEFAULT_POOL_ID then print(' ') end print[[
]] local protos = interface.getnDPIProtocols() local protos_in_use = shaper_utils.getPoolProtoShapers(ifid, selected_pool.id, true --[[ do not aggregate into categories ]]) local protocol_categories = shaper_utils.getCategoriesWithProtocols() -- families of protocols which are currently used by at least one protocol local categories_in_use = {} for k,v in pairs(protos_in_use) do local proto_id = tonumber(v.protoId) -- can be null for default if proto_id ~= nil then local category_id = tostring(interface.getnDPIProtoCategory(proto_id).id) if not categories_in_use[category_id] then categories_in_use[category_id] = 1 else categories_in_use[category_id] = categories_in_use[category_id] + 1 end end end function print_ndpi_families_and_protocols(categories, protos, categories_disabled, protos_disabled, terminator) local protos_excluded = {GRE=1, BGP=1, IGMP=1, IPP=1, IP_in_IP=1, OSPF=1, PPTP=1, SCTP=1, TFTP=1} print('') for k,category in pairsByKeys(categories, asc) do print(''..terminator) end print('') print('') for protoName,protoId in pairsByKeys(protos, asc) do if not protos_excluded[protoName] then -- find protocol category for _,category in pairs(categories) do for _,catProto in pairs(category.protos) do if catProto == protoId then print('"..terminator) break end end end end end print('') end local sites_categories = ntop.getSiteCategories() if sites_categories ~= nil then -- flashstart is enabled here local blocked_categories = shaper_utils.getBlockedSitesCategories(ifid, selected_pool.id) print[[

Flashstart Categories
Select the categories to block

]] end print [[
NOTES:
]] -- ****************************************** -- ==== Bandwidth Manager tab ==== print[[

]] print [[
]] print(i18n('shaping.notes')) print[[
]] elseif page == "traffic_report" then dofile(dirs.installdir .. "/pro/scripts/lua/enterprise/traffic_report.lua") end print(" ]] print [[ ]] dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")