-- -- (C) 2014-21 - ntop.org -- require "lua_utils" local json = require ("dkjson") local graph_common = require "graph_common" local favourites_url = ntop.getHttpPrefix().."/lua/get_historical_favourites.lua" local flows_download_url = ntop.getHttpPrefix().."/lua/get_db_flows.lua" function commonJsUtils() print[[ function hideAll(cla){ $('.' + cla).hide(); } function showOne(cla, id){ $('.' + cla).not('#' + id).hide(); $('#' + id).show(); } function hostkey2hostid(host_key) { var info; var hostinfo = []; host_key = host_key.replace(/\:/g, "____"); host_key = host_key.replace(/\//g, "___"); host_key = host_key.replace(/\./g, "__"); info = host_key.split("@"); return(info); } /* * Returns a map of querystring parameters * * Keys of type [] will automatically be added to an array * * @param String url * @return Object parameters */ function getParams(url) { var regex = /([^=&?]+)=([^&#]*)/g, params = {}, parts, key, value; while((parts = regex.exec(url)) != null) { key = parts[1], value = parts[2]; var isArray = /\[\]$/.test(key); if(isArray) { params[key] = params[key] || []; params[key].push(value); } else { params[key] = value; } } return params; } /* adds a CSS style to replace the / in the breadcrumb */ var style = $(""); $('html > head').append(style); function buildRequestData(source_div_id){ var epoch_begin = $('#' + source_div_id).attr("epoch_begin"); var epoch_end = $('#' + source_div_id).attr("epoch_end"); var ifId = "]] print(tostring(ifId)) print [["; var host = $('#' + source_div_id).attr("host"); var peer = $('#' + source_div_id).attr("peer"); var l7_proto_id = $('#' + source_div_id).attr("l7_proto_id"); var l4_proto_id = $('#' + source_div_id).attr("l4_proto_id"); var port = $('#' + source_div_id).attr("port"); var vlan = $('#' + source_div_id).attr("vlan"); var profile = $('#' + source_div_id).attr("profile"); var res = {epoch_begin: epoch_begin, epoch_end: epoch_end}; if (typeof ifId != 'undefined') res.ifid = ifId; if (typeof host != 'undefined') res.peer1 = host; if (typeof peer != 'undefined') res.peer2 = peer; if (typeof port != 'undefined') res.port = port; if (typeof vlan != 'undefined') res.vlan = vlan; if (typeof profile != 'undefined') res.profile = profile; if (typeof l7_proto_id != 'undefined'){ res.l7_proto_id = l7_proto_id; res.l7proto = l7_proto_id; }; if (typeof l4_proto_id != 'undefined'){ res.l4_proto_id = l4_proto_id; res.l4proto = l4_proto_id; }; return res; } var zoom_vals = { ]] if graph_common.zoom_vals ~= nil then for _, zv in pairs(graph_common.zoom_vals) do print('"'..zv[1]..'": '..zv[3]..', ') end end print[[ }; function populateHistoricalDbExplorerLink(the_td, host, l7_proto) { var url_params = getParams(window.location.href); var mandatory_params = ["host", "l4proto", "port", "info", "protocol", "search"]; $.each(mandatory_params, function(_, p) { if(url_params[p] === undefined) { url_params[p] = ""; } }); if(host != '' && host !== undefined) { url_params["host"] = host; } if(l7_proto != '' && l7_proto !== undefined) { url_params["protocol"] = l7_proto; } if(url_params["zoom"]) { /* This is a chart url */ var zoom = url_params["zoom"]; var epoch = url_params["epoch"]; if(!epoch) { url_params["epoch_end"] = Math.round(new Date() / 1000); /* now */ url_params["epoch_begin"] = url_params["epoch_end"] - zoom_vals[zoom]; } else { epoch = parseInt(epoch); url_params["epoch_end"] = epoch + zoom_vals[zoom] / 2; url_params["epoch_begin"] = epoch - zoom_vals[zoom] / 2; } } the_td.html('' + the_td.text() + ''); } ]] end function historicalDownloadButtonsBar(button_id, pcap_request_data_container_div_id, ipv4_enabled, ipv6_enabled) if not ntop.isPro() then return end -- integrate only in the Pro version -- ipv4 and ipv6 download buttons can be either disabled from lua using the parameters above. -- If download buttons are not disabled explicitly from Lua, then a javascript check will disable -- them at display time to make sure no button is shown when the number of flows equals to zero local style_ipv4 = "" local style_ipv6 = "" if ipv4_enabled == false or tonumber(ipv4_enabled) == 0 then style_ipv4 = "display:none;" end if ipv6_enabled == false or tonumber(ipv6_enabled) == 0 then style_ipv6 = "display:none;" end local displacement = "7" if not interface.isPacketInterface() then displacement = "9" end print [[
]] print(i18n("db_explorer.download_flows")) print[[: ]] if(ipv4_enabled) then print [[ ]] print(i18n("ipv4")) print[[ ]] else print [[]] print(i18n("ipv6")) print[[]] end print [[

]] print(i18n("db_explorer.download_flows_limit")) print[[


]] end function printFlowsCountColumn() -- hides the flows count column when aggregated database flows are being used local col = '{title: "'..i18n("flows") local hide_count = "" col = col..'", field: "column_flows", '..hide_count..' sortable: true, css: {textAlign:\'right\'}}' return col end function historicalTopTalkersTable(ifid, epoch_begin, epoch_end, host, l7proto, l4proto, port, vlan, profile) local breadcrumb_root = "interface" local container_params = ' epoch_begin="" epoch_end="" host="" peer="" l7_proto_id="" l7_proto="" l4_proto_id="" l4_proto="" ' local host_talkers_url_params = "" local interface_talkers_url_params = "" local isv6 = isIPv6(host) interface_talkers_url_params = interface_talkers_url_params.."&epoch_begin="..epoch_begin interface_talkers_url_params = interface_talkers_url_params.."&epoch_end="..epoch_end if l7proto ~= "" and l7proto ~= nil and not string.starts(tostring(l7proto), 'all') then if not isnumber(l7proto) then local id id = interface.getnDPIProtoId(l7proto) if id ~= -1 then l7proto = id interface_talkers_url_params = interface_talkers_url_params.."&l7_proto_id="..l7proto else l7proto = "" end elseif tonumber(l7proto) ~= nil then interface_talkers_url_params = interface_talkers_url_params.."&l7_proto_id="..tonumber(l7proto) end end if l4proto ~= "" and l4proto ~= nil and tonumber(l4proto) ~= nil then interface_talkers_url_params = interface_talkers_url_params.."&l4_proto_id="..tonumber(l4proto) end if port ~= "" and port ~= nil and tonumber(port) ~= nil then interface_talkers_url_params = interface_talkers_url_params.."&port="..tonumber(port) end if vlan ~= "" and vlan ~= nil and tonumber(vlan) ~= nil then interface_talkers_url_params = interface_talkers_url_params.."&vlan="..tostring(vlan) container_params = container_params..' vlan="'..(tostring(vlan) or '')..'"' else container_params = container_params..' vlan=0 ' end if profile ~= "" and profile ~= nil then interface_talkers_url_params = interface_talkers_url_params.."&profile="..profile container_params = container_params..' profile="'..(profile or '')..'"' end if host and host ~= "" then host_talkers_url_params = interface_talkers_url_params.."&peer1="..host breadcrumb_root = "host" else host_talkers_url_params = interface_talkers_url_params end local preference = tablePreferences("historical_rows_number",_GET["perPage"]) local sort_order = getDefaultTableSortOrder("historical_stats_top_talkers") local sort_column= getDefaultTableSort("historical_stats_top_talkers") if not sort_column or sort_column == "column_" then sort_column = "column_bytes" end print[[
]] historicalDownloadButtonsBar("pcap-button-top-talkers", "historical-container", not(isv6), isv6) if allowedNetworksRestrictions() then print(""..i18n("notes").."") print("
  • "..i18n("note_flow_search_allowed_networks",{nets=ntop.getAllowedNetworks()}).."
  • ") print("
  • "..i18n("note_flow_search_allowed_networks_ipv6").."
  • ") print("
  • "..i18n("note_flow_search_allowed_networks_talkers").."
  • ") end print [[ ]] end function historicalTopApplicationsTable(ifid, epoch_begin, epoch_end, host, vlan, profile) local breadcrumb_root = "interface" local container_params = ' epoch_begin="" epoch_end="" host="" peer="" l7_proto_id="" l7_proto="" l4_proto_id="" l4_proto="" ' local top_apps_url_params="" local isv6 = isIPv6(host) top_apps_url_params = top_apps_url_params.."&epoch_begin="..epoch_begin top_apps_url_params = top_apps_url_params.."&epoch_end="..epoch_end if vlan ~= "" and vlan ~= nil and tonumber(vlan) ~= nil then top_apps_url_params = top_apps_url_params.."&vlan="..tostring(vlan) container_params = container_params..' vlan="'..(tostring(vlan) or '')..'"' else container_params = container_params..' vlan=0 ' end if profile ~= "" and profile ~= nil then top_apps_url_params = top_apps_url_params.."&profile="..profile container_params = container_params..' profile="'..(profile or '')..'"' end if host and host ~= "" then breadcrumb_root="host" end local preference = tablePreferences("historical_rows_number",_GET["perPage"]) local sort_order = getDefaultTableSortOrder("historical_stats_top_applications") local sort_column= getDefaultTableSort("historical_stats_top_applications") if not sort_column or sort_column == "column_" then sort_column = "column_bytes" end print[[
    ]] historicalDownloadButtonsBar("pcap-button-top-protocols", "historical-apps-container", not(isv6), isv6) if allowedNetworksRestrictions() then print(""..i18n("notes").."") print("
  • "..i18n("note_flow_search_allowed_networks",{nets=ntop.getAllowedNetworks()}).."
  • ") print("
  • "..i18n("note_flow_search_allowed_networks_ipv6").."
  • ") print("
  • "..i18n("note_flow_search_allowed_networks_applications").."
  • ") end print [[ ]] end -- ########################################## function historicalFlowsTab(ifId, host, epoch_begin, epoch_end, l7proto, l4proto, port, info, vlan, profile) -- prepare some attributes that will be attached to divs local div_data = "" if ifId ~= "" and ifId ~= nil then _GET["ifid"] = ifId div_data = div_data..' ifid="'..tostring(ifId)..'" ' end if epoch_begin ~= "" and epoch_begin ~= nil then _GET["epoch_begin"] = epoch_begin div_data = div_data..' epoch_begin="'..tostring(epoch_begin)..'" ' end if epoch_end ~= "" and epoch_end ~= nil then _GET["epoch_end"] = epoch_end div_data = div_data..' epoch_end="'..tostring(epoch_end)..'" ' end if host ~= "" and host ~= nil then _GET["host"] = host div_data = div_data..' host="'..tostring(host)..'" ' end if l7proto ~= "" and l7proto ~= nil and not string.starts(tostring(l7proto), 'all') then if not isnumber(l7proto) then local id = interface.getnDPIProtoId(l7proto) if id ~= -1 then l7proto = id else l7proto = "" end end _GET["protocol"] = l7proto div_data = div_data..' l7_proto_id="'..l7proto..'" ' end if l4proto ~= "" and l4proto ~= nil then if tonumber(l4proto) == nil then l4proto = l4_proto_to_id(l4proto) end _GET["l4proto"] = l4proto div_data = div_data..' l4_proto_id="'..l4proto..'" ' end if port ~= "" and port ~= nil then _GET["port"] = port div_data = div_data..' port="'..port..'" ' end if vlan ~= "" and vlan ~= nil then _GET["vlan"] = vlan div_data = div_data..' vlan="'..vlan..'" ' end if profile ~= "" and profile ~= nil then _GET["profile"] = profile div_data = div_data..' profile="'..profile..'" ' end print[[

    ]] print(i18n("flow_search_results")) print[[ 

      ]] print(i18n("db_explorer.query_in_progress")) print[[
    ]] print[[]] print[[
    ]] print[[
    ]] print [[
    ]] historicalDownloadButtonsBar('flows_v4', 'tab-ipv4', true, false) print[[
    ]] print [[
    ]] historicalDownloadButtonsBar('flows_v6', 'tab-ipv6', false, true ) print[[
    ]] if allowedNetworksRestrictions() then print(""..i18n("notes").."") print("
  • "..i18n("note_flow_search_allowed_networks",{nets=ntop.getAllowedNetworks()}).."
  • ") print("
  • "..i18n("note_flow_search_allowed_networks_ipv6").."
  • ") print("
  • "..i18n("note_flow_search_allowed_networks_counter").."
  • ") end print [[
    ]] print[[ ]] historicalFlowsTabTables(ifId, host, epoch_begin, epoch_end, l7proto, l4proto, port, info, vlan, profile) end -- ########################################## function historicalFlowsTabTables(ifId, host, epoch_begin, epoch_end, l7proto, l4proto, port, info, vlan, profile) local url_update = ntop.getHttpPrefix().."/lua/get_db_flows.lua?ifid="..ifId.. "&peer1="..(host or '') .. "&epoch_begin="..(epoch_begin or '').."&epoch_end="..(epoch_end or '').."&l4proto="..(l4proto or '').."&port="..(port or '').."&info="..(info or '').."&vlan="..(vlan or '').."&profile="..(profile or '') if(l7proto ~= "") then if(not(isnumber(l7proto))) then local id -- io.write(l7proto.."\n") id = interface.getnDPIProtoId(l7proto) if(id ~= -1) then l7proto = id ipv4_title = i18n("db_explorer.top_proto_ipv4_flows", {proto=l7proto}) ipv6_title = i18n("db_explorer.top_proto_ipv6_flows", {proto=l7proto}) else l7proto = "" ipv4_title = "" ipv6_title = "" end end if(l7proto ~= "") then url_update = url_update.."&l7proto="..l7proto end end if((host == "") and (l4proto == "") and (port == "")) then ipv4_title = i18n("db_explorer.top_flows_ipv4", {date_from=formatEpoch(epoch_begin), date_to=formatEpoch(epoch_end)}) ipv6_title = i18n("db_explorer.top_flows_ipv6", {date_from=formatEpoch(epoch_begin), date_to=formatEpoch(epoch_end)}) else ipv4_title = "" ipv6_title = "" end print [[ ]] end