1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
|
--
-- (C) 2013-16 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
require "json"
local top_talkers_intf = {}
if(ntop.isPro()) then
package.path = dirs.installdir .. "/pro/scripts/lua/modules/top_scripts/?.lua;" .. package.path
local new = require("top_aggregate")
if(type(new) ~= "table") then new = {} end
-- Add pro methods to local method table
for k,v in pairs(new) do
top_talkers_intf[k] = v
end
end
local function getTopTalkers(ifid, ifname)
return getCurrentTopTalkers(ifid, ifname, nil, nil, true, nil, nil,
top_talkers_intf.uniqueKey)
end
local function getTopTalkersBy(ifid, ifname, filter_col, filter_val)
return getCurrentTopTalkers(ifid, ifname, filter_col, filter_val, true, nil, nil,
top_talkers_intf.uniqueKey)
end
local function getTopTalkersClean(ifid, ifname, param)
top = getCurrentTopTalkers(ifid, ifname, nil, nil, false, param, true,
top_talkers_intf.uniqueKey)
section_beginning = string.find(top, '%[')
if(section_beginning == nil) then
return("[ ]\n")
else
return(string.sub(top, section_beginning))
end
end
local function printTopTalkersTable(tbl)
local rsp = "{\n"
for i,v in pairs(tbl) do
local outouterlooped = 0
for dk,dv in pairs(v) do
rsp = rsp..'"'..dk..'": [\n'
local keys = getKeys(dv, "value")
local outerlooped = 0
for tv,tk in pairsByKeys(keys, rev) do
rv = dv[tk]
rsp = rsp.."{ "
local looped = 0
for k,v in pairs(rv) do
rsp = rsp..'"'..k..'": '
if(k == "value") then
rsp = rsp..tostring(v)
else
rsp = rsp..'"'..v..'"'
end
rsp = rsp..", "
looped = looped + 1
end
if(looped > 0) then
rsp = string.sub(rsp, 1, -3)
end
rsp = rsp.."},\n"
outerlooped = outerlooped + 1
end
if(outerlooped > 0) then
rsp = string.sub(rsp, 1, -3)
end
rsp = rsp.."],\n"
outouterlooped = outouterlooped + 1
end
if(outouterlooped > 0) then
rsp= string.sub(rsp, 1, -3)
end
end
rsp = rsp.."\n}"
return rsp
end
local function topTalkersSectionInTableOP(tblarray, arithOp)
local ret = {}
local outer_cnt = 1
local num_glob = 1
for _,tbl in pairs(tblarray) do
for _,outer in pairs(tbl) do
if(ret[outer_cnt] == nil) then ret[outer_cnt] = {} end
for key, value in pairs(outer) do
for _,record in pairs(value) do
local found = false
if(ret[outer_cnt][key] == nil) then ret[outer_cnt][key] = {} end
for _,el in pairs(ret[outer_cnt][key]) do
if(found == false and el["address"] == record["address"]) then
el["value"] = arithOp(el["value"], record["value"])
found = true
end
end
if(found == false) then
ret[outer_cnt][key][num_glob] = record
num_glob = num_glob + 1
end
end
end
end
end
return ret
end
local function getTopTalkersFromJSONDirection(table, wantedDir, add_vlan)
local elements = ""
-- For each VLAN, get hosts and concatenate them
for i,vlan in pairs(table["vlan"]) do
local vlanid = vlan["label"]
local vlanname = vlan["name"]
-- XXX hosts is an array of (senders, receivers) pairs?
for i2,hostpair in pairs(vlan[top_talkers_intf.JSONkey]) do
-- hostpair is { "senders": [...], "receivers": [...] }
for k2,direction in pairs(hostpair) do
-- direction is "senders": [...] or "receivers": [...]
if(k2 ~= wantedDir) then goto continue end
-- scan hosts
for i2,host in pairs(direction) do
-- host is { "label": ..., "value": ..., "url": ... }
elements = elements.."{ "
local n_el = 0
for k3,v3 in pairs(host) do
elements = elements..'"'..k3..'": '
if(k3 == "value") then
elements = elements..tostring(v3)
else
elements = elements..'"'..v3..'"'
end
elements = elements..", "
n_el = n_el + 1
end
if(add_vlan ~= nil) then
elements = elements..'"vlanm": "'..vlanname..'", '
elements = elements..'"vlan": "'..vlanid..'", '
end
if(n_el ~= 0) then
elements = string.sub(elements, 1, -3)
end
elements = elements.." },\n"
end
::continue::
end
end
end
return elements
end
local function printTopTalkersFromTable(table, add_vlan)
if(table == nil or table["vlan"] == nil) then return "[ ]\n" end
local elements = "{\n"
elements = elements..'"senders": [\n'
local result = getTopTalkersFromJSONDirection(table, "senders", add_vlan)
if(result ~= "") then
result = string.sub(result, 1, -3) --remove comma
end
elements = elements..result
elements = elements.."],\n"
elements = elements..'"receivers": [\n'
result = getTopTalkersFromJSONDirection(table, "receivers", add_vlan)
if(result ~= "") then
result = string.sub(result, 1, -3) --remove comma
end
elements = elements..result
elements = elements.."]\n"
elements = elements.."}\n"
return elements
end
local function getTopTalkersFromJSON(content, add_vlan)
if(content == nil) then return("[ ]\n") end
local table = parseJSON(content)
local rsp = printTopTalkersFromTable(table, add_vlan)
if(rsp == nil or rsp == "") then return "[ ]\n" end
return rsp
end
local function getHistoricalTopTalkers(ifid, ifname, epoch, add_vlan)
if(epoch == nil) then
return("[ ]\n")
end
res = ntop.getMinuteSampling(ifid, tonumber(epoch))
return getTopTalkersFromJSON(res, add_vlan)
end
local function getHistoricalTopTalkersInInterval(ifid, ifname, epoch_start, epoch_end, add_vlan)
-- retrieves Aggregated top Talkers value from sqlite
local json = require ("dkjson")
if epoch_start == nil or epoch_end == nil or epoch_start == "" or epoch_end == "" then
return json.encode({}, nil)
end
local query = ntop.getMinuteSamplingsInterval(ifid, tonumber(epoch_start), tonumber(epoch_end))
-- sum up the selected 1-minute top talker statistics to have an aggregated 'top'
-- please keep in mind that this is an approximation of the real top talkers
-- the resulting table will be like the following
--[[
table
senders table
senders.216.58.210.238 number 7743
senders.173.194.112.169 number 2586
...
receivers table
receivers.216.58.210.238 number 5281
receivers.173.194.112.169 number 3093
...
--]]
local res = {["senders"] = {}, ["receivers"] = {}}
for record,_ in pairs(query) do
record = parseJSON(record)
if not record or not next(record) or not record["vlan"] then goto next_record end
-- tprint(record)
for _, vlan in pairs(record["vlan"]) do
local vlanid = vlan["label"]
local vlanname = vlan["name"]
-- TODO: handle vlans
if not vlan["hosts"] then goto next_vlan end
for _, host_pair in pairs(vlan["hosts"]) do
for direction, top_hosts in pairs(host_pair) do
for _, host in pairs(top_hosts) do
local label = host["address"]
local traffic = tonumber(host["value"])
if label == nil then label = "" end
if traffic == nil then traffic = 0 end
if res[direction][label] == nil then
res[direction][label] = traffic
else
res[direction][label] = res[direction][label] + traffic
end
end
end
end
::next_vlan::
end
::next_record::
end
-- tprint(res)
-- reformat the output so that it becomes easier to parse
local pretty_res = {}
for direction, hosts in pairs(res) do
local t = {}
for addr, traffic in pairs(hosts) do
table.insert(pretty_res, {["addr"] = addr, ["bytes"] = traffic, ["direction"] = direction})
end
end
res = pretty_res
return res
end
top_talkers_intf.name = "Top Talkers"
top_talkers_intf.infoScript = "host_details.lua"
top_talkers_intf.infoScriptKey = "host"
top_talkers_intf.key = "host"
top_talkers_intf.JSONkey = "hosts"
top_talkers_intf.uniqueKey = "top_talkers"
top_talkers_intf.getTop = getTopTalkers
top_talkers_intf.getTopBy = getTopTalkersBy
top_talkers_intf.getTopClean = getTopTalkersClean
top_talkers_intf.getTopFromJSON = getTopTalkersFromJSON
top_talkers_intf.printTopTable = printTopTalkersTable
top_talkers_intf.getHistoricalTop = getHistoricalTopTalkers
top_talkers_intf.getHistoricalTopInInterval = getHistoricalTopTalkersInInterval
top_talkers_intf.topSectionInTableOp = topTalkersSectionInTableOP
top_talkers_intf.numLevels = 2
return top_talkers_intf
|