mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-02 17:00:10 +00:00
Initial import from SVN
This commit is contained in:
parent
1601f6bbf2
commit
730d76b9f5
1612 changed files with 715104 additions and 0 deletions
551
scripts/lua/hosts_interaction.lua
Normal file
551
scripts/lua/hosts_interaction.lua
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
--
|
||||
-- (C) 2013-15 - ntop.org
|
||||
--
|
||||
|
||||
dirs = ntop.getDirs()
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
require "lua_utils"
|
||||
|
||||
-- host_info = url2hostinfo(_GET)
|
||||
|
||||
|
||||
if(host_ip == nil) then
|
||||
host_info = url2hostinfo(_GET)
|
||||
else
|
||||
-- print("host_ip:"..host_ip.."<br>")
|
||||
host_info = {}
|
||||
host_info = hostkey2hostinfo(host_ip)
|
||||
end
|
||||
|
||||
if(mode == nil) then
|
||||
mode = _GET["mode"]
|
||||
end
|
||||
|
||||
if(host_name == nil) then
|
||||
host_name = _GET["name"]
|
||||
end
|
||||
|
||||
if(mode ~= "embed") then
|
||||
sendHTTPHeader('text/html; charset=iso-8859-1')
|
||||
ntop.dumpFile(dirs.installdir .. "/httpdocs/inc/header.inc")
|
||||
active_page = "hosts"
|
||||
dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")
|
||||
end
|
||||
|
||||
num_top_hosts = 10
|
||||
|
||||
if(host_info["host"] ~= nil) then
|
||||
num = 1
|
||||
else
|
||||
interface.select(ifname)
|
||||
hosts_stats = interface.getHostsInfo()
|
||||
num = 0
|
||||
for key, value in pairs(hosts_stats) do
|
||||
num = num + 1
|
||||
end
|
||||
end
|
||||
|
||||
if(num > 0) then
|
||||
if(mode ~= "embed") then
|
||||
if(host_info["host"] == nil) then
|
||||
print("<hr><h2>Top Hosts Interaction</H2>")
|
||||
else
|
||||
name = host_name
|
||||
if(name == nil) then name = host_info["host"] end
|
||||
print("<hr><h2>"..name.." Interactions</H2><i class=\"fa fa-chevron-left fa-lg\"></i><small><A onClick=\"javascript:history.back()\">Back</A></small>")
|
||||
end
|
||||
end
|
||||
|
||||
print [[
|
||||
<style>
|
||||
svg {
|
||||
font: 10px sans-serif;
|
||||
}
|
||||
|
||||
.axis path, .axis line {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
sup, sub {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
q:before, blockquote:before {
|
||||
content: "?";
|
||||
}
|
||||
|
||||
q:after, blockquote:after {
|
||||
content: "?";
|
||||
}
|
||||
|
||||
blockquote:before {
|
||||
position: absolute;
|
||||
left: 2em;
|
||||
}
|
||||
|
||||
blockquote:after {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
</style>
|
||||
<style>
|
||||
#chart {
|
||||
height:
|
||||
]]
|
||||
|
||||
if(mode ~= "embed") then
|
||||
print("600")
|
||||
elseif(interface.getNumAggregatedHosts() > 0) then
|
||||
print("400")
|
||||
else
|
||||
print("300")
|
||||
end
|
||||
|
||||
print [[
|
||||
px;
|
||||
}
|
||||
.node rect {
|
||||
cursor: move;
|
||||
fill-opacity: .9;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
.node text {
|
||||
pointer-events: none;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
}
|
||||
.link {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
stroke-opacity: .2;
|
||||
}
|
||||
.link:hover {
|
||||
stroke-opacity: .5;
|
||||
}
|
||||
|
||||
circle.node-dot {
|
||||
fill: DarkSlateGray;
|
||||
stroke: SlateGray;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
|
||||
path.link {
|
||||
fill: none;
|
||||
stroke: SlateGray;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
marker#defaultMarker {
|
||||
fill: SlateGray;
|
||||
}
|
||||
|
||||
path.link.defaultMarker {
|
||||
stroke: SlateGray;
|
||||
}
|
||||
|
||||
circle {
|
||||
fill: #ccc;
|
||||
stroke: #333;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
text {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
text.shadow {
|
||||
stroke: #fff;
|
||||
stroke-width: 3px;
|
||||
stroke-opacity: .8;
|
||||
}
|
||||
|
||||
</style><style>path.link.proposer{stroke:red;}
|
||||
marker#bus{fill:blue;}
|
||||
marker#manual{fill:red;}
|
||||
path.link.direct{stroke:green; }
|
||||
path.link.bus{stroke:blue;}
|
||||
path.link.manual{stroke:red;stroke-dasharray: 0, 2 1;} </style><script>
|
||||
/**
|
||||
* do the force vizualization
|
||||
* @param {string} divName name of the div to hold the tree
|
||||
* @param {object} inData the source data
|
||||
*/
|
||||
function doTheTreeViz(divName, inData) {
|
||||
// tweak the options
|
||||
var options = $.extend({
|
||||
stackHeight : 12,
|
||||
radius : 5,
|
||||
fontSize : 12,
|
||||
labelFontSize : 8,
|
||||
nodeLabel : null,
|
||||
markerWidth : 0,
|
||||
markerHeight : 0,
|
||||
width : $(divName).outerWidth(),
|
||||
gap : 1.5,
|
||||
nodeResize : "",
|
||||
linkDistance : 30,
|
||||
charge : -120,
|
||||
styleColumn : null,
|
||||
styles : null,
|
||||
linkName : null,
|
||||
height : $(divName).outerHeight()
|
||||
}, inData.d3.options);
|
||||
// set up the parameters
|
||||
options.gap = options.gap * options.radius;
|
||||
var width = options.width;
|
||||
var height = options.height;
|
||||
var data = inData.d3.data;
|
||||
var nodes = data.nodes;
|
||||
var links = data.links;
|
||||
var color = d3.scale.category10();
|
||||
|
||||
color["local"] = "#aec7e8";
|
||||
color["remote"] = "#bcbd22";
|
||||
color["sun"] = "#fd8d3c";
|
||||
color["aggregation"] = "#008d3c";
|
||||
|
||||
var force = d3.layout.force().nodes(nodes).links(links).size([width, height]).linkDistance(options.linkDistance).charge(options.charge).on("tick", tick).start();
|
||||
|
||||
var main = d3.select(divName).append("svg:svg").attr("width", width).attr("height", height);
|
||||
|
||||
var svg = main.append('svg:g')
|
||||
.call(d3.behavior.zoom().on("zoom", rescale))
|
||||
.on("dblclick.zoom", null);
|
||||
|
||||
function rescale() {
|
||||
trans=d3.event.translate;
|
||||
scale=d3.event.scale;
|
||||
|
||||
svg.attr("transform",
|
||||
"translate(" + trans + ")"
|
||||
+ " scale(" + scale + ")");
|
||||
}
|
||||
|
||||
// get list of unique values in stylecolumn
|
||||
linkStyles = [];
|
||||
if (options.styleColumn) {
|
||||
var x;
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
if (linkStyles.indexOf( x = links[i][options.styleColumn].toLowerCase()) == -1)
|
||||
linkStyles.push(x);
|
||||
}
|
||||
} else
|
||||
linkStyles[0] = "defaultMarker";
|
||||
|
||||
// do we need a marker?
|
||||
|
||||
if (options.markerWidth) {
|
||||
svg.append("svg:defs").selectAll("marker").data(linkStyles).enter().append("svg:marker").attr("id", String).attr("viewBox", "0 -5 10 10").attr("refX", 15).attr("refY", -1.5).attr("markerWidth", options.markerWidth).attr("markerHeight", options.markerHeight).attr("orient", "auto").append("svg:path").attr("d", "M0,-5L10,0L0,5");
|
||||
}
|
||||
|
||||
var path = svg.append("svg:g").selectAll("path").data(force.links()).enter().append("svg:path").attr("class", function(d) {
|
||||
return "link " + (options.styleColumn ? d[options.styleColumn].toLowerCase() : linkStyles[0]);
|
||||
}).attr("marker-end", function(d) {
|
||||
return "url(#" + (options.styleColumn ? d[options.styleColumn].toLowerCase() : linkStyles[0] ) + ")";
|
||||
});
|
||||
|
||||
var circle = svg.append("svg:g").selectAll("circle")
|
||||
.data(force.nodes())
|
||||
.enter()
|
||||
.append("svg:circle")
|
||||
.attr("r", function(d) {
|
||||
return getRadius(d);
|
||||
})
|
||||
.style("fill", function(d) {
|
||||
return color[d.group];
|
||||
})
|
||||
.call(force.drag)
|
||||
//.on("mousedown",
|
||||
// function(d) {
|
||||
// disable zoom
|
||||
// svg.call(d3.behavior.zoom().on("zoom"), null);
|
||||
// })
|
||||
//.on("mouseup",
|
||||
// function(d) {
|
||||
// enable zoom
|
||||
// svg.call(d3.behavior.zoom().on("zoom"), rescale);
|
||||
// })
|
||||
;
|
||||
|
||||
if (options.nodeLabel) {
|
||||
circle.append("title").html(function(d) {
|
||||
return d[options.nodeLabel];
|
||||
});
|
||||
}
|
||||
|
||||
circle.on("dblclick", function(d) { if(d.link.length > 0) { window.location.href = d.link; } } );
|
||||
|
||||
if (options.linkName) {
|
||||
path.append("title").text(function(d) {
|
||||
return d[options.linkName];
|
||||
});
|
||||
}
|
||||
var text = svg.append("svg:g").selectAll("g").data(force.nodes()).enter().append("svg:g");
|
||||
|
||||
// A copy of the text with a thick white stroke for legibility.
|
||||
text.append("svg:text").attr("x", options.labelFontSize).attr("y", ".31em").attr("class", "shadow").text(function(d) {
|
||||
return d[options.nodeLabel];
|
||||
});
|
||||
|
||||
text.append("svg:text").attr("x", options.labelFontSize).attr("y", ".31em").text(function(d) {
|
||||
return d[options.nodeLabel];
|
||||
});
|
||||
function getRadius(d) {
|
||||
return options.radius * (options.nodeResize ? Math.sqrt(d[options.nodeResize]) / Math.PI : 1);
|
||||
}
|
||||
|
||||
// Use elliptical arc path segments to doubly-encode directionality.
|
||||
function tick() {
|
||||
path.attr("d", function(d) {
|
||||
var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math.sqrt(dx * dx + dy * dy);
|
||||
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
|
||||
});
|
||||
|
||||
circle.attr("transform", function(d) {
|
||||
return "translate(" + d.x + "," + d.y + ")";
|
||||
});
|
||||
|
||||
text.attr("transform", function(d) {
|
||||
return "translate(" + d.x + "," + d.y + ")";
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
</script><script>
|
||||
|
||||
window['ntopData'] = {"d3":{"options":
|
||||
{"radius":"16","fontSize":"30","labelFontSize":"30","charge":"-2000","nodeResize":"count","nodeLabel":"label","markerHeight":"6","markerWidth":"6","styleColumn":"styleColumn","linkName":"group"},
|
||||
"data":{"links":[
|
||||
|
||||
]]
|
||||
|
||||
-- Nodes
|
||||
|
||||
interface.select(ifname)
|
||||
|
||||
if(host_info["host"] == nil) then
|
||||
hosts_stats = getTopInterfaceHosts(num_top_hosts, true)
|
||||
else
|
||||
hosts_stats = {}
|
||||
hosts_stats[host_info["host"]] = interface.getHostInfo(host_info["host"],host_info["vlan"])
|
||||
end
|
||||
|
||||
hosts_id = {}
|
||||
ids = {}
|
||||
|
||||
num = 0
|
||||
links = 0
|
||||
local host
|
||||
|
||||
for key, values in pairs(hosts_stats) do
|
||||
|
||||
host = interface.getHostInfo(key)
|
||||
|
||||
if(host ~= nil) then
|
||||
-- init host
|
||||
if(hosts_id[key] == nil) then
|
||||
hosts_id[key] = { }
|
||||
hosts_id[key]['count'] = 0
|
||||
hosts_id[key]['id'] = num
|
||||
ids[num] = key
|
||||
key_id = num
|
||||
num = num + 1
|
||||
else
|
||||
key_id = hosts_id[key]['id']
|
||||
end
|
||||
|
||||
-- client contacts
|
||||
if(host["contacts"]["client"] ~= nil) then
|
||||
for k,v in pairs(host["contacts"]["client"]) do
|
||||
|
||||
if(hosts_id[k] == nil) then
|
||||
hosts_id[k] = { }
|
||||
hosts_id[k]['count'] = 0
|
||||
hosts_id[k]['id'] = num
|
||||
ids[num] = k
|
||||
peer_id = num
|
||||
num = num + 1
|
||||
else
|
||||
peer_id = hosts_id[k]['id']
|
||||
end
|
||||
|
||||
hosts_id[key]['count'] = hosts_id[key]['count'] + v
|
||||
if(links > 0) then print(",") end
|
||||
print('\n{"source":'..key_id..',"target":'..peer_id..',"depth":6,"count":'..v..',"styleColumn":"client","linkName":""}')
|
||||
links = links + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- server contacts
|
||||
if(host["contacts"]["server"] ~= nil) then
|
||||
for k,v in pairs(host["contacts"]["server"]) do
|
||||
|
||||
if(hosts_id[k] == nil) then
|
||||
hosts_id[k] = { }
|
||||
hosts_id[k]['count'] = 0
|
||||
hosts_id[k]['id'] = num
|
||||
ids[num] = k
|
||||
peer_id = num
|
||||
num = num + 1
|
||||
else
|
||||
peer_id = hosts_id[k]['id']
|
||||
end
|
||||
|
||||
hosts_id[key]['count'] = hosts_id[key]['count'] + v
|
||||
if(links > 0) then print(",") end
|
||||
print('\n{"source":'..key_id..',"target":'..peer_id..',"depth":6,"count":'..v..',"styleColumn":"server"}')
|
||||
links = links + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
aggregation_ids = {}
|
||||
|
||||
if(host_info["host"] ~= nil) then
|
||||
aggregations = interface.getAggregationsForHost(host_info["host"])
|
||||
else
|
||||
aggregations = {}
|
||||
end
|
||||
|
||||
for name,num_contacts in pairs(aggregations) do
|
||||
aggregation_ids[name] = num
|
||||
|
||||
hosts_id[name] = { }
|
||||
hosts_id[name]['count'] = num_contacts
|
||||
hosts_id[name]['id'] = num
|
||||
ids[num] = name
|
||||
|
||||
if(links > 0) then print(",") end
|
||||
print('\n{"source":'..num..',"target": 0,"depth":6,"count":'..num_contacts..',"styleColumn":"aggregation"}')
|
||||
links = links + 1
|
||||
|
||||
num = num + 1
|
||||
end
|
||||
|
||||
tot_hosts = num
|
||||
|
||||
print [[
|
||||
|
||||
],"nodes":[
|
||||
]]
|
||||
|
||||
-- Nodes
|
||||
|
||||
min_size = 5
|
||||
maxval = 0
|
||||
for k,v in pairs(hosts_id) do
|
||||
if(v['count'] > maxval) then maxval = v['count'] end
|
||||
end
|
||||
|
||||
num = 0
|
||||
for i=0,tot_hosts-1 do
|
||||
k = ids[i]
|
||||
v = hosts_id[k]
|
||||
k_info = hostkey2hostinfo(k)
|
||||
|
||||
target_host = interface.getHostInfo(k)
|
||||
|
||||
if(target_host ~= nil) then
|
||||
|
||||
name = target_host["name"]
|
||||
if(name ~= nil) then
|
||||
name = name
|
||||
else
|
||||
name = ntop.getResolvedAddress(k_info["host"])
|
||||
target_host["name"] = name
|
||||
end
|
||||
|
||||
if(target_host['localhost'] ~= nil) then label = "local" else label = "remote" end
|
||||
|
||||
else
|
||||
|
||||
name = k
|
||||
if(aggregations[k] ~= nil) then label = "aggregation" else label = "remote" end
|
||||
|
||||
end
|
||||
|
||||
if ((host_info["host"] ~= nil) and (host_info["host"] == k_info["host"])) then label = "sun" end
|
||||
-- f(name == k) then name = ntop.getResolvedAddress(k) end
|
||||
if(name == nil) then name = k end
|
||||
|
||||
if(maxval == 0) then
|
||||
tot = maxval
|
||||
else
|
||||
tot = math.floor(0.5+(v['count']*100)/maxval)
|
||||
if(tot < min_size) then tot = min_size end
|
||||
end
|
||||
|
||||
if(num > 0) then print(",") end
|
||||
print('\n{"name":"'.. name ..'","count":'.. tot ..',"group":"' .. label .. '","linkCount": '.. tot .. ',"label":"'.. name..'"')
|
||||
|
||||
if(target_host ~= nil) then
|
||||
-- Host still in memory
|
||||
if((host_info["host"] == nil) or (k_info["host"] ~= host_info["host"])) then
|
||||
print(', "link": "'..ntop.getHttpPrefix()..'/lua/hosts_interaction.lua?"}')
|
||||
else
|
||||
print(', "link": "'..ntop.getHttpPrefix()..'/lua/host_details.lua?host='.. k.. '"}')
|
||||
end
|
||||
else
|
||||
-- print('->>'..k..'<<-\n')
|
||||
if(aggregations[k] ~= nil) then
|
||||
print(', "link": "'..ntop.getHttpPrefix()..'/lua/aggregated_host_details.lua?host='.. k .. '"}')
|
||||
else
|
||||
-- Host purged ?
|
||||
print(', "link": ""}')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
num = num + 1
|
||||
end
|
||||
|
||||
if ((num == 0) and (host_info["host"] ~= nil)) then
|
||||
tot = 1
|
||||
label = ""
|
||||
name = host_info["host"]
|
||||
print('\n{"name":"'.. name ..'","count":'.. tot ..',"group":"' .. label .. '","linkCount": '.. tot .. ',"label":"'.. name..'", "link": "'..ntop.getHttpPrefix()..'/lua/host_details.lua?host='.. hostinfo2hostkey(host_info).. '"}')
|
||||
end
|
||||
|
||||
print [[
|
||||
|
||||
]
|
||||
}}};
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div id="chart"></div>
|
||||
|
||||
<p> <p><small><b>NOTE</b></small>
|
||||
<ol>
|
||||
]]
|
||||
|
||||
if(host_info["host"] ~= nil) then
|
||||
print('<li><small>This map is centered on host <font color="#fd8d3c">'.. hostinfo2hostkey(host_info))
|
||||
if(host_name ~= nil) then print('('.. host_name .. ')') end
|
||||
print('</font>. Clicking on this host you will visualize its details.</small></li>\n')
|
||||
else
|
||||
print('<li><small>This map depicts the interactions of the top '.. num_top_hosts .. ' hosts.</small></li>\n')
|
||||
end
|
||||
print('<li><small>Color map: <font color=#aec7e8><b>local</b></font>, <font color=#bcbd22><b>remote</b></font>, <font color=#008d3c><b>aggregation</b></font>, <font color=#fd8d3c><b>focus</b></font> host.</small></li>\n')
|
||||
print [[
|
||||
<li> <small>Click is enabled only for hosts that have not been purged from memory.</small></li>
|
||||
</ol>
|
||||
|
||||
<!-- http://ramblings.mcpher.com/Home/excelquirks/d3 -->
|
||||
<script type="text/javascript">
|
||||
doTheTreeViz("#chart", ntopData);
|
||||
</script>
|
||||
|
||||
]]
|
||||
else
|
||||
print("<div class=\"alert alert-danger\"><img src=".. ntop.getHttpPrefix() .. "/img/warning.png> No results found</div>")
|
||||
end
|
||||
|
||||
if(mode ~= "embed") then
|
||||
dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue