-- -- (C) 2013-20 - ntop.org -- local dirs = ntop.getDirs() package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path if(ntop.isPro()) then package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path require "snmp_utils" shaper_utils = require("shaper_utils") host_pools_utils = require "host_pools_utils" end require "lua_utils" require "graph_utils" require "alert_utils" require "historical_utils" local json = require ("dkjson") local host_pools_utils = require "host_pools_utils" local discover = require "discover_utils" local page_utils = require "page_utils" local template = require "template_utils" local mud_utils = require "mud_utils" local companion_interface_utils = require "companion_interface_utils" local flow_consts = require "flow_consts" local alert_consts = require "alert_consts" local info = ntop.getInfo() local have_nedge = ntop.isnEdge() local debug_hosts = false local page = _GET["page"] local protocol_id = _GET["protocol"] local application = _GET["application"] local category = _GET["category"] local host_info = url2hostinfo(_GET) local host_ip = host_info["host"] local host_name = hostinfo2hostkey(host_info) local host_vlan = host_info["vlan"] or 0 local always_show_hist = _GET["always_show_hist"] local ntopinfo = ntop.getInfo() if not isEmptyString(_GET["ifid"]) then interface.select(_GET["ifid"]) else interface.select(ifname) end local ifstats = interface.getStats() ifId = ifstats.id local charts_available = areHostTimeseriesEnabled(ifId, host_info) local is_pcap_dump = interface.isPcapDumpInterface() local host = nil local family = nil local prefs = ntop.getPrefs() local hostkey = hostinfo2hostkey(host_info, nil, true --[[ force show vlan --]]) local hostkey_compact = hostinfo2hostkey(host_info) -- do not force vlan if((host_name == nil) or (host_ip == nil)) then sendHTTPContentTypeHeader('text/html') page_utils.print_header() dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") print("
" .. i18n("host_details.host_parameter_missing_message") .. "
") return end -- print(">>>") print(host_info["host"]) print("<<<") if(debug_hosts) then traceError(TRACE_DEBUG,TRACE_CONSOLE, i18n("host_details.trace_debug_host_info",{hostinfo=host_info["host"],vlan=host_vlan}).."\n") end local host = interface.getHostInfo(host_info["host"], host_vlan) local tskey if _GET["tskey"] then tskey = _GET["tskey"] elseif host then tskey = host["tskey"] else tskey = host_key end local restoreFailed = false -- NOTE: calling interface.restoreHost generates crashes! --[[ if((host == nil) and ((_POST["mode"] == "restore") or (page == "historical"))) then if(debug_hosts) then traceError(TRACE_DEBUG,TRACE_CONSOLE, i18n("host_details.trace_debug_restored_host_info").."\n") end interface.restoreHost(host_info["host"], host_vlan) host = interface.getHostInfo(host_info["host"], host_vlan) restoreFailed = true end ]] local top_sites = ((host ~= nil) and host["sites"] and json.decode(host["sites"])) or {} local top_sites_old = ((host ~= nil) and host["sites.old"] and json.decode(host["sites.old"])) or {} local labelKey = host_info["host"].."@"..host_info["vlan"] local host_pool_id = nil if (host ~= nil) then charts_available = charts_available and host["localhost"] if (isAdministrator() and (_POST["pool"] ~= nil)) then host_pool_id = _POST["pool"] local prev_pool = tostring(host["host_pool_id"]) if host_pool_id ~= prev_pool then local key = host2member(host["ip"], host["vlan"]) if not host_pools_utils.changeMemberPool(ifId, key, host_pool_id, host) then host_pool_id = nil else interface.reloadHostPools() end end end if (host_pool_id == nil) then host_pool_id = tostring(host["host_pool_id"]) end end local only_historical = (host == nil) and ((page == "historical") or (page == "config") or (page == "alerts")) if(host == nil) and (not only_historical) then -- We need to check if this is an aggregated host if(not(restoreFailed) and (host_info ~= nil) and (host_info["host"] ~= nil)) then json = ntop.getCache(host_info["host"].. "." .. ifId .. ".json") end sendHTTPContentTypeHeader('text/html') page_utils.set_active_menu_entry(page_utils.menu_entries.hosts) if page == "alerts" then print('') else dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") print('
'.. i18n("host_details.host_cannot_be_found_message",{host=hostinfo2hostkey(host_info)}) .. " ") if((json ~= nil) and (json ~= "")) then print[[
]] print[[]] print[[]] print[[
]] print[[ ]] print(i18n("host_details.restore_from_cache_message",{js_code="\"javascript:void(0);\" onclick=\"$(\'#host_restore_form\').submit();\""})) else print(purgedErrorString()) end print("
") dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua") return end else sendHTTPContentTypeHeader('text/html') page_utils.set_active_menu_entry(page_utils.menu_entries.hosts, nil, i18n("host", { host = host_info["host"] })) print("\n") dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua") -- Added global javascript variable, in order to disable the refresh of pie chart in case -- of historical interface print('\n\n') if _POST["action"] == "reset_stats" and isAdministrator() then if interface.resetHostStats(hostkey) then print("
") print[[]] print(i18n("host_details.reset_stats_in_progress")) print("
") end end if host == nil then -- only_historical = true here host = hostkey2hostinfo(host_info["host"] .. "@" .. host_vlan) end if(host["ip"] ~= nil) then host_name = hostinfo2hostkey(host) host_info["host"] = host["ip"] end if(_POST["custom_name"] ~=nil) and isAdministrator() then setHostAltName(hostinfo2hostkey(host_info), _POST["custom_name"]) end host["label"] = getHostAltName(hostinfo2hostkey(host_info), host["mac"]) if((host["label"] == nil) or (host["label"] == "")) then host["label"] = getHostAltName(host["ip"]) end if(host["name"] == nil) then host["name"] = host["label"] end print('
 '..i18n("details.host_purged")..'
') local url = ntop.getHttpPrefix().."/lua/host_details.lua?ifid="..ifId.."&"..hostinfo2url(host_info) if _GET["tskey"] ~= nil then url = url .. "&tskey=" .. _GET["tskey"] end local title = i18n("host_details.host")..": "..host_info["host"] if host["broadcast_domain_host"] then title = title.." " end if host.dhcpHost then title = title.." " end local url = ntop.getHttpPrefix().."/lua/host_details.lua?"..hostinfo2url(host_info) local has_snmp_location = info["version.enterprise_edition"] and host_has_snmp_location(host["mac"]) page_utils.print_navbar(title, url, { { hidden = only_historical, active = page == "overview" or page == nil, page_name = "overview", label = "", }, { hidden = only_historical, active = page == "traffic", page_name = "traffic", label = i18n("traffic"), }, { hidden = only_historical or (host["packets.sent"] + host["packets.rcvd"] == 0), active = page == "packets", page_name = "packets", label = i18n("packets"), }, { hidden = only_historical, active = page == "ports", page_name = "ports", label = i18n("ports"), }, { hidden = only_historical or interface.isLoopback(), active = page == "peers", page_name = "peers", label = i18n("peers"), }, { hidden = only_historical or not host["localhost"] or (not host["ICMPv4"] and not host["ICMPv6"]), active = page == "ICMP", page_name = "ICMP", label = i18n("icmp"), }, { hidden = only_historical, active = page == "ndpi", page_name = "ndpi", label = i18n("applications"), }, { hidden = only_historical or not host["localhost"], active = page == "dns", page_name = "dns", label = i18n("dns"), }, { hidden = only_historical or not host["ja3_fingerprint"], active = page == "tls", page_name = "tls", label = i18n("tls"), }, { hidden = only_historical or not host["hassh_fingerprint"], active = page == "ssh", page_name = "ssh", label = i18n("ssh"), }, { hidden = only_historical or ntop.isnEdge() or not host["localhost"] or not host["http"] or (host["http"]["sender"]["query"]["total"] == 0 and host["http"]["receiver"]["response"]["total"] == 0 and table.len(host["http"]["virtual_hosts"] or {}) == 0), active = page == "http", page_name = "http", label = i18n("http"), badge_num = host["active_http_hosts"], }, { hidden = only_historical, active = page == "flows", page_name = "flows", label = i18n("flows"), }, { hidden = only_historical or not host["localhost"] or (table.len(top_sites) == 0 and table.len(top_sites_old) == 0), active = page == "sites", page_name = "sites", label = i18n("sites_page.sites"), }, { hidden = only_historical or not host["systemhost"] or not interface.hasEBPF(), active = page == "processes", page_name = "processes", label = i18n("user_info.processes"), }, { hidden = only_historical or host["privatehost"] or not ntop.hasGeoIP(), active = page == "geomap", page_name = "geomap", label = "", }, { hidden = not areAlertsEnabled(), active = page == "alerts", page_name = "alerts", label = "", }, { hidden = not charts_available, active = page == "historical", page_name = "historical", label = "", }, { hidden = only_historical or (not host["localhost"]) or (not hasTrafficReport()), active = page == "traffic_report", page_name = "traffic_report", label = "", }, { hidden = only_historical or not ntop.isEnterprise() or not ifstats.inline or not host_pool_id ~= host_pools_utils.DEFAULT_POOL_ID, active = page == "quotas", page_name = "quotas", label = i18n("quotas"), }, { hidden = not isAdministrator() or interface.isPcapDumpInterface(), active = page == "config", page_name = "config", label = "", }, } ) -- tprint(host.bins) local macinfo = interface.getMacInfo(host["mac"]) local has_snmp_location = host['localhost'] and (host["mac"] ~= "") and (info["version.enterprise_edition"]) and host_has_snmp_location(host["mac"]) and isAllowedSystemInterface() if((page == "overview") or (page == nil)) then print("\n") if(host["ip"] ~= nil) then if(host["mac"] ~= "00:00:00:00:00:00") then print("') end local snmp_url = ntop.getHttpPrefix().."/lua/host_details.lua?ifid="..ifId.."&"..hostinfo2url(host_info).."&page=snmp"; if has_snmp_location then local url = ntop.getHttpPrefix().."/lua/host_details.lua?ifid="..ifId.."&"..hostinfo2url(host_info).."&page=snmp"; print_host_snmp_location(host["mac"], url) end print("") print("") else if(host["mac"] ~= nil) then print("\n") end end if host["vlan"] and host["vlan"] > 0 then print("\n") end if(host["os"] ~= "" and host["os"] ~= 0) then print("") if(host["os"] ~= "") then local os_detail = "" if not isEmptyString(host["os_detail"]) then os_detail = os_detail .. " [" .. host["os_detail"] .. "]" end print("\n") else print("\n") end print("") end if((host["asn"] ~= nil) and (host["asn"] > 0)) then print("") print('') print("\n") end if(host["ip"] ~= nil) then if(isEmptyString(host["name"])) then host["name"] = getResolvedAddress(hostkey2hostinfo(host["ip"])) end if(isEmptyString(host["name"])) then host["name"] = host["ip"] end print("") if(isAdministrator()) then print("\n") end if(host["num_alerts"] > 0) then print("\n") end if isScoreEnabled() then local score_chart = "" if charts_available then score_chart = '' end print("\n") end if(host["active_alerted_flows"] > 0) then print("\n") end if ntop.isPro() and ifstats.inline and (host["has_blocking_quota"] or host["has_blocking_shaper"]) then local msg = "" local target = "" local quotas_page = "/lua/host_details.lua?"..hostinfo2url(host).."&page=quotas&ifid="..ifId local policies_page = "/lua/if_stats.lua?ifid="..ifId.."&page=filtering&pool="..host_pool_id if host["has_blocking_quota"] then if host["has_blocking_shaper"] then msg = i18n("host_details.host_traffic_blocked_quota_and_shaper") target = quotas_page else msg = i18n("host_details.host_traffic_blocked_quota") target = quotas_page end else msg = i18n("host_details.host_traffic_blocked_shaper") target = policies_page end print("") end print("\n") print("\n") if((host["bytes.sent"]+host["bytes.rcvd"]) > 0) then print("\n") end print("\n") local flows_th = i18n("details.flows_non_packet_iface") if interface.isPacketInterface() then flows_th = i18n("details.flows_packet_iface") end if interfaceHasNindexSupport() then flows_th = flows_th .. ' ' end print("\n") print("") print("") if(false) then print("\n") print("\n") end print("") print("") print("") print("") end if host["tcp.packets.seq_problems"] == true then local tcp_seq_label = "TCP: "..i18n("details.retransmissions").." / "..i18n("details.out_of_order").." / "..i18n("details.lost").." / "..i18n("details.keep_alive") -- SENT ANALYSIS local tcp_retx_sent = ""..formatPackets(host["tcpPacketStats.sent"]["retransmissions"]).."" local tcp_ooo_sent = ""..formatPackets(host["tcpPacketStats.sent"]["out_of_order"]).."" local tcp_lost_sent = ""..formatPackets(host["tcpPacketStats.sent"]["lost"]).."" local tcp_keep_alive_sent = ""..formatPackets(host["tcpPacketStats.sent"]["keep_alive"]).."" -- RCVD ANALYSIS local tcp_retx_rcvd = ""..formatPackets(host["tcpPacketStats.rcvd"]["retransmissions"]).."" local tcp_ooo_rcvd = ""..formatPackets(host["tcpPacketStats.rcvd"]["out_of_order"]).."" local tcp_lost_rcvd = ""..formatPackets(host["tcpPacketStats.rcvd"]["lost"]).."" local tcp_keep_alive_rcvd = ""..formatPackets(host["tcpPacketStats.rcvd"]["keep_alive"]).."" print("") print("") end -- Stats reset print( template.gen("modal_confirm_dialog.html", { dialog={ id = "reset_host_stats_dialog", action = "$('#reset_host_stats_form').submit();", title = i18n("host_details.reset_host_stats"), message = i18n("host_details.reset_host_stats_confirm", {host=host["name"]}) .. "

" .. i18n("host_details.reset_host_stats_note"), confirm = i18n("reset"), } }) ) print[[]] local num_extra_names = 0 local extra_names = host["names"] local num_extra_names = table.len(extra_names) if num_extra_names > 0 then local name_sources = {} for source, name in pairsByKeys(extra_names, rev) do if source == "resolved" then source = "DNS Resolution" else source = source:upper() end if not name_sources[name] then name_sources[name] = source else -- Collapse multiple sources in a single row when the name is the same name_sources[name] = string.format("%s, %s", source, name_sources[name]) num_extra_names = num_extra_names - 1 end end print('') print("\n") for name, source in pairsByValues(name_sources, asc) do print("\n") end end print("JSON") print [[]] print("\n") if(host["ssdp"] ~= nil) then print("\n") end print("
"..i18n("details.router_access_point_mac_address").."" ..get_symbolic_mac(host["mac"]).. " " .. discover.devtype2icon(host["device_type"])) print('') if(host['localhost'] and (macinfo ~= nil)) then -- This is a known device type print(discover.devtype2icon(macinfo.devtype) .. " ") if macinfo.devtype ~= 0 then print(discover.devtype2string(macinfo.devtype) .. " ") else print(i18n("host_details.unknown_device_type") .. " ") end print('\n') else print(" ") end print('
"..i18n("ip_address").."" .. host["ip"]) if(host.childSafe == true) then print(getSafeChildIcon()) end if(host.os ~= 0) then print(" "..discover.getOsIcon(host.os).." ") end historicalProtoHostHref(getInterfaceId(ifname), host["ip"], nil, nil, nil) if(host["local_network_name"] ~= nil) then print(" [ ".. host["local_network_name"].." ]") end if((host["city"] ~= nil) and (host["city"] ~= "")) then print(" [ " .. host["city"] .." "..getFlag(host["country"]).." ]") end print[[]] print(i18n(ternary(have_nedge, "nedge.user", "details.host_pool"))..": ") print[[]] print(host_pools_utils.getPoolName(ifId, host_pool_id)) print[[]] print[[  ]] print[[]] print("
"..i18n("mac_address").."" .. host["mac"].. "
") print(i18n("details.vlan_id")) print(""..host["vlan"].."
"..i18n("os").." ".. discover.getOsAndIcon(host["os"]) .."".. os_detail .."
"..i18n("asn").."") print(""..host.asname.." [ "..i18n("asn").." ".. host.asn.." ]'..i18n("details.whois_lookup")..'
"..i18n("name").." ") else print("") end if(host["ip"] == host["name"]) then print(" ") end -- tprint(host) io.write("\n") print(host["name"] .. " ") if host["is_blacklisted"] then print(" ") end print[[ ]] print[[ ]] if(host["localhost"] == true) then print(''..i18n("details.label_local_host")..'') else print(''..i18n("details.label_remote")..'') end if(host["is_multicast"] == true) then print(' Multicast ') end if(host["is_broadcast"] == true) then print(' Broadcast ') end if host["broadcast_domain_host"] then print(" ") end if(host["privatehost"] == true) then print(' '..i18n("details.label_private_ip")..'') end if(host["systemhost"] == true) then print(' ') end if(host["is_blacklisted"] == true) then print(' '..i18n("details.label_blacklisted_host")..'') end print("
"..i18n("show_alerts.engaged_alerts").." "..host["num_alerts"] .. "
"..i18n("score").." " .. score_chart .." "..host["score"] .. "
"..i18n("host_details.active_alerted_flows").." "..host["active_alerted_flows"] .. "
"..i18n("host_details.blocked_traffic")..""..msg) print(".") print("
"..i18n("details.first_last_seen").."" .. formatEpoch(host["seen.first"]) .. " [" .. secondsToTime(os.time()-host["seen.first"]) .. " "..i18n("details.ago").."]" .. "" .. formatEpoch(host["seen.last"]) .. " [" .. secondsToTime(os.time()-host["seen.last"]) .. " "..i18n("details.ago") .. "]" .. "
"..i18n("details.sent_vs_received_traffic_breakdown").."") breakdownBar(host["bytes.sent"], i18n("sent"), host["bytes.rcvd"], i18n("details.rcvd"), 0, 100) print("
"..i18n("details.traffic_sent_received").."" .. formatPackets(host["packets.sent"]) .. " / ".. bytesToSize(host["bytes.sent"]) .. " " .. formatPackets(host["packets.rcvd"]) .. " / ".. bytesToSize(host["bytes.rcvd"]) .. "
"..i18n("details.as_client")..""..i18n("details.as_server").."
"..flows_th.."" .. formatValue(host["active_flows.as_client"]) .. " \n") print("/ " .. formatValue(host["flows.as_client"]) .. " \n") print("/ " .. formatValue(host["misbehaving_flows.as_client"]) .. " ") print(" / " .. formatValue(host["unreachable_flows.as_client"]) .. " ") print("" .. formatValue(host["active_flows.as_server"]) .. " \n") print("/ "..formatValue(host["flows.as_server"]) .. " \n") print("/ " .. formatValue(host["misbehaving_flows.as_server"]) .. " ") print(" / " .. formatValue(host["unreachable_flows.as_server"]) .. " ") print("
"..i18n("details.misbehaving_flows_reasons").."") for _, t in pairs(flow_consts.status_types) do local id = t.status_id if ntop.bitmapIsSet(host["misbehaving_flows_status_map.as_client"], id) then print(flow_consts.getStatusDescription(id).."
") end end print("
") for _, t in pairs(flow_consts.status_types) do local id = t.status_id if ntop.bitmapIsSet(host["misbehaving_flows_status_map.as_server"], id) then print(flow_consts.getStatusDescription(id).."
") end end print("
"..i18n("details.peers").."" .. formatValue(host["contacts.as_client"]) .. " \n") print("" .. formatValue(host["contacts.as_server"]) .. " \n") if ntop.isnEdge() then print("
"..i18n("details.flows_dropped_by_bridge").."" .. formatValue((host["flows.dropped"] or 0)) .. " ") print("
"..tcp_seq_label..""..i18n("sent")..""..i18n("received").."
"..string.format("%s / %s / %s / %s", tcp_retx_sent, tcp_ooo_sent, tcp_lost_sent, tcp_keep_alive_sent)..""..string.format("%s / %s / %s / %s", tcp_retx_rcvd, tcp_ooo_rcvd, tcp_lost_rcvd, tcp_keep_alive_rcvd).."
]] print(i18n("host_details.reset_host_stats")) print[[
'.. i18n("details.further_host_names_information") ..' "..i18n("details.source")..""..i18n("name").."
"..source..""..name.."
"..i18n("download").." ]] if (show_live_capture and ifstats.isView == false and ifstats.isDynamic == false and interface.isPacketInterface()) then local live_traffic_utils = require("live_traffic_utils") live_traffic_utils.printLiveTrafficForm(ifId, host_info) end print[[
SSDP (UPnP) "..host["ssdp"].."
\n") elseif((page == "packets")) then print [[ ]] local tots = 0 for key, value in pairs(host["pktStats.sent"]["size"]) do tots = tots + value end local totr = 0 for key, value in pairs(host["pktStats.recv"]["size"]) do totr = totr + value end if((tots > 0) or (totr > 0)) then print('') if(tots > 0) then print('') else print('') end if(totr > 0) then print('') else print('') end print('') end local has_tcp_distro = (host["tcp.packets.rcvd"] + host["tcp.packets.sent"] > 0) local has_arp_distro = (not isEmptyString(host["mac"])) and (host["mac"] ~= "00:00:00:00:00:00") if(has_tcp_distro and has_arp_distro) then print('') else if (has_tcp_distro) then print('') end if (has_arp_distro) then if (macinfo ~= nil) and (macinfo["arp_requests.sent"] + macinfo["arp_requests.rcvd"] + macinfo["arp_replies.sent"] + macinfo["arp_replies.rcvd"] > 0) then print('') end end end hostinfo2json(host_info) print [[
'..i18n("packets_page.sent_vs_rcvd_distribution")..'
 
 
'..i18n("packets_page.tcp_flags_vs_arp_distribution")..'
'..i18n("packets_page.tcp_flags_distribution")..'
'..i18n("packets_page.arp_distribution")..'

]] elseif((page == "ports")) then print [[ ]] print('') print('') print [[
'..i18n("ports_page.client_ports")..'
'..i18n("ports_page.server_ports")..'

]] elseif((page == "peers")) then host_info = url2hostinfo(_GET) peers = getTopFlowPeers(hostinfo2hostkey(host_info), 1 --[[exists query]]) found = 0 for key, value in pairs(peers) do found = 1 break end if(found) then print [[
]] print(i18n("peers_page.top_peers_for_host",{hostkey=hostinfo2hostkey(host_info)})) print [[
]] print(i18n("peers_page.top_peer_protocol")) print[[

]] print(i18n("peers_page.host")) print[[ ]] print(i18n("application")) print[[ ]] print(i18n("peers_page.traffic_volume")) print[[
]] else print(" "..i18n("peers_page.no_active_flows_message").."") end elseif((page == "traffic")) then total = 0 for id, _ in ipairs(l4_keys) do k = l4_keys[id][2] if(host[k..".bytes.sent"] ~= nil) then total = total + host[k..".bytes.sent"] end if(host[k..".bytes.rcvd"] ~= nil) then total = total + host[k..".bytes.rcvd"] end end if(total == 0) then print("

"..i18n("traffic_page.no_traffic_observed_message").."
") else print [[ ]] local num_expired_client_flows = host["flows.as_client"]-host["active_flows.as_client"] local num_expired_server_flows = host["flows.as_server"]-host["active_flows.as_server"] if((num_expired_client_flows+num_expired_server_flows) > 0) then print [[ ]] -- ############ print [[]] if(num_expired_client_flows) then print [[ ]] else print("td colspan=2> ") end -- ############ print [[]] if(num_expired_server_flows) then print [[ ]] else print("td colspan=2> ") end end print [[ ]] print("\n") for id, _ in ipairs(l4_keys) do label = l4_keys[id][1] k = l4_keys[id][2] sent = host[k..".bytes.sent"] if(sent == nil) then sent = 0 end rcvd = host[k..".bytes.rcvd"] if(rcvd == nil) then rcvd = 0 end if((sent > 0) or (rcvd > 0)) then print("\n") end end print("
]] print(i18n("traffic_page.l4_proto_overview")) print[[
]] print(i18n("traffic_page.flow_distribution")) print[[ ]] print(i18n("traffic_page.flow_duration")) print[[ ]] print(i18n("traffic_page.flow_frequency")) print[[
]] print(i18n("details.as_client")) print[[
 
]] print(i18n("details.as_server")) print[[
 
"..i18n("protocol")..""..i18n("sent")..""..i18n("received")..""..i18n("breakdown")..""..i18n("total").."
") if(charts_available) then print("".. label .."") else print(label) end t = sent+rcvd historicalProtoHostHref(ifId, host, l4_keys[id][3], nil, nil) print("" .. bytesToSize(sent) .. "" .. bytesToSize(rcvd) .. "") breakdownBar(sent, i18n("sent"), rcvd, i18n("traffic_page.rcvd"), 0, 100) print("" .. bytesToSize(t).. "" .. round((t * 100)/total, 2).. " %
\n") print("\n") end elseif((page == "ICMP")) then print [[
]] print(i18n("icmp_page.icmp_message")) print[[]] print(i18n("icmp_page.icmp_type")) print [[]] print(i18n("icmp_page.icmp_code")) print [[]] print(i18n("icmp_page.last_sent_peer")) print[[]] print(i18n("icmp_page.last_rcvd_peer")) print[[]] print(i18n("breakdown")) print[[]] print(i18n("icmp_page.packets_sent")) print[[]] print(i18n("icmp_page.packets_received")) print[[]] print(i18n("total")) print[[
]] elseif((page == "ndpi")) then if(host["ndpi"] ~= nil) then print [[

]] if ntop.isPro() and host["custom_apps"] then print[[ ]] end print[[
]] print(i18n("ndpi_page.overview", {what = i18n("ndpi_page.custom_applications")})) print [[
]] print(i18n("ndpi_page.overview", {what = i18n("applications")})) print[[
]] local direction_filter = "" local base_url = ntop.getHttpPrefix().."/lua/host_details.lua?ifid="..ifId.."&"..hostinfo2url(host_info).."&page=ndpi"; if(direction ~= nil) then direction_filter = '' end print('
') print('
') print [[
]] print(i18n("application")) print[[ ]] print(i18n("duration")) print[[ ]] print(i18n("sent")) print[[ ]] print(i18n("received")) print[[ ]] print(i18n("breakdown")) print[[ ]] print(i18n("total")) print[[

]] print(i18n("ndpi_page.overview", {what = i18n("categories")})) print[[
]] print(i18n("category")) print[[ ]] print(i18n("duration")) print[[ ]] print(i18n("total")) print[[
]] print[[ ]] local host_ndpi_timeseries_creation = ntop.getCache("ntopng.prefs.host_ndpi_timeseries_creation") print(""..i18n("notes").."") if host_ndpi_timeseries_creation ~= "both" and host_ndpi_timeseries_creation ~= "per_protocol" then print("
  • "..i18n("ndpi_page.note_historical_per_protocol_traffic",{what=i18n("application"), url=ntop.getHttpPrefix().."/lua/admin/prefs.lua?tab=on_disk_ts",flask_icon=""}).." ") end if host_ndpi_timeseries_creation ~= "both" and host_ndpi_timeseries_creation ~= "per_category" then print("
  • "..i18n("ndpi_page.note_historical_per_protocol_traffic",{what=i18n("category"), url=ntop.getHttpPrefix().."/lua/admin/prefs.lua",flask_icon=""}).." ") end print("
  • "..i18n("ndpi_page.note_possible_probing_alert",{icon="",url=ntop.getHttpPrefix().."/lua/host_details.lua?ifid="..ifId.."&host=".._GET["host"].."&page=historical"})) print("
  • "..i18n("ndpi_page.note_protocol_usage_time")) print("") end elseif(page == "dns") then if(host["dns"] ~= nil) then print("\n") print("") print("") print("") print("") print("") print("") print("") if host["dns"]["rcvd"]["num_replies_ok"] + host["dns"]["rcvd"]["num_replies_error"] > 0 then print('') local dns_ratio = tonumber(host["dns"]["sent"]["num_queries"]) / tonumber(host["dns"]["rcvd"]["num_replies_ok"]+host["dns"]["rcvd"]["num_replies_error"]) local dns_ratio_str = string.format("%.2f", dns_ratio) if(dns_ratio < 0.9) then dns_ratio_str = "".. dns_ratio_str .."" end print(']] end -- Charts if((host["dns"]["sent"]["num_queries"] + host["dns"]["rcvd"]["num_queries"]) > 0) then print [[]] if(host["dns"]["sent"]["num_queries"] > 0) then print[[ ]] else print[[]] end if(host["dns"]["rcvd"]["num_queries"] > 0) then print [[ ]] else print [[]] end print("") end print[[
    "..i18n("dns_page.dns_breakdown")..""..i18n("dns_page.queries")..""..i18n("dns_page.positive_replies")..""..i18n("dns_page.error_replies")..""..i18n("dns_page.reply_breakdown").."
    "..i18n("sent").."".. formatValue(host["dns"]["sent"]["num_queries"]) .." ".. formatValue(host["dns"]["sent"]["num_replies_ok"]) .." ".. formatValue(host["dns"]["sent"]["num_replies_error"]) .." ") breakdownBar(host["dns"]["sent"]["num_replies_ok"], "OK", host["dns"]["sent"]["num_replies_error"], "Error", 0, 100) print("
    "..i18n("dns_page.rcvd").."".. formatValue(host["dns"]["rcvd"]["num_queries"]) .." ".. formatValue(host["dns"]["rcvd"]["num_replies_ok"]) .." ".. formatValue(host["dns"]["rcvd"]["num_replies_error"]) .." ") breakdownBar(host["dns"]["rcvd"]["num_replies_ok"], "OK", host["dns"]["rcvd"]["num_replies_error"], "Error", 50, 100) print("
    '..i18n("dns_page.request_vs_reply")..''.. dns_ratio_str ..'') breakdownBar(host["dns"]["sent"]["num_queries"], i18n("dns_page.queries"), host["dns"]["rcvd"]["num_replies_ok"]+host["dns"]["rcvd"]["num_replies_error"], i18n("dns_page.replies"), 30, 70) print [[
    ]] print(i18n("dns_page.dns_query_sent_vs_rcvd_distribution")) print[[
     
     
    ]] print(i18n("dns_page.note")) print[[:
    ]] print(i18n("dns_page.note_dns_ratio")) print[[
    ]] end elseif(page == "tls") then print [[ ]] if not isEmptyString(companion_interface_utils.getCurrentCompanion(ifId)) then print[[]] end print[[]] print[[
    ]] print(''..i18n("ja3_fingerprint")..'') print[[]] print(i18n("app_name")) print[[]] print(i18n("num_uses")) print[[
    ]] print(""..i18n("notes").."") elseif(page == "ssh") then print [[ ]] if not isEmptyString(companion_interface_utils.getCurrentCompanion(ifId)) then print[[]] end print[[
    ]] print(''..i18n("hassh_fingerprint")..'') print[[]] print(i18n("app_name")) print[[]] print(i18n("num_uses")) print[[
    ]] print(""..i18n("notes").."") elseif(page == "http") then local http = host["http"] if http then print("\n") if http["sender"]["query"]["total"] > 0 then print("") print("") print("") print("") print("") print("") end if http["receiver"]["response"]["total"] > 0 then print("") print("") print("") print("") print("") print("") end local vh = http["virtual_hosts"] if vh then local now = os.time() local ago1h = now - 3600 local num = table.len(vh) if(num > 0) then local ifId = getInterfaceId(ifname) print("\n") for k,v in pairsByKeys(vh, asc) do local j = string.gsub(k, "%.", "___") print("") print("") print("") print("\n") end end end print("
    "..i18n("http_page.http_queries")..""..i18n("http_page.method")..""..i18n("http_page.requests")..""..i18n("http_page.distribution").."
    GET".. formatValue(http["sender"]["query"]["num_get"]) .." ") print [[
    ]] print("
    POST".. formatValue(http["sender"]["query"]["num_post"]) .."
    HEAD".. formatValue(http["sender"]["query"]["num_head"]) .."
    PUT".. formatValue(http["sender"]["query"]["num_put"]) .."
    "..i18n("http_page.other_method").."".. formatValue(http["sender"]["query"]["num_other"]) .."
    "..i18n("http_page.http_responses")..""..i18n("http_page.response_code")..""..i18n("http_page.responses")..""..i18n("http_page.distribution").."
    "..i18n("http_page.response_code_1xx").."".. formatValue(http["receiver"]["response"]["num_1xx"]) .." ") print [[
    ]] print("
    "..i18n("http_page.response_code_2xx").."".. formatValue(http["receiver"]["response"]["num_2xx"]) .."
    "..i18n("http_page.response_code_3xx").."".. formatValue(http["receiver"]["response"]["num_3xx"]) .."
    "..i18n("http_page.response_code_4xx").."".. formatValue(http["receiver"]["response"]["num_4xx"]) .."
    "..i18n("http_page.response_code_5xx").."".. formatValue(http["receiver"]["response"]["num_5xx"]) .."
    "..i18n("http_page.virtual_hosts").."Name"..i18n("http_page.traffic_sent")..""..i18n("http_page.traffic_received")..""..i18n("http_page.requests_served").."
    "..k.." ") historicalProtoHostHref(ifId, host, nil, nil, k) print(""..bytesToSize(vh[k]["bytes.sent"])..""..bytesToSize(vh[k]["bytes.rcvd"])..""..formatValue(vh[k]["http.requests"]).."
    \n") end elseif(page == "sites") then if not prefs.are_top_talkers_enabled then local msg = i18n("sites_page.top_sites_not_enabled_message",{url=ntop.getHttpPrefix().."/lua/admin/prefs.lua?tab=protocols"}) print("
    "..msg.."
    ") elseif table.len(top_sites) > 0 or table.len(top_sites_old) > 0 then print("\n") local old_top_len = table.len(top_sites_old) if(old_top_len > 10) then old_top_len = 10 end local top_len = table.len(top_sites) if(top_len > 10) then top_len = 10 end if(old_top_len > top_len) then num = old_top_len else num = top_len end print("\n") local sites = {} for k,v in pairsByValues(top_sites, rev) do table.insert(sites, { k, v }) end local sites_old = {} for k,v in pairsByValues(top_sites_old, rev) do table.insert(sites_old, { k, v }) end for i = 1,num do if(sites[i] == nil) then sites[i] = { "", 0 } end if(sites_old[i] == nil) then sites_old[i] = { "", 0 } end print("\n") else print(" \n") end if(sites_old[i][1] ~= "") then print("\n") else print("\n") end print("") end print("
    "..i18n("sites_page.top_visited_sites")..""..i18n("sites_page.current_sites")..""..i18n("sites_page.contacts")..""..i18n("sites_page.last_5_minutes_sites")..""..i18n("sites_page.contacts").."
    ") if(sites[i][1] ~= "") then print(formatWebSite(sites[i][1])..""..sites[i][2].." "..formatWebSite(sites_old[i][1])..""..sites_old[i][2].."  
    \n") else local msg = i18n("sites_page.top_sites_not_seen") print("
    "..msg.."
    ") end elseif(page == "flows") then require("flow_utils") print [[
    ]] elseif(page == "snmp" and ntop.isEnterprise() and isAllowedSystemInterface()) then local snmp_devices = get_snmp_devices() if snmp_devices[host_ip] == nil then -- host has not been configured if not has_snmp_location then local msg = i18n("snmp_page.not_configured_as_snmp_device_message",{host_ip=host_ip}) msg = msg.." "..i18n("snmp_page.guide_snmp_page_message",{url=ntop.getHttpPrefix().."/lua/pro/enterprise/snmpdevices_stats.lua"}) print("
    "..msg.."
    ") end else local snmp_device = require "snmp_device" local snmp_device_ip = snmp_devices[host_ip]["ip"] snmp_device.init(snmp_device_ip) local cache_status = snmp_device.get_cache_status() if not cache_status["system"] or cache_status["system"]["last_updated"] < os.time() - 86400 then local res = snmp_device.cache_system() if res["status"] ~= "OK" then snmp_handle_cache_errors(snmp_device_ip, res) end end print_snmp_device_system_table(snmp_device.get_device()) end if has_snmp_location then print[[]] print_host_snmp_localization_table_entry(host["mac"]) print[[
    ]] end elseif(page == "processes") then local ebpf_utils = require "ebpf_utils" ebpf_utils.draw_processes_graph(host_info) elseif not host.privatehost and page == "geomap" then print ([[

    ]].. i18n("geo_map.hosts_geomap").. [[

    ]]) elseif(page == "contacts") then if(num > 0) then mode = "embed" if(host["name"] == nil) then host["name"] = getResolvedAddress(hostkey2hostinfo(host["ip"])) end name = host["name"] dofile(dirs.installdir .. "/scripts/lua/hosts_interaction.lua") print("\n") print("\n") print("") if(cnum == 0) then print("") else print("\n") end if(snum == 0) then print("") else print("\n") end print("\n") print("
    "..i18n("contacts_page.client_contacts_initiator")..""..i18n("contacts_page.server_contacts_receiver").."
    "..i18n("contacts_page.no_client_contacts_so_far").."\n") print("\n") -- TOFIX VLAN (We need to remove the host vlan and add the client vlan) -- Client sortTable = {} for k,v in pairs(host["contacts"]["client"]) do sortTable[v]=k end num = 0 max_num = 64 -- Do not create huge maps for _v,k in pairsByKeys(sortTable, rev) do if(num >= max_num) then break end num = num + 1 name = interface.getHostInfo(k) -- TOFIX VLAN (We need to remove the host vlan and add the client vlan) v = host["contacts"]["client"][k] info = interface.getHostInfo(k) if(info ~= nil) then if(info["name"] ~= nil) then n = info["name"] else n = getResolvedAddress(hostkey2hostinfo(info["ip"])) end url = ""..n.."" else url = k end if(info ~= nil) then url = url .. getFlag(info["country"]).." " end -- print(v.."
    ") print("\n") end print("
    "..i18n("contacts_page.server_address")..""..i18n("contacts_page.contacts").."
    "..url.."" .. formatValue(v) .. "
    "..i18n("contacts_page.no_server_contacts_so_far").."\n") print("\n") -- Server sortTable = {} for k,v in pairs(host["contacts"]["server"]) do sortTable[v]=k end for _v,k in pairsByKeys(sortTable, rev) do v = host["contacts"]["server"][k] info = interface.getHostInfo(k) if(info ~= nil) then if(info["name"] ~= nil) then n = info["name"] else n = getResolvedAddress(hostkey2hostinfo(info["ip"])) end url = ""..n.."" else url = k end if(info ~= nil) then url = url ..getFlag(info["country"]).." " end print("\n") end print("
    "..i18n("contacts_page.client_address")..""..i18n("contacts_page.contacts").."
    "..url.."" .. formatValue(v) .. "
    \n") else print(i18n("contacts_page.no_contacts_message")) end elseif(page == "alerts") then printAlertTables("host", hostkey, "host_details.lua", {ifid=ifId, host=hostkey}, host_name, "host", {host_ip=host_ip, host_vlan=host_vlan, remote_host = (not host["localhost"]), enable_label = i18n("show_alerts.trigger_host_alert_descr", {host = host_name})}) elseif (page == "quotas" and ntop.isEnterprise() and host_pool_id ~= host_pools_utils.DEFAULT_POOL_ID and ifstats.inline) then local page_params = {ifid=ifId, pool=host_pool_id, host=hostkey, page=page} host_pools_utils.printQuotas(host_pool_id, host, page_params) elseif (page == "config") then if(not isAdministrator()) then return end local top_hiddens = ntop.getMembersCache(getHideFromTopSet(ifId) or {}) local is_top_hidden = swapKeysValues(top_hiddens)[hostkey_compact] ~= nil local host_key = hostinfo2hostkey(host_info, nil, true --[[show vlan]]) if _SERVER["REQUEST_METHOD"] == "POST" then if(ifstats.inline and (host.localhost or host.systemhost)) then local drop_host_traffic = _POST["drop_host_traffic"] local host_key = hostinfo2hostkey(host_info) if(drop_host_traffic ~= "1") then ntop.delHashCache("ntopng.prefs.drop_host_traffic", host_key) else ntop.setHashCache("ntopng.prefs.drop_host_traffic", host_key, "true") end interface.updateHostTrafficPolicy(host_info["host"], host_vlan) end local new_top_hidden = (_POST["top_hidden"] == "1") if new_top_hidden ~= is_top_hidden then local set_name = getHideFromTopSet(ifId) if new_top_hidden then ntop.setMembersCache(set_name, hostkey_compact) else ntop.delMembersCache(set_name, hostkey_compact) end is_top_hidden = new_top_hidden interface.reloadHideFromTop() end if _POST["mud_recording"] then mud_utils.setHostMUDRecordingPref(ifId, host_info.host, _POST["mud_recording"]) interface.reloadHostPrefs(host_info.host) end if _POST["action"] == "delete_mud" then mud_utils.deleteHostMUD(ifId, host_info.host) end end print[[
    ]] print[[]] print[[]] print[[
    ]] print[[
    ]] printPoolChangeDropdown(ifId, host_pool_id, have_nedge) local top_hidden_checked = ternary(is_top_hidden, "checked", "") print [[]] if(host["localhost"] and ((host_vlan == nil) or (host_vlan == 0))) then local mud_recording_pref = mud_utils.getHostMUDRecordingPref(ifId, host_info.host, _POST["mud_recording"]) print [[]] end if(ifstats.inline and (host.localhost or host.systemhost)) then -- Traffic policy print("') print('') print('') end print[[
    ]] print(i18n("host_config.host_alias")) print[[ ]] print [[
    ]] print(i18n("host_config.hide_from_top")) print[[
    ]] print(i18n("host_config.mud_recording")) print[[ ]] if mud_utils.hasRecordedMUD(ifId, host_info.host) then print(" ") print("") end print[[
    " .. i18n("host_config.host_traffic_policy") .. "") if(host["localhost"] == true) then local host_key = hostinfo2hostkey(host_info) drop_traffic = ntop.getHashCache("ntopng.prefs.drop_host_traffic", host_key) if(drop_traffic == "true") then drop_traffic_checked = 'checked="checked"' drop_traffic_value = "false" -- Opposite else drop_traffic_checked = "" drop_traffic_value = "true" -- Opposite end print([[
    ]]) print(' '..i18n("host_config.drop_all_host_traffic")..'') print([[]]) print([[
    ]]) end print[[]] print(i18n("host_config.modify_host_pool_policy_btn")) print[[]] else print[[/lua/pro/nedge/admin/nf_edit_user.lua]] print(ternary(host_pool_id == host_pools_utils.DEFAULT_POOL_ID, "", "?username=" .. host_pools_utils.poolIdToUsername(host_pool_id))) print[[">]] print(i18n("host_config.modify_host_pool_policy_btn")) print[[]] end print('


    ]] elseif(page == "historical") then host_url = "host="..host_ip host_key = host_ip if(host_vlan and (host_vlan > 0)) then host_url = host_url.."&vlan="..host_vlan host_key = host_key.."@"..host_vlan end local schema = _GET["ts_schema"] or "host:traffic" local selected_epoch = _GET["epoch"] or "" local tags = { ifid = ifId, host = host_key, protocol = _GET["protocol"], category = _GET["category"], l4proto = _GET["l4proto"], } local url = ntop.getHttpPrefix()..'/lua/host_details.lua?ifid='..ifId..'&'..host_url..'&page=historical' drawGraphs(ifId, schema, tags, _GET["zoom"], url, selected_epoch, { top_protocols = "top:host:ndpi", top_categories = "top:host:ndpi_categories", l4_protocols = "host:l4protos", show_historical = true, tskey = tskey, timeseries = table.merge({ {schema="host:traffic", label=i18n("traffic")}, {schema="host:score", label=i18n("score"), enterprise_only=true}, {schema="host:active_flows", label=i18n("graphs.active_flows")}, {schema="host:total_flows", label=i18n("db_explorer.total_flows")}, {schema="host:misbehaving_flows", label=i18n("graphs.total_misbehaving_flows")}, {schema="host:unreachable_flows", label=i18n("graphs.total_unreachable_flows")}, {schema="host:contacts", label=i18n("graphs.active_host_contacts")}, {schema="host:total_alerts", label=i18n("details.alerts")}, {schema="host:engaged_alerts", label=i18n("show_alerts.engaged_alerts")}, {schema="host:total_flow_alerts", label=i18n("show_alerts.flow_alerts")}, {schema="host:host_unreachable_flows", label=i18n("graphs.host_unreachable_flows")}, {schema="host:dns_qry_sent_rsp_rcvd", label=i18n("graphs.dns_qry_sent_rsp_rcvd")}, {schema="host:dns_qry_rcvd_rsp_sent", label=i18n("graphs.dns_qry_rcvd_rsp_sent")}, {schema="host:udp_pkts", label=i18n("graphs.udp_packets")}, {schema="host:tcp_rx_stats", label=i18n("graphs.tcp_rx_stats")}, {schema="host:tcp_tx_stats", label=i18n("graphs.tcp_tx_stats")}, {schema="host:echo_reply_packets", label=i18n("graphs.echo_reply_packets")}, {schema="host:echo_packets", label=i18n("graphs.echo_request_packets")}, {schema="host:tcp_packets", label=i18n("graphs.tcp_packets")}, {schema="host:udp_sent_unicast", label=i18n("graphs.udp_sent_unicast_vs_non_unicast")}, {schema="host:1d_delta_traffic_volume", label="1 Day Traffic Delta"}, -- TODO localize {schema="host:1d_delta_flows", label="1 Day Active Flows Delta"}, -- TODO localize {schema="host:1d_delta_contacts", label="1 Day Active Host Contacts Delta"}, -- TODO localize }, getDeviceCommonTimeseries()), device_timeseries_mac = host["mac"], }) elseif(page == "traffic_report") then dofile(dirs.installdir .. "/pro/scripts/lua/enterprise/traffic_report.lua") end end if(not only_historical) and (host ~= nil) then print[[]] print [[ ]] end dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")