Initial import from SVN

This commit is contained in:
Luca 2015-04-30 12:22:35 +02:00
parent 1601f6bbf2
commit 730d76b9f5
1612 changed files with 715104 additions and 0 deletions

View file

@ -0,0 +1,169 @@
--
-- (C) 2014-15-15 - ntop.org
--
-- This file contains the description of all functions
-- used to trigger host alerts
local verbose = false
j = require("dkjson")
function ndpival_bytes(json, protoname)
if((json["ndpiStats"] == nil) or (json["ndpiStats"][protoname] == nil)) then
if(verbose) then print("## ("..protoname..") Empty<br>\n") end
return(0)
else
local v = json["ndpiStats"][protoname]["bytes"]["sent"]+json["ndpiStats"][protoname]["bytes"]["rcvd"]
if(verbose) then print("## ("..protoname..") "..v.."<br>\n") end
return(v)
end
end
function proto_bytes(old, new, protoname)
return(ndpival_bytes(new, protoname)-ndpival_bytes(old, protoname))
end
-- =====================================================
function bytes(old, new) return((new["sent"]["bytes"]+new["rcvd"]["bytes"])-(old["sent"]["bytes"]+old["rcvd"]["bytes"])) end
function packets(old, new) return((new["sent"]["packets"]+new["rcvd"]["packets"])-(old["sent"]["packets"]+old["rcvd"]["packets"])) end
function dns(old, new) return(proto_bytes(old, new, "DNS")) end
function p2p(old, new) return(proto_bytes(old, new, "eDonkey")+proto_bytes(old, new, "BitTorrent")+proto_bytes(old, new, "Skype")) end
alerts_granularity = {
{ "min", "Every Minute" },
{ "5mins", "Every 5 Minutes" },
{ "hour", "Hourly" },
{ "day", "Daily" }
}
alert_functions_description = {
["bytes"] = "Bytes delta (sent + received)",
["packets"] = "Packets delta (sent + received)",
["dns"] = "DNS traffic delta bytes (sent + received)",
["p2p"] = "Peer-to-peer traffic delta bytes (sent + received)",
}
-- #################################################################
function delete_host_alert_configuration(host_ip)
for k,v in pairs(alerts_granularity) do
key = "ntopng.prefs.alerts_"..v[1]
-- print(key.."<br>\n")
ntop.delHashCache(key, host_ip)
end
end
function check_host_alert(ifname, hostname, mode, key, old_json, new_json)
if(verbose) then
print("check_host_alert("..ifname..", "..hostname..", "..mode..", "..key..")<br>\n")
print("<p>--------------------------------------------<p>\n")
print("NEW<br>"..new_json.."<br>\n")
print("<p>--------------------------------------------<p>\n")
print("OLD<br>"..old_json.."<br>\n")
print("<p>--------------------------------------------<p>\n")
end
old = j.decode(old_json, 1, nil)
new = j.decode(new_json, 1, nil)
-- str = "bytes;>;123,packets;>;12"
hkey = "ntopng.prefs.alerts_"..mode
str = ntop.getHashCache(hkey, hostname)
-- if(verbose) then ("--"..hkey.."="..str.."--<br>") end
if((str ~= nil) and (str ~= "")) then
tokens = split(str, ",")
for _,s in pairs(tokens) do
-- if(verbose) then ("<b>"..s.."</b><br>\n") end
t = string.split(s, ";")
if(t[2] == "gt") then
op = ">"
else
if(t[2] == "lt") then
op = "<"
else
op = "=="
end
end
local what = "val = "..t[1].."(old, new); if(val ".. op .. " " .. t[3] .. ") then return(true) else return(false) end"
local f = loadstring(what)
local rc = f()
if(rc) then
local alert_msg = "Threshold <b>"..t[1].."</b> crossed by host <A HREF="..ntop.getHttpPrefix().."/lua/host_details.lua?host="..key..">"..key.."</A> [".. val .." ".. op .. " " .. t[3].."]"
local alert_level = 1 -- alert_level_warning
local alert_type = 2 -- alert_threshold_exceeded
ntop.queueAlert(alert_level, alert_type, alert_msg)
if(verbose) then print("<font color=red>".. alert_msg .."</font><br>\n") end
else
if(verbose) then print("<p><font color=green><b>Threshold "..t[1].."@"..key.." not crossed</b> [value="..val.."]["..op.." "..t[3].."]</font><p>\n") end
end
end
end
end
-- #################################
function check_host_threshold(ifname, hostname, mode)
if(verbose) then print("check_host_threshold("..ifname..", "..hostname..", "..mode..")<br>\n") end
basedir = fixPath(dirs.workingdir .. "/" .. ifname .. "/json/" .. mode)
if(not(ntop.exists(basedir))) then
ntop.mkdir(basedir)
end
--if(verbose) then print(basedir.."<br>\n") end
interface.select(ifname)
json = interface.getHostInfo(hostname)
if(json ~= nil) then
fname = fixPath(basedir.."/".. hostname ..".json")
if(verbose) then print(fname.."<p>\n") end
-- Read old version
f = io.open(fname, "r")
if(f ~= nil) then
old_json = f:read("*all")
f:close()
check_host_alert(ifname, hostname, mode, hostname, old_json, json["json"])
end
-- Write new version
f = io.open(fname, "w")
if(f ~= nil) then
f:write(json["json"])
f:close()
end
end
end
-- #################################
function scanAlerts(granularity)
ifnames = interface.getIfNames()
for _,_ifname in pairs(ifnames) do
ifname = purifyInterfaceName(_ifname)
if(verbose) then print("[minute.lua] Processing interface " .. ifname.."<p>\n") end
hash_key = "ntopng.prefs.alerts_"..granularity
hosts = ntop.getHashKeysCache(hash_key)
if(hosts ~= nil) then
for h in pairs(hosts) do
check_host_threshold(ifname, h, granularity)
end
end
end -- interfaces
end

View file

@ -0,0 +1,803 @@
-- Module options:
local always_try_using_lpeg = true
local register_global_module_table = false
local global_module_name = 'json'
--[==[
David Kolf's JSON module for Lua 5.1/5.2
========================================
*Version 2.3*
In the default configuration this module writes no global values, not even
the module table. Import it using
json = require ("dkjson")
In environments where `require` or a similiar function are not available
and you cannot receive the return value of the module, you can set the
option `register_global_module_table` to `true`. The module table will
then be saved in the global variable with the name given by the option
`global_module_name`.
Exported functions and values:
`json.encode (object [, state])`
--------------------------------
Create a string representing the object. `Object` can be a table,
a string, a number, a boolean, `nil`, `json.null` or any object with
a function `__tojson` in its metatable. A table can only use strings
and numbers as keys and its values have to be valid objects as
well. It raises an error for any invalid data types or reference
cycles.
`state` is an optional table with the following fields:
- `indent`
When `indent` (a boolean) is set, the created string will contain
newlines and indentations. Otherwise it will be one long line.
- `keyorder`
`keyorder` is an array to specify the ordering of keys in the
encoded output. If an object has keys which are not in this array
they are written after the sorted keys.
- `level`
This is the initial level of indentation used when `indent` is
set. For each level two spaces are added. When absent it is set
to 0.
- `buffer`
`buffer` is an array to store the strings for the result so they
can be concatenated at once. When it isn't given, the encode
function will create it temporary and will return the
concatenated result.
- `bufferlen`
When `bufferlen` is set, it has to be the index of the last
element of `buffer`.
- `tables`
`tables` is a set to detect reference cycles. It is created
temporary when absent. Every table that is currently processed
is used as key, the value is `true`.
When `state.buffer` was set, the return value will be `true` on
success. Without `state.buffer` the return value will be a string.
`json.decode (string [, position [, null]])`
--------------------------------------------
Decode `string` starting at `position` or at 1 if `position` was
omitted.
`null` is an optional value to be returned for null values. The
default is `nil`, but you could set it to `json.null` or any other
value.
The return values are the object or `nil`, the position of the next
character that doesn't belong to the object, and in case of errors
an error message.
Two metatables are created. Every array or object that is decoded gets
a metatable with the `__jsontype` field set to either `array` or
`object`. If you want to provide your own metatables use the syntax
json.decode (string, position, null, objectmeta, arraymeta)
To prevent the assigning of metatables pass `nil`:
json.decode (string, position, null, nil)
`<metatable>.__jsonorder`
-------------------------
`__jsonorder` can overwrite the `keyorder` for a specific table.
`<metatable>.__jsontype`
------------------------
`__jsontype` can be either `"array"` or `"object"`. This value is only
checked for empty tables. (The default for empty tables is `"array"`).
`<metatable>.__tojson (self, state)`
------------------------------------
You can provide your own `__tojson` function in a metatable. In this
function you can either add directly to the buffer and return true,
or you can return a string. On errors nil and a message should be
returned.
`json.null`
-----------
You can use this value for setting explicit `null` values.
`json.version`
--------------
Set to `"dkjson 2.3"`.
`json.quotestring (string)`
---------------------------
Quote a UTF-8 string and escape critical characters using JSON
escape sequences. This function is only necessary when you build
your own `__tojson` functions.
`json.addnewline (state)`
-------------------------
When `state.indent` is set, add a newline to `state.buffer` and spaces
according to `state.level`.
LPeg support
------------
When the local configuration variable `always_try_using_lpeg` is set,
this module tries to load LPeg to replace the `decode` function. The
speed increase is significant. You can get the LPeg module at
<http://www.inf.puc-rio.br/~roberto/lpeg/>.
When LPeg couldn't be loaded, the pure Lua functions stay active.
In case you don't want this module to require LPeg on its own,
disable the option `always_try_using_lpeg` in the options section at
the top of the module.
In this case you can later load LPeg support using
### `json.use_lpeg ()`
Require the LPeg module and replace the functions `quotestring` and
and `decode` with functions that use LPeg patterns.
This function returns the module table, so you can load the module
using:
json = require "dkjson".use_lpeg()
Alternatively you can use `pcall` so the JSON module still works when
LPeg isn't found.
json = require "dkjson"
pcall (json.use_lpeg)
### `json.using_lpeg`
This variable is set to `true` when LPeg was loaded successfully.
---------------------------------------------------------------------
Contact
-------
You can contact the author by sending an e-mail to 'david' at the
domain 'dkolf.de'.
---------------------------------------------------------------------
*Copyright (C) 2010-2013 David Heiko Kolf*
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<!-- This documentation can be parsed using Markdown to generate HTML.
The source code is enclosed in a HTML comment so it won't be displayed
by browsers, but it should be removed from the final HTML file as
it isn't a valid HTML comment (and wastes space).
-->
<!--]==]
-- global dependencies:
local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
local error, require, pcall, select = error, require, pcall, select
local floor, huge = math.floor, math.huge
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
string.rep, string.gsub, string.sub, string.byte, string.char,
string.find, string.len, string.format
local concat = table.concat
local json = { version = "dkjson 2.3" }
if register_global_module_table then
_G[global_module_name] = json
end
local _ENV = nil -- blocking globals in Lua 5.2
pcall (function()
-- Enable access to blocked metatables.
-- Don't worry, this module doesn't change anything in them.
local debmeta = require "debug".getmetatable
if debmeta then getmetatable = debmeta end
end)
json.null = setmetatable ({}, {
__tojson = function () return "null" end
})
local function isarray (tbl)
local max, n, arraylen = 0, 0, 0
for k,v in pairs (tbl) do
if k == 'n' and type(v) == 'number' then
arraylen = v
if v > max then
max = v
end
else
if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
return false
end
if k > max then
max = k
end
n = n + 1
end
end
if max > 10 and max > arraylen and max > n * 2 then
return false -- don't create an array with too many holes
end
return true, max
end
local escapecodes = {
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f",
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t"
}
local function escapeutf8 (uchar)
local value = escapecodes[uchar]
if value then
return value
end
local a, b, c, d = strbyte (uchar, 1, 4)
a, b, c, d = a or 0, b or 0, c or 0, d or 0
if a <= 0x7f then
value = a
elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
value = (a - 0xc0) * 0x40 + b - 0x80
elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
else
return ""
end
if value <= 0xffff then
return strformat ("\\u%.4x", value)
elseif value <= 0x10ffff then
-- encode as UTF-16 surrogate pair
value = value - 0x10000
local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400)
return strformat ("\\u%.4x\\u%.4x", highsur, lowsur)
else
return ""
end
end
local function fsub (str, pattern, repl)
-- gsub always builds a new string in a buffer, even when no match
-- exists. First using find should be more efficient when most strings
-- don't contain the pattern.
if strfind (str, pattern) then
return gsub (str, pattern, repl)
else
return str
end
end
local function quotestring (value)
-- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8)
if strfind (value, "[\194\216\220\225\226\239]") then
value = fsub (value, "\194[\128-\159\173]", escapeutf8)
value = fsub (value, "\216[\128-\132]", escapeutf8)
value = fsub (value, "\220\143", escapeutf8)
value = fsub (value, "\225\158[\180\181]", escapeutf8)
value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8)
value = fsub (value, "\226\129[\160-\175]", escapeutf8)
value = fsub (value, "\239\187\191", escapeutf8)
value = fsub (value, "\239\191[\176-\191]", escapeutf8)
end
return "\"" .. value .. "\""
end
json.quotestring = quotestring
local function addnewline2 (level, buffer, buflen)
buffer[buflen+1] = "\n"
buffer[buflen+2] = strrep (" ", level)
buflen = buflen + 2
return buflen
end
function json.addnewline (state)
if state.indent then
state.bufferlen = addnewline2 (state.level or 0,
state.buffer, state.bufferlen or #(state.buffer))
end
end
local encode2 -- forward declaration
local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder)
local kt = type (key)
if kt ~= 'string' and kt ~= 'number' then
return nil, "type '" .. kt .. "' is not supported as a key by JSON."
end
if prev then
buflen = buflen + 1
buffer[buflen] = ","
end
if indent then
buflen = addnewline2 (level, buffer, buflen)
end
buffer[buflen+1] = quotestring (key)
buffer[buflen+2] = ":"
return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder)
end
encode2 = function (value, indent, level, buffer, buflen, tables, globalorder)
local valtype = type (value)
local valmeta = getmetatable (value)
valmeta = type (valmeta) == 'table' and valmeta -- only tables
local valtojson = valmeta and valmeta.__tojson
if valtojson then
if tables[value] then
return nil, "reference cycle"
end
tables[value] = true
local state = {
indent = indent, level = level, buffer = buffer,
bufferlen = buflen, tables = tables, keyorder = globalorder
}
local ret, msg = valtojson (value, state)
if not ret then return nil, msg end
tables[value] = nil
buflen = state.bufferlen
if type (ret) == 'string' then
buflen = buflen + 1
buffer[buflen] = ret
end
elseif value == nil then
buflen = buflen + 1
buffer[buflen] = "null"
elseif valtype == 'number' then
local s
if value ~= value or value >= huge or -value >= huge then
-- This is the behaviour of the original JSON implementation.
s = "null"
else
s = tostring (value)
end
buflen = buflen + 1
buffer[buflen] = s
elseif valtype == 'boolean' then
buflen = buflen + 1
buffer[buflen] = value and "true" or "false"
elseif valtype == 'string' then
buflen = buflen + 1
buffer[buflen] = quotestring (value)
elseif valtype == 'table' then
if tables[value] then
return nil, "reference cycle"
end
tables[value] = true
level = level + 1
local isa, n = isarray (value)
if n == 0 and valmeta and valmeta.__jsontype == 'object' then
isa = false
end
local msg
if isa then -- JSON array
buflen = buflen + 1
buffer[buflen] = "["
for i = 1, n do
buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder)
if not buflen then return nil, msg end
if i < n then
buflen = buflen + 1
buffer[buflen] = ","
end
end
buflen = buflen + 1
buffer[buflen] = "]"
else -- JSON object
local prev = false
buflen = buflen + 1
buffer[buflen] = "{"
local order = valmeta and valmeta.__jsonorder or globalorder
if order then
local used = {}
n = #order
for i = 1, n do
local k = order[i]
local v = value[k]
if v then
used[k] = true
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
prev = true -- add a seperator before the next element
end
end
for k,v in pairs (value) do
if not used[k] then
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
if not buflen then return nil, msg end
prev = true -- add a seperator before the next element
end
end
else -- unordered
for k,v in pairs (value) do
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder)
if not buflen then return nil, msg end
prev = true -- add a seperator before the next element
end
end
if indent then
buflen = addnewline2 (level - 1, buffer, buflen)
end
buflen = buflen + 1
buffer[buflen] = "}"
end
tables[value] = nil
else
return nil, "type '" .. valtype .. "' is not supported by JSON."
end
return buflen
end
function json.encode (value, state)
state = state or {}
local oldbuffer = state.buffer
local buffer = oldbuffer or {}
local ret, msg = encode2 (value, state.indent, state.level or 0,
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder)
if not ret then
error (msg, 2)
elseif oldbuffer then
state.bufferlen = ret
return true
else
return concat (buffer)
end
end
local function loc (str, where)
local line, pos, linepos = 1, 1, 0
while true do
pos = strfind (str, "\n", pos, true)
if pos and pos < where then
line = line + 1
linepos = pos
pos = pos + 1
else
break
end
end
return "line " .. line .. ", column " .. (where - linepos)
end
local function unterminated (str, what, where)
return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where)
end
local function scanwhite (str, pos)
while true do
pos = strfind (str, "%S", pos)
if not pos then return nil end
if strsub (str, pos, pos + 2) == "\239\187\191" then
-- UTF-8 Byte Order Mark
pos = pos + 3
else
return pos
end
end
end
local escapechars = {
["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f",
["n"] = "\n", ["r"] = "\r", ["t"] = "\t"
}
local function unichar (value)
if value < 0 then
return nil
elseif value <= 0x007f then
return strchar (value)
elseif value <= 0x07ff then
return strchar (0xc0 + floor(value/0x40),
0x80 + (floor(value) % 0x40))
elseif value <= 0xffff then
return strchar (0xe0 + floor(value/0x1000),
0x80 + (floor(value/0x40) % 0x40),
0x80 + (floor(value) % 0x40))
elseif value <= 0x10ffff then
return strchar (0xf0 + floor(value/0x40000),
0x80 + (floor(value/0x1000) % 0x40),
0x80 + (floor(value/0x40) % 0x40),
0x80 + (floor(value) % 0x40))
else
return nil
end
end
local function scanstring (str, pos)
local lastpos = pos + 1
local buffer, n = {}, 0
while true do
local nextpos = strfind (str, "[\"\\]", lastpos)
if not nextpos then
return unterminated (str, "string", pos)
end
if nextpos > lastpos then
n = n + 1
buffer[n] = strsub (str, lastpos, nextpos - 1)
end
if strsub (str, nextpos, nextpos) == "\"" then
lastpos = nextpos + 1
break
else
local escchar = strsub (str, nextpos + 1, nextpos + 1)
local value
if escchar == "u" then
value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16)
if value then
local value2
if 0xD800 <= value and value <= 0xDBff then
-- we have the high surrogate of UTF-16. Check if there is a
-- low surrogate escaped nearby to combine them.
if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then
value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16)
if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
else
value2 = nil -- in case it was out of range for a low surrogate
end
end
end
value = value and unichar (value)
if value then
if value2 then
lastpos = nextpos + 12
else
lastpos = nextpos + 6
end
end
end
end
if not value then
value = escapechars[escchar] or escchar
lastpos = nextpos + 2
end
n = n + 1
buffer[n] = value
end
end
if n == 1 then
return buffer[1], lastpos
elseif n > 1 then
return concat (buffer), lastpos
else
return "", lastpos
end
end
local scanvalue -- forward declaration
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta)
local len = strlen (str)
local tbl, n = {}, 0
local pos = startpos + 1
if what == 'object' then
setmetatable (tbl, objectmeta)
else
setmetatable (tbl, arraymeta)
end
while true do
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
local char = strsub (str, pos, pos)
if char == closechar then
return tbl, pos + 1
end
local val1, err
val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
char = strsub (str, pos, pos)
if char == ":" then
if val1 == nil then
return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")"
end
pos = scanwhite (str, pos + 1)
if not pos then return unterminated (str, what, startpos) end
local val2
val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end
tbl[val1] = val2
pos = scanwhite (str, pos)
if not pos then return unterminated (str, what, startpos) end
char = strsub (str, pos, pos)
else
n = n + 1
tbl[n] = val1
end
if char == "," then
pos = pos + 1
end
end
end
scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
pos = pos or 1
pos = scanwhite (str, pos)
if not pos then
return nil, strlen (str) + 1, "no valid JSON value (reached the end)"
end
local char = strsub (str, pos, pos)
if char == "{" then
return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta)
elseif char == "[" then
return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta)
elseif char == "\"" then
return scanstring (str, pos)
else
local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
if pstart then
local number = tonumber (strsub (str, pstart, pend))
if number then
return number, pend + 1
end
end
pstart, pend = strfind (str, "^%a%w*", pos)
if pstart then
local name = strsub (str, pstart, pend)
if name == "true" then
return true, pend + 1
elseif name == "false" then
return false, pend + 1
elseif name == "null" then
return nullval, pend + 1
end
end
return nil, pos, "no valid JSON value at " .. loc (str, pos)
end
end
local function optionalmetatables(...)
if select("#", ...) > 0 then
return ...
else
return {__jsontype = 'object'}, {__jsontype = 'array'}
end
end
function json.decode (str, pos, nullval, ...)
local objectmeta, arraymeta = optionalmetatables(...)
return scanvalue (str, pos, nullval, objectmeta, arraymeta)
end
function json.use_lpeg ()
local g = require ("lpeg")
local pegmatch = g.match
local P, S, R, V = g.P, g.S, g.R, g.V
local function ErrorCall (str, pos, msg, state)
if not state.msg then
state.msg = msg .. " at " .. loc (str, pos)
state.pos = pos
end
return false
end
local function Err (msg)
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
end
local Space = (S" \n\r\t" + P"\239\187\191")^0
local PlainChar = 1 - S"\"\\\n\r"
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
local HexDigit = R("09", "af", "AF")
local function UTF16Surrogate (match, pos, high, low)
high, low = tonumber (high, 16), tonumber (low, 16)
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
else
return false
end
end
local function UTF16BMP (hex)
return unichar (tonumber (hex, 16))
end
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
local Char = UnicodeEscape + EscapeSequence + PlainChar
local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string")
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
local Fractal = P"." * R"09"^0
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
local Number = (Integer * Fractal^(-1) * Exponent^(-1))/tonumber
local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1)
local SimpleValue = Number + String + Constant
local ArrayContent, ObjectContent
-- The functions parsearray and parseobject parse only a single value/pair
-- at a time and store them directly to avoid hitting the LPeg limits.
local function parsearray (str, pos, nullval, state)
local obj, cont
local npos
local t, nt = {}, 0
repeat
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
if not npos then break end
pos = npos
nt = nt + 1
t[nt] = obj
until cont == 'last'
return pos, setmetatable (t, state.arraymeta)
end
local function parseobject (str, pos, nullval, state)
local obj, key, cont
local npos
local t = {}
repeat
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
if not npos then break end
pos = npos
t[key] = obj
until cont == 'last'
return pos, setmetatable (t, state.objectmeta)
end
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
local Value = Space * (Array + Object + SimpleValue)
local ExpectedValue = Value + Space * Err "value expected"
ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
local DecodeValue = ExpectedValue * g.Cp ()
function json.decode (str, pos, nullval, ...)
local state = {}
state.objectmeta, state.arraymeta = optionalmetatables(...)
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
if state.msg then
return nil, state.pos, state.msg
else
return obj, retpos
end
end
-- use this function only once:
json.use_lpeg = function () return json end
json.using_lpeg = true
return json -- so you can get the module using json = require "dkjson".use_lpeg()
end
if always_try_using_lpeg then
pcall (json.use_lpeg)
end
return json
-->

View file

@ -0,0 +1,946 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "template"
-- http://www.itu.int/itudoc/itu-t/ob-lists/icc/e212_685.pdf
local mobile_country_code = {
["202"] = "Greece",
["204"] = "Netherlands (Kingdom of the)",
["206"] = "Belgium",
["208"] = "France",
["212"] = "Monaco (Principality of)",
["213"] = "Andorra (Principality of)",
["214"] = "Spain",
["216"] = "Hungary (Republic of)",
["218"] = "Bosnia and Herzegovina",
["219"] = "Croatia (Republic of)",
["220"] = "Serbia and Montenegro",
["222"] = "Italy",
["225"] = "Vatican City State",
["226"] = "Romania",
["228"] = "Switzerland (Confederation of)",
["230"] = "Czech Republic",
["231"] = "Slovak Republic",
["232"] = "Austria",
["234"] = "United Kingdom",
["235"] = "United Kingdom",
["238"] = "Denmark",
["240"] = "Sweden",
["242"] = "Norway",
["244"] = "Finland",
["246"] = "Lithuania (Republic of)",
["247"] = "Latvia (Republic of)",
["248"] = "Estonia (Republic of)",
["250"] = "Russian Federation",
["255"] = "Ukraine",
["257"] = "Belarus (Republic of)",
["259"] = "Moldova (Republic of)",
["260"] = "Poland (Republic of)",
["262"] = "Germany (Federal Republic of)",
["266"] = "Gibraltar",
["268"] = "Portugal",
["270"] = "Luxembourg",
["272"] = "Ireland",
["274"] = "Iceland",
["276"] = "Albania (Republic of)",
["278"] = "Malta",
["280"] = "Cyprus (Republic of)",
["282"] = "Georgia",
["283"] = "Armenia (Republic of)",
["284"] = "Bulgaria (Republic of)",
["286"] = "Turkey",
["288"] = "Faroe Islands",
["290"] = "Greenland (Denmark)",
["292"] = "San Marino (Republic of)",
["293"] = "Slovenia (Republic of)",
["294"] = "The Former Yugoslav Republic of Macedonia",
["295"] = "Liechtenstein (Principality of)",
["302"] = "Canada",
["308"] = "Saint Pierre and Miquelon",
["310"] = "United States of America",
["311"] = "United States of America",
["312"] = "United States of America",
["313"] = "United States of America",
["314"] = "United States of America",
["315"] = "United States of America",
["316"] = "United States of America",
["330"] = "Puerto Rico",
["332"] = "United States Virgin Islands",
["334"] = "Mexico",
["338"] = "Jamaica",
["340"] = "Martinique / Guadeloupe",
["342"] = "Barbados",
["344"] = "Antigua and Barbuda",
["346"] = "Cayman Islands",
["348"] = "British Virgin Islands",
["350"] = "Bermuda",
["352"] = "Grenada",
["354"] = "Montserrat",
["356"] = "Saint Kitts and Nevis",
["358"] = "SaintLucia",
["360"] = "Saint Vincent and the Grenadines",
["362"] = "Netherlands Antilles",
["363"] = "Aruba",
["364"] = "Bahamas (Commonwealth of the)",
["365"] = "Anguilla",
["366"] = "Dominica (Commonwealth of)",
["368"] = "Cuba",
["370"] = "Dominican Republic",
["372"] = "Haiti (Republic of)",
["374"] = "Trinidad and Tobago",
["376"] = "Turks and Caicos Islands",
["400"] = "Azerbaijani Republic",
["401"] = "Kazakhstan (Republic of)",
["402"] = "Bhutan (Kingdom of)",
["404"] = "India (Republic of)",
["410"] = "Pakistan (Islamic Republic of)",
["412"] = "Afghanistan",
["413"] = "Sri Lanka (Democratic Socialist Republic of)",
["414"] = "Myanmar (Union of)",
["415"] = "Lebanon",
["416"] = "Jordan (Hashemite Kingdom of)",
["417"] = "Syrian Arab Republic",
["418"] = "Iraq (Republic of)",
["419"] = "Kuwait (State of)",
["420"] = "Saudi Arabia (Kingdom of)",
["421"] = "Yemen (Republic of)",
["422"] = "Oman (Sultanate of)",
["424"] = "United Arab Emirates",
["425"] = "Israel (State of)",
["426"] = "Bahrain (Kingdom of)",
["427"] = "Qatar (State of)",
["428"] = "Mongolia",
["429"] = "Nepal",
["430"] = "United Arab Emirates b",
["431"] = "United Arab Emirates b",
["432"] = "Iran (Islamic Republic of)",
["434"] = "Uzbekistan (Republic of)",
["436"] = "Tajikistan (Republic of)",
["437"] = "Kyrgyz Republic",
["438"] = "Turkmenistan",
["440"] = "Japan",
["441"] = "Japan",
["450"] = "Korea (Republic of)",
["452"] = "Viet Nam (Socialist Republic of)",
["454"] = "Hongkong China",
["455"] = "Macao China",
["456"] = "Cambodia (Kingdom of)",
["457"] = "Lao People's Democratic Republic",
["460"] = "China (People's Republic of)",
["461"] = "China (People's Republic of)",
["466"] = "Taiwan",
["467"] = "Democratic People's Republic of Korea",
["470"] = "Bangladesh (People's Republic of)",
["472"] = "Maldives (Republic of)",
["502"] = "Malaysia",
["505"] = "Australia",
["510"] = "Indonesia (Republic of)",
["514"] = "Democratique Republic of Timor-Leste",
["515"] = "Philippines (Republic of the)",
["520"] = "Thailand",
["525"] = "Singapore (Republic of)",
["528"] = "Brunei Darussalam",
["530"] = "New Zealand",
["534"] = "Northern Mariana Islands (Commonwealth of the)",
["535"] = "Guam",
["536"] = "Nauru (Republic of)",
["537"] = "Papua New Guinea",
["539"] = "Tonga (Kingdom of)",
["540"] = "Solomon Islands",
["541"] = "Vanuatu (Republic of)",
["542"] = "Fiji (Republic of)",
["543"] = "Wallis and Futuna",
["544"] = "American Samoa",
["545"] = "Kiribati (Republic of)",
["546"] = "New Caledonia",
["547"] = "French Polynesia",
["548"] = "Cook Islands",
["549"] = "Samoa (Independent State of)",
["550"] = "Micronesia (Federated States of)",
["551"] = "Marshall Islands (Republic of the)",
["552"] = "Palau (Republic of)",
["602"] = "Egypt (Arab Republic of)",
["603"] = "Algeria (People's Democratic Republic of)",
["604"] = "Morocco (Kingdom of)",
["605"] = "Tunisia",
["606"] = "Libya",
["607"] = "Gambia (Republic of the)",
["608"] = "Senegal (Republic of)",
["609"] = "Mauritania (Islamic Republic of)",
["610"] = "Mali (Republic of)",
["611"] = "Guinea (Republic of)",
["612"] = "Cote d'Ivoire (Republic of)",
["613"] = "Burkina Faso",
["614"] = "Niger (Republic of the)",
["615"] = "Togolese Republic",
["616"] = "Benin (Republic of)",
["617"] = "Mauritius (Republic of)",
["618"] = "Liberia (Republic of)",
["619"] = "Sierra Leone",
["620"] = "Ghana",
["621"] = "Nigeria (Federal Republic of)",
["622"] = "Chad (Republic of)",
["623"] = "Central African Republic",
["624"] = "Cameroon (Republic of)",
["625"] = "Cape Verde (Republic of)",
["626"] = "Sao Tome and Principe (Democratic Republic of)",
["627"] = "Equatorial Guinea (Republic of)",
["628"] = "Gabonese Republic",
["629"] = "Congo (Republic of the)",
["630"] = "Democratic Republic of the Congo",
["631"] = "Angola (Republic of)",
["632"] = "Guinea-Bissau (Republic of)",
["633"] = "Seychelles (Republic of)",
["634"] = "Sudan (Republic of the)",
["635"] = "Rwandese Republic",
["636"] = "Ethiopia (Federal Democratic Republic of)",
["637"] = "Somali Democratic Republic",
["638"] = "Djibouti (Republic of)",
["639"] = "Kenya (Republic of)",
["640"] = "Tanzania (United Republic of)",
["641"] = "Uganda (Republic of)",
["642"] = "Burundi (Republic of)",
["643"] = "Mozambique (Republic of)",
["645"] = "Zambia (Republic of)",
["646"] = "Madagascar (Republic of)",
["647"] = "Reunion (French Department of)",
["648"] = "Zimbabwe (Republic of)",
["649"] = "Namibia (Republic of)",
["650"] = "Malawi",
["651"] = "Lesotho (Kingdom of)",
["652"] = "Botswana (Republic of)",
["653"] = "Swaziland (Kingdom of)",
["654"] = "Comoros (Union of the)",
["655"] = "South Africa (Republic of)",
["657"] = "Eritrea",
["702"] = "Belize",
["704"] = "Guatemala (Republic of)",
["706"] = "El Salvador (Republic of)",
["708"] = "Honduras (Republic of)",
["710"] = "Nicaragua",
["712"] = "Costa Rica",
["714"] = "Panama (Republic of)",
["716"] = "Peru",
["722"] = "Argentine Republic",
["724"] = "Brazil (Federative Republic of)",
["730"] = "Chile",
["732"] = "Colombia (Republic of)",
["734"] = "Venezuela (Bolivarian Republic of)",
["736"] = "Bolivia (Republic of)",
["738"] = "Guyana",
["740"] = "Ecuador",
["742"] = "French Guiana (French Department of)",
["744"] = "Paraguay (Republic of)",
["746"] = "Suriname (Republic of)",
["748"] = "Uruguay (Eastern Republic of)",
["412"] = "Afghanistan",
["276"] = "Albania (Republic of)",
["603"] = "Algeria (People's Democratic Republic of)",
["544"] = "American Samoa",
["213"] = "Andorra (Principality of)",
["631"] = "Angola (Republic of)",
["365"] = "Anguilla",
["344"] = "Antigua and Barbuda",
["722"] = "Argentine Republic",
["283"] = "Armenia (Republic of)",
["363"] = "Aruba",
["505"] = "Australia",
["232"] = "Austria",
["400"] = "Azerbaijani Republic",
["364"] = "Bahamas (Commonwealth of the)",
["426"] = "Bahrain (Kingdom of)",
["470"] = "Bangladesh (People's Republic of)",
["342"] = "Barbados",
["257"] = "Belarus (Republic of)",
["206"] = "Belgium",
["702"] = "Belize",
["616"] = "Benin (Republic of)",
["350"] = "Bermuda",
["402"] = "Bhutan (Kingdom of)",
["736"] = "Bolivia (Republic of)",
["218"] = "Bosnia and Herzegovina",
["652"] = "Botswana (Republic of)",
["724"] = "Brazil (Federative Republic of)",
["348"] = "British Virgin Islands",
["528"] = "Brunei Darussalam",
["284"] = "Bulgaria (Republic of)",
["613"] = "Burkina Faso",
["642"] = "Burundi (Republic of)",
["456"] = "Cambodia (Kingdom of)",
["624"] = "Cameroon (Republic of)",
["302"] = "Canada",
["625"] = "Cape Verde (Republic of)",
["346"] = "Cayman Islands",
["623"] = "Central African Republic",
["622"] = "Chad (Republic of)",
["730"] = "Chile",
["461"] = "China (People's Republic of)",
["460"] = "China (People's Republic of)",
["732"] = "Colombia (Republic of)",
["654"] = "Comoros (Union of the)",
["629"] = "Congo (Republic of the)",
["548"] = "Cook Islands",
["712"] = "Costa Rica",
["612"] = "Cote d'Ivoire (Republic of)",
["219"] = "Croatia (Republic of)",
["368"] = "Cuba",
["280"] = "Cyprus (Republic of)",
["230"] = "Czech Republic",
["467"] = "Democratic People's Republic of Korea",
["630"] = "Democratic Republic of the Congo",
["514"] = "Democratique Republic of Timor-Leste",
["238"] = "Denmark",
["638"] = "Djibouti (Republic of)",
["366"] = "Dominica (Commonwealth of)",
["370"] = "Dominican Republic",
["740"] = "Ecuador",
["602"] = "Egypt (Arab Republic of)",
["706"] = "El Salvador (Republic of)",
["627"] = "Equatorial Guinea (Republic of)",
["657"] = "Eritrea",
["248"] = "Estonia (Republic of)",
["636"] = "Ethiopia (Federal Democratic Republic of)",
["288"] = "Faroe Islands",
["542"] = "Fiji (Republic of)",
["244"] = "Finland",
["208"] = "France",
["742"] = "French Guiana (French Department of)",
["547"] = "French Polynesia",
["628"] = "Gabonese Republic",
["607"] = "Gambia (Republic of the)",
["282"] = "Georgia",
["262"] = "Germany (Federal Republic of)",
["620"] = "Ghana",
["266"] = "Gibraltar",
["202"] = "Greece",
["290"] = "Greenland (Denmark)",
["352"] = "Grenada",
["340"] = "Guadeloupe (French Department of)",
["535"] = "Guam",
["704"] = "Guatemala (Republic of)",
["611"] = "Guinea (Republic of)",
["632"] = "Guinea-Bissau (Republic of)",
["738"] = "Guyana",
["372"] = "Haiti (Republic of)",
["708"] = "Honduras (Republic of)",
["454"] = "Hongkong China",
["216"] = "Hungary (Republic of)",
["274"] = "Iceland",
["404"] = "India (Republic of)",
["510"] = "Indonesia (Republic of)",
["901"] = "International Mobile shared code c",
["432"] = "Iran (Islamic Republic of)",
["418"] = "Iraq (Republic of)",
["272"] = "Ireland",
["425"] = "Israel (State of)",
["222"] = "Italy",
["338"] = "Jamaica",
["441"] = "Japan",
["440"] = "Japan",
["416"] = "Jordan (Hashemite Kingdom of)",
["401"] = "Kazakhstan (Republic of)",
["639"] = "Kenya (Republic of)",
["545"] = "Kiribati (Republic of)",
["450"] = "Korea (Republic of)",
["419"] = "Kuwait (State of)",
["437"] = "Kyrgyz Republic",
["457"] = "Lao People's Democratic Republic",
["247"] = "Latvia (Republic of)",
["415"] = "Lebanon",
["651"] = "Lesotho (Kingdom of)",
["618"] = "Liberia (Republic of)",
["606"] = "Libya",
["295"] = "Liechtenstein (Principality of)",
["246"] = "Lithuania (Republic of)",
["270"] = "Luxembourg",
["455"] = "Macao China",
["646"] = "Madagascar (Republic of)",
["650"] = "Malawi",
["502"] = "Malaysia",
["472"] = "Maldives (Republic of)",
["610"] = "Mali (Republic of)",
["278"] = "Malta",
["551"] = "Marshall Islands (Republic of the)",
["340"] = "Martinique (French Department of)",
["609"] = "Mauritania (Islamic Republic of)",
["617"] = "Mauritius (Republic of)",
["334"] = "Mexico",
["550"] = "Micronesia (Federated States of)",
["259"] = "Moldova (Republic of)",
["212"] = "Monaco (Principality of)",
["428"] = "Mongolia",
["354"] = "Montserrat",
["604"] = "Morocco (Kingdom of)",
["643"] = "Mozambique (Republic of)",
["414"] = "Myanmar (Union of)",
["649"] = "Namibia (Republic of)",
["536"] = "Nauru (Republic of)",
["429"] = "Nepal",
["204"] = "Netherlands (Kingdom of the)",
["362"] = "Netherlands Antilles",
["546"] = "New Caledonia",
["530"] = "New Zealand",
["710"] = "Nicaragua",
["614"] = "Niger (Republic of the)",
["621"] = "Nigeria (Federal Republic of)",
["534"] = "Northern Mariana Islands (Commonwealth of the)",
["242"] = "Norway",
["422"] = "Oman (Sultanate of)",
["410"] = "Pakistan (Islamic Republic of)",
["552"] = "Palau (Republic of)",
["714"] = "Panama (Republic of)",
["537"] = "Papua New Guinea",
["744"] = "Paraguay (Republic of)",
["716"] = "Peru",
["515"] = "Philippines (Republic of the)",
["260"] = "Poland (Republic of)",
["268"] = "Portugal",
["330"] = "Puerto Rico",
["427"] = "Qatar (State of)",
["8XX"] = "Reserved a 0XX Reserved a 1XX Reserved a",
["647"] = "Reunion (French Department of) 226 Romania",
["250"] = "Russian Federation",
["635"] = "Rwandese Republic",
["356"] = "Saint Kitts and Nevis",
["358"] = "SaintLucia",
["308"] = "Saint Pierre and Miquelon",
["360"] = "Saint Vincent and the Grenadines",
["549"] = "Samoa (Independent State of)",
["292"] = "San Marino (Republic of)",
["626"] = "Sao Tome and Principe (Democratic Republic of)",
["420"] = "Saudi Arabia (Kingdom of)",
["608"] = "Senegal (Republic of)",
["220"] = "Serbia and Montenegro",
["633"] = "Seychelles (Republic of)",
["619"] = "Sierra Leone",
["525"] = "Singapore (Republic of)",
["231"] = "Slovak Republic",
["293"] = "Slovenia (Republic of)",
["540"] = "Solomon Islands",
["637"] = "Somali Democratic Republic",
["655"] = "South Africa (Republic of)",
["214"] = "Spain",
["413"] = "Sri Lanka (Democratic Socialist Republic of)",
["634"] = "Sudan (Republic of the)",
["746"] = "Suriname (Republic of)",
["653"] = "Swaziland (Kingdom of)",
["240"] = "Sweden",
["228"] = "Switzerland (Confederation of)",
["417"] = "Syrian Arab Republic",
["466"] = "Taiwan",
["436"] = "Tajikistan (Republic of)",
["640"] = "Tanzania (United Republic of)",
["520"] = "Thailand",
["294"] = "The Former Yugoslav Republic of Macedonia",
["615"] = "Togolese Republic",
["539"] = "Tonga (Kingdom of)",
["374"] = "Trinidad and Tobago",
["605"] = "Tunisia",
["286"] = "Turkey",
["438"] = "Turkmenistan",
["376"] = "Turks and Caicos Islands",
["641"] = "Uganda (Republic of)",
["255"] = "Ukraine",
["424"] = "United Arab Emirates",
["430"] = "United Arab Emirates b",
["431"] = "United Arab Emirates b",
["235"] = "United Kingdom",
["234"] = "United Kingdom",
["310"] = "United States of America",
["316"] = "United States of America",
["311"] = "United States of America",
["312"] = "United States of America",
["313"] = "United States of America",
["314"] = "United States of America",
["315"] = "United States of America",
["332"] = "United States Virgin Islands",
["748"] = "Uruguay (Eastern Republic of)",
["434"] = "Uzbekistan (Republic of)",
["541"] = "Vanuatu (Republic of)",
["225"] = "Vatican City State",
["734"] = "Venezuela (Bolivarian Republic of)",
["452"] = "Viet Nam (Socialist Republic of)",
["543"] = "Wallis and Futuna",
["421"] = "Yemen (Republic of)",
["645"] = "Zambia (Republic of)",
["648"] = "Zimbabwe (Republic of)",
}
-- #######################
function handleCustomFlowField(key, value)
if(key == 'TCP_FLAGS') then
return(formatTcpFlags(value))
elseif((key == 'INPUT_SNMP') or (key == 'OUTPUT_SNMP')) then
return(formatInterfaceId(value))
elseif((key == 'FLOW_USER_NAME') or (key == '57593')) then
elems = string.split(value, ';')
if((elems ~= nil) and (table.getn(elems) == 6)) then
r = '<table class="table table-bordered table-striped">'
imsi = elems[1]
mcc = string.sub(imsi, 1, 3)
if(mobile_country_code[mcc] ~= nil) then
mcc_name = " ["..mobile_country_code[mcc].."]"
else
mcc_name = ""
end
r = r .. "<th>IMSI (International mobile Subscriber Identity)</th><td>"..elems[1]..mcc_name
r = r .. " <A HREF=http://www.numberingplans.com/?page=analysis&sub=imsinr><i class='fa fa-info'></i></A></td></tr>"
r = r .. "<th>NSAPI</th><td>".. elems[2].."</td></tr>"
r = r .. "<th>GSM Cell LAC (Location Area Code)</th><td>".. elems[3].."</td></tr>"
r = r .. "<th>GSM Cell Identifier</th><td>".. elems[4].."</td></tr>"
r = r .. "<th>SAC (Service Area Code)</th><td>".. elems[5].."</td></tr>"
r = r .. "<th>IP Address</th><td>".. ntop.inet_ntoa(elems[6]).."</td></tr>"
r = r .. "</table>"
return(r)
else
return(value)
end
end
-- Unformatted value
return value
end
-- #######################
function formatTcpFlags(flags)
if(flags == 0) then
return("")
end
rsp = "<A HREF=http://en.wikipedia.org/wiki/Transmission_Control_Protocol>"
if(bit.band(flags, 1) == 2) then rsp = rsp .. " SYN " end
if(bit.band(flags, 16) == 16) then rsp = rsp .. " ACK " end
if(bit.band(flags, 1) == 1) then rsp = rsp .. " FIN " end
if(bit.band(flags, 4) == 4) then rsp = rsp .. " RST " end
if(bit.band(flags, 8) == 8 ) then rsp = rsp .. " PUSH " end
return(rsp .. "</A>")
end
-- #######################
function formatInterfaceId(id)
if(id == 65535) then
return("Unknown")
else
return(id)
end
end
-- #######################
local flow_fields_description = {
["IN_BYTES"] = "Incoming flow bytes (src->dst)",
["IN_PKTS"] = "Incoming flow packets (src->dst)",
["FLOWS"] = "Number of flows",
["PROTOCOL"] = "IP protocol byte",
["PROTOCOL_MAP"] = "IP protocol name",
["SRC_TOS"] = "Type of service (TOS)",
["TCP_FLAGS"] = "Cumulative of all flow TCP flags",
["L4_SRC_PORT"] = "IPv4 source port",
["L4_SRC_PORT_MAP"] = "Layer 4 source port symbolic name",
["IPV4_SRC_ADDR"] = "IPv4 source address",
["IPV4_SRC_MASK"] = "IPv4 source subnet mask (/<bits>)",
["INPUT_SNMP"] = "Input interface SNMP idx",
["L4_DST_PORT"] = "IPv4 destination port",
["L4_DST_PORT_MAP"] = "Layer 4 destination port symbolic name",
["L4_SRV_PORT"] = "Layer 4 server port",
["L4_SRV_PORT_MAP"] = "Layer 4 server port symbolic name",
["IPV4_DST_ADDR"] = "IPv4 destination address",
["IPV4_DST_MASK"] = "IPv4 dest subnet mask (/<bits>)",
["OUTPUT_SNMP"] = "Output interface SNMP idx",
["IPV4_NEXT_HOP"] = "IPv4 Next Hop",
["SRC_AS"] = "Source BGP AS",
["DST_AS"] = "Destination BGP AS",
["LAST_SWITCHED"] = "SysUptime (msec) of the last flow pkt",
["FIRST_SWITCHED"] = "SysUptime (msec) of the first flow pkt",
["OUT_BYTES"] = "Outgoing flow bytes (dst->src)",
["OUT_PKTS"] = "Outgoing flow packets (dst->src)",
["IPV6_SRC_ADDR"] = "IPv6 source address",
["IPV6_DST_ADDR"] = "IPv6 destination address",
["IPV6_SRC_MASK"] = "IPv6 source mask",
["IPV6_DST_MASK"] = "IPv6 destination mask",
["ICMP_TYPE"] = "ICMP Type * 256 + ICMP code",
["SAMPLING_INTERVAL"] = "Sampling rate",
["SAMPLING_ALGORITHM"] = "Sampling type (deterministic/random)",
["FLOW_ACTIVE_TIMEOUT"] = "Activity timeout of flow cache entries",
["FLOW_INACTIVE_TIMEOUT"] = "Inactivity timeout of flow cache entries",
["ENGINE_TYPE"] = "Flow switching engine",
["ENGINE_ID"] = "Id of the flow switching engine",
["TOTAL_BYTES_EXP"] = "Total bytes exported",
["TOTAL_PKTS_EXP"] = "Total flow packets exported",
["TOTAL_FLOWS_EXP"] = "Total number of exported flows",
["MIN_TTL"] = "Min flow TTL",
["MAX_TTL"] = "Max flow TTL",
["DST_TOS"] = "TOS/DSCP (dst->src)",
["IN_SRC_MAC"] = "Source MAC Address",
["SRC_VLAN"] = "Source VLAN",
["DST_VLAN"] = "Destination VLAN",
["IP_PROTOCOL_VERSION"] = "4=IPv4]6=IPv6]",
["DIRECTION"] = "It indicates where a sample has been taken (always 0)",
["IPV6_NEXT_HOP"] = "IPv6 next hop address",
["MPLS_LABEL_1"] = "MPLS label at position 1",
["MPLS_LABEL_2"] = "MPLS label at position 2",
["MPLS_LABEL_3"] = "MPLS label at position 3",
["MPLS_LABEL_4"] = "MPLS label at position 4",
["MPLS_LABEL_5"] = "MPLS label at position 5",
["MPLS_LABEL_6"] = "MPLS label at position 6",
["MPLS_LABEL_7"] = "MPLS label at position 7",
["MPLS_LABEL_8"] = "MPLS label at position 8",
["MPLS_LABEL_9"] = "MPLS label at position 9",
["MPLS_LABEL_10"] = "MPLS label at position 10",
["OUT_DST_MAC"] = "Destination MAC Address",
["APPLICATION_ID"] = "Cisco NBAR Application Id",
["PACKET_SECTION_OFFSET"] = "Packet section offset",
["SAMPLED_PACKET_SIZE"] = "Sampled packet size",
["SAMPLED_PACKET_ID"] = "Sampled packet id",
["EXPORTER_IPV4_ADDRESS"] = "Exporter IPv4 Address",
["EXPORTER_IPV6_ADDRESS"] = "Exporter IPv6 Address",
["FLOW_ID"] = "Serial Flow Identifier",
["FLOW_START_SEC"] = "Seconds (epoch) of the first flow packet",
["FLOW_END_SEC"] = "Seconds (epoch) of the last flow packet",
["FLOW_START_MILLISECONDS"] = "Msec (epoch) of the first flow packet",
["FLOW_END_MILLISECONDS"] = "Msec (epoch) of the last flow packet",
["BIFLOW_DIRECTION"] = "1=initiator, 2=reverseInitiator",
["OBSERVATION_POINT_TYPE"] = "Observation point type",
["OBSERVATION_POINT_ID"] = "Observation point id",
["SELECTOR_ID"] = "Selector id",
["IPFIX_SAMPLING_ALGORITHM"] = "Sampling algorithm",
["SAMPLING_SIZE"] = "Number of packets to sample",
["SAMPLING_POPULATION"] = "Sampling population",
["FRAME_LENGTH"] = "Original L2 frame length",
["PACKETS_OBSERVED"] = "Tot number of packets seen",
["PACKETS_SELECTED"] = "Number of pkts selected for sampling",
["SELECTOR_NAME"] = "Sampler name",
["APPLICATION_NAME"] = "Palo Alto App-Id",
["USER_NAME"] = "Palo Alto User-Id",
["FRAGMENTS"] = "Number of fragmented flow packets",
["CLIENT_NW_DELAY_SEC"] = "Network latency client <-> nprobe (sec)",
["CLIENT_NW_DELAY_USEC"] = "Network latency client <-> nprobe (residual usec)",
["CLIENT_NW_DELAY_MS"] = "Network latency client <-> nprobe (msec)",
["SERVER_NW_DELAY_SEC"] = "Network latency nprobe <-> server (sec)",
["SERVER_NW_DELAY_USEC"] = "Network latency nprobe <-> server (residual usec)",
["SERVER_NW_DELAY_MS"] = "Network latency nprobe <-> server (residual msec)",
["APPL_LATENCY_SEC"] = "Application latency (sec)",
["APPL_LATENCY_USEC"] = "Application latency (residual usec)",
["APPL_LATENCY_MS"] = "Application latency (msec)",
["NUM_PKTS_UP_TO_128_BYTES"] = "# packets whose size <= 128",
["NUM_PKTS_128_TO_256_BYTES"] = "# packets whose size > 128 and <= 256",
["NUM_PKTS_256_TO_512_BYTES"] = "# packets whose size > 256 and < 512",
["NUM_PKTS_512_TO_1024_BYTES"] = "# packets whose size > 512 and < 1024",
["NUM_PKTS_1024_TO_1514_BYTES"] = "# packets whose size > 1024 and <= 1514",
["NUM_PKTS_OVER_1514_BYTES"] = "# packets whose size > 1514",
["CUMULATIVE_ICMP_TYPE"] = "Cumulative OR of ICMP type packets",
["SRC_IP_COUNTRY"] = "Country where the src IP is located",
["SRC_IP_CITY"] = "City where the src IP is located",
["DST_IP_COUNTRY"] = "Country where the dst IP is located",
["DST_IP_CITY"] = "City where the dst IP is located",
["FLOW_PROTO_PORT"] = "L7 port that identifies the flow protocol or 0 if unknown",
["UPSTREAM_TUNNEL_ID"] = "Upstream tunnel identifier (e.g. GTP TEID) or 0 if unknown",
["LONGEST_FLOW_PKT"] = "Longest packet (bytes) of the flow",
["SHORTEST_FLOW_PKT"] = "Shortest packet (bytes) of the flow",
["RETRANSMITTED_IN_PKTS"] = "Number of retransmitted TCP flow packets (src->dst)",
["RETRANSMITTED_IN_BYTES"] = "Number of retransmitted TCP flow bytes (src->dst)",
["RETRANSMITTED_OUT_PKTS"] = "Number of retransmitted TCP flow packets (dst->src)",
["RETRANSMITTED_OUT_BYTES"] = "Number of retransmitted TCP flow bytes (dst->src)",
["OOORDER_IN_PKTS"] = "Number of out of order TCP flow packets (dst->src)",
["OOORDER_OUT_PKTS"] = "Number of out of order TCP flow packets (dst->src)",
["UNTUNNELED_PROTOCOL"] = "Untunneled IP protocol byte",
["UNTUNNELED_IPV4_SRC_ADDR"] = "Untunneled IPv4 source address",
["UNTUNNELED_L4_SRC_PORT"] = "Untunneled IPv4 source port",
["UNTUNNELED_IPV4_DST_ADDR"] = "Untunneled IPv4 destination address",
["UNTUNNELED_L4_DST_PORT"] = "Untunneled IPv4 destination port",
["L7_PROTO"] = "Layer 7 protocol (numeric)",
["L7_PROTO_NAME"] = "Layer 7 protocol name",
["DOWNSTREAM_TUNNEL_ID"] = "Downstream tunnel identifier (e.g. GTP TEID) or 0 if unknown",
["FLOW_USER_NAME"] = "Flow Username",
["FLOW_SERVER_NAME"] = "Flow server name",
["PLUGIN_NAME"] = "Plugin name used by this flow (if any)",
["UNTUNNELED_IPV6_SRC_ADDR"] = "Untunneled IPv6 source address",
["UNTUNNELED_IPV6_DST_ADDR"] = "Untunneled IPv6 destination address",
["NUM_PKTS_TTL_EQ_1"] = "# packets with TTL = 1",
["NUM_PKTS_TTL_2_5"] = "# packets with TTL > 1 and TTL <= 5",
["NUM_PKTS_TTL_5_32"] = "# packets with TTL > 5 and TTL <= 32",
["NUM_PKTS_TTL_32_64"] = "# packets with TTL > 32 and <= 64 ",
["NUM_PKTS_TTL_64_96"] = "# packets with TTL > 64 and <= 96",
["NUM_PKTS_TTL_96_128"] = "# packets with TTL > 96 and <= 128",
["NUM_PKTS_TTL_128_160"] = "# packets with TTL > 128 and <= 160",
["NUM_PKTS_TTL_160_192"] = "# packets with TTL > 160 and <= 192",
["NUM_PKTS_TTL_192_224"] = "# packets with TTL > 192 and <= 224",
["NUM_PKTS_TTL_224_255"] = "# packets with TTL > 224 and <= 255",
["IN_SRC_OSI_SAP"] = "OSI Source SAP (OSI Traffic Only)",
["OUT_DST_OSI_SAP"] = "OSI Destination SAP (OSI Traffic Only)",
["DURATION_IN"] = "Client to Server stream duration (msec)",
["DURATION_OUT"] = "Client to Server stream duration (msec)",
["TCP_WIN_MIN_IN"] = "Min TCP Window (src->dst)",
["TCP_WIN_MAX_IN"] = "Max TCP Window (src->dst)",
["TCP_WIN_MSS_IN"] = "TCP Max Segment Size (src->dst)",
["TCP_WIN_SCALE_IN"] = "TCP Window Scale (src->dst)",
["TCP_WIN_MIN_OUT"] = "Min TCP Window (dst->src)",
["TCP_WIN_MAX_OUT"] = "Max TCP Window (dst->src)",
["TCP_WIN_MSS_OUT"] = "TCP Max Segment Size (dst->src)",
["TCP_WIN_SCALE_OUT"] = "TCP Window Scale (dst->src)",
-- MYSQL
["MYSQL_SERVER_VERSION"] = "MySQL server version",
["MYSQL_USERNAME"] = "MySQL username",
["MYSQL_DB"] = "MySQL database in use",
["MYSQL_QUERY"] = "MySQL Query",
["MYSQL_RESPONSE"] = "MySQL server response",
["MYSQL_APPL_LATENCY_USEC"] = "MySQL request->response latecy (usec)",
["SRC_AS_PATH_1"] = "Src AS path position 1",
["SRC_AS_PATH_2"] = "Src AS path position 2",
["SRC_AS_PATH_3"] = "Src AS path position 3",
["SRC_AS_PATH_4"] = "Src AS path position 4",
["SRC_AS_PATH_5"] = "Src AS path position 5",
["SRC_AS_PATH_6"] = "Src AS path position 6",
["SRC_AS_PATH_7"] = "Src AS path position 7",
["SRC_AS_PATH_8"] = "Src AS path position 8",
["SRC_AS_PATH_9"] = "Src AS path position 9",
["SRC_AS_PATH_10"] = "Src AS path position 10",
["DST_AS_PATH_1"] = "Dest AS path position 1",
["DST_AS_PATH_2"] = "Dest AS path position 2",
["DST_AS_PATH_3"] = "Dest AS path position 3",
["DST_AS_PATH_4"] = "Dest AS path position 4",
["DST_AS_PATH_5"] = "Dest AS path position 5",
["DST_AS_PATH_6"] = "Dest AS path position 6",
["DST_AS_PATH_7"] = "Dest AS path position 7",
["DST_AS_PATH_8"] = "Dest AS path position 8",
["DST_AS_PATH_9"] = "Dest AS path position 9",
["DST_AS_PATH_10"] = "Dest AS path position 10",
-- DHCP
["DHCP_CLIENT_MAC"] = "MAC of the DHCP client",
["DHCP_CLIENT_IP"] = "DHCP assigned client IPv4 address",
["DHCP_CLIENT_NAME"] = "DHCP client name",
["DHCP_REMOTE_ID"] = "DHCP agent remote Id",
["DHCP_SUBSCRIBER_ID"] = "DHCP subscribed Id",
["DHCP_MESSAGE_TYPE"] = "DHCP message type",
-- DIAMETER
["DIAMETER_REQ_MSG_TYPE"] = "DIAMETER Request Msg Type",
["DIAMETER_RSP_MSG_TYPE"] = "DIAMETER Response Msg Type",
["DIAMETER_REQ_ORIGIN_HOST"] = "DIAMETER Origin Host Request",
["DIAMETER_RSP_ORIGIN_HOST"] = "DIAMETER Origin Host Response",
["DIAMETER_REQ_USER_NAME"] = "DIAMETER Request User Name",
["DIAMETER_RSP_RESULT_CODE"] = "DIAMETER Response Result Code",
["DIAMETER_EXP_RES_VENDOR_ID"] = "DIAMETER Response Experimental Result Vendor Id",
["DIAMETER_EXP_RES_RESULT_CODE"] = "DIAMETER Response Experimental Result Code",
-- DNS
["DNS_QUERY"] = "DNS query",
["DNS_QUERY_ID"] = "DNS query transaction Id",
["DNS_QUERY_TYPE"] = "DNS query type (e.g. 1=A, 2=NS..)",
["DNS_RET_CODE"] = "DNS return code (e.g. 0=no error)",
["DNS_NUM_ANSWERS"] = "DNS # of returned answers",
["DNS_TTL_ANSWER"] = "TTL of the first A record (if any)",
["DNS_RESPONSE"] = "DNS response(s)",
-- FTP
["FTP_LOGIN"] = "FTP client login",
["FTP_PASSWORD"] = "FTP client password",
["FTP_COMMAND"] = "FTP client command",
["FTP_COMMAND_RET_CODE"] = "FTP client command return code",
-- GTP
["GTPV0_REQ_MSG_TYPE"] = "GTPv0 Request Msg Type",
["GTPV0_RSP_MSG_TYPE"] = "GTPv0 Response Msg Type",
["GTPV0_TID"] = "GTPv0 Tunnel Identifier",
["GTPV0_APN_NAME"] = "GTPv0 APN Name",
["GTPV0_END_USER_IP"] = "GTPv0 End User IP Address",
["GTPV0_END_USER_MSISDN"] = "GTPv0 End User MSISDN",
["GTPV0_RAI_MCC"] = "GTPv0 Mobile Country Code",
["GTPV0_RAI_MNC"] = "GTPv0 Mobile Network Code",
["GTPV0_RAI_CELL_LAC"] = "GTPv0 Cell Location Area Code",
["GTPV0_RAI_CELL_RAC"] = "GTPv0 Cell Routing Area Code",
["GTPV0_RESPONSE_CAUSE"] = "GTPv0 Cause of Operation",
["GTPV1_REQ_MSG_TYPE"] = "GTPv1 Request Msg Type",
["GTPV1_RSP_MSG_TYPE"] = "GTPv1 Response Msg Type",
["GTPV1_C2S_TEID_DATA"] = "GTPv1 Client->Server TunnelId Data",
["GTPV1_C2S_TEID_CTRL"] = "GTPv1 Client->Server TunnelId Control",
["GTPV1_S2C_TEID_DATA"] = "GTPv1 Server->Client TunnelId Data",
["GTPV1_S2C_TEID_CTRL"] = "GTPv1 Server->Client TunnelId Control",
["GTPV1_END_USER_IP"] = "GTPv1 End User IP Address",
["GTPV1_END_USER_IMSI"] = "GTPv1 End User IMSI",
["GTPV1_END_USER_MSISDN"] = "GTPv1 End User MSISDN",
["GTPV1_END_USER_IMEI"] = "GTPv1 End User IMEI",
["GTPV1_APN_NAME"] = "GTPv1 APN Name",
["GTPV1_RAI_MCC"] = "GTPv1 RAI Mobile Country Code",
["GTPV1_RAI_MNC"] = "GTPv1 RAI Mobile Network Code",
["GTPV1_RAI_LAC"] = "GTPv1 RAI Location Area Code",
["GTPV1_RAI_RAC"] = "GTPv1 RAI Routing Area Code",
["GTPV1_ULI_MCC"] = "GTPv1 ULI Mobile Country Code",
["GTPV1_ULI_MNC"] = "GTPv1 ULI Mobile Network Code",
["GTPV1_ULI_CELL_LAC"] = "GTPv1 ULI Cell Location Area Code",
["GTPV1_ULI_CELL_CI"] = "GTPv1 ULI Cell CI",
["GTPV1_ULI_SAC"] = "GTPv1 ULI SAC",
["GTPV1_RESPONSE_CAUSE"] = "GTPv1 Cause of Operation",
["GTPV2_REQ_MSG_TYPE"] = "GTPv2 Request Msg Type",
["GTPV2_RSP_MSG_TYPE"] = "GTPv2 Response Msg Type",
["GTPV2_C2S_S1U_GTPU_TEID"] = "GTPv2 Client->Svr S1U GTPU TEID",
["GTPV2_C2S_S1U_GTPU_IP"] = "GTPv2 Client->Svr S1U GTPU IP",
["GTPV2_S2C_S1U_GTPU_TEID"] = "GTPv2 Srv->Client S1U GTPU TEID",
["GTPV2_S2C_S1U_GTPU_IP"] = "GTPv2 Srv->Client S1U GTPU IP",
["GTPV2_END_USER_IMSI"] = "GTPv2 End User IMSI",
["GTPV2_END_USER_MSISDN"] = "GTPv2 End User MSISDN",
["GTPV2_APN_NAME"] = "GTPv2 APN Name",
["GTPV2_ULI_MCC"] = "GTPv2 Mobile Country Code",
["GTPV2_ULI_MNC"] = "GTPv2 Mobile Network Code",
["GTPV2_ULI_CELL_TAC"] = "GTPv2 Tracking Area Code",
["GTPV2_ULI_CELL_ID"] = "GTPv2 Cell Identifier",
["GTPV2_RESPONSE_CAUSE"] = "GTPv2 Cause of Operation",
-- HTTP
["HTTP_URL"] = "HTTP URL",
["HTTP_METHOD"] = "HTTP METHOD",
["HTTP_RET_CODE"] = "HTTP return code (e.g. 200, 304...)",
["HTTP_REFERER"] = "HTTP Referer",
["HTTP_UA"] = "HTTP User Agent",
["HTTP_MIME"] = "HTTP Mime Type",
["HTTP_HOST"] = "HTTP Host Name",
["HTTP_FBOOK_CHAT"] = "HTTP Facebook Chat",
["HTTP_SITE"] = "HTTP server without host name",
-- Oracle
["ORACLE_USERNAME"] = "Oracle Username",
["ORACLE_QUERY"] = "Oracle Query",
["ORACLE_RSP_CODE"] = "Oracle Response Code",
["ORACLE_RSP_STRING"] = "Oracle Response String",
["ORACLE_QUERY_DURATION"] = "Oracle Query Duration (msec)",
-- Process
['SRC_PROC_PID'] = "Client Process PID",
['SRC_PROC_NAME'] = "Client Process Name",
['SRC_PROC_UID'] = "Client process UID",
['SRC_PROC_USER_NAME'] = "Client process User Name",
['SRC_FATHER_PROC_PID'] = "Client Father Process PID",
['SRC_FATHER_PROC_NAME'] = "Client Father Process Name",
['SRC_PROC_ACTUAL_MEMORY'] = "Client Process Used Memory (KB)",
['SRC_PROC_PEAK_MEMORY'] = "Client Process Peak Memory (KB)",
['SRC_PROC_AVERAGE_CPU_LOAD'] = "Client Process Average Process CPU Load (%)",
['SRC_PROC_NUM_PAGE_FAULTS'] = "Client Process Number of page faults",
['SRC_PROC_PCTG_IOWAIT'] = "Client process iowait time % (% * 100)",
['DST_PROC_PID'] = "Server Process PID",
['DST_PROC_UID'] = "Server process UID",
['DST_PROC_NAME'] = "Server Process Name",
['DST_PROC_USER_NAME'] = "Server process User Name",
['DST_FATHER_PROC_PID'] = "Server Father Process PID",
['DST_FATHER_PROC_NAME'] = "Server Father Process Name",
['DST_PROC_ACTUAL_MEMORY'] = "Server Process Used Memory (KB)",
['DST_PROC_PEAK_MEMORY'] = "Server Process Peak Memory (KB)",
['DST_PROC_AVERAGE_CPU_LOAD'] = "Server Process Average Process CPU Load (%)",
['DST_PROC_NUM_PAGE_FAULTS'] = "Server Process Number of page faults",
['DST_PROC_PCTG_IOWAIT'] = "Server process iowait time % (% * 100)",
-- Radius
["RADIUS_REQ_MSG_TYPE"] = "RADIUS Request Msg Type",
["RADIUS_RSP_MSG_TYPE"] = "RADIUS Response Msg Type",
["RADIUS_USER_NAME"] = "RADIUS User Name (Access Only)",
["RADIUS_CALLING_STATION_ID"] = "RADIUS Calling Station Id",
["RADIUS_CALLED_STATION_ID"] = "RADIUS Called Station Id",
["RADIUS_NAS_IP_ADDR"] = "RADIUS NAS IP Address",
["RADIUS_NAS_IDENTIFIER"] = "RADIUS NAS Identifier",
["RADIUS_USER_IMSI"] = "RADIUS User IMSI (Extension)",
["RADIUS_USER_IMEI"] = "RADIUS User MSISDN (Extension)",
["RADIUS_FRAMED_IP_ADDR"] = "RADIUS Framed IP",
["RADIUS_ACCT_SESSION_ID"] = "RADIUS Accounting Session Name",
["RADIUS_ACCT_STATUS_TYPE"] = "RADIUS Accounting Status Type",
["RADIUS_ACCT_IN_OCTETS"] = "RADIUS Accounting Input Octets",
["RADIUS_ACCT_OUT_OCTETS"] = "RADIUS Accounting Output Octets",
["RADIUS_ACCT_IN_PKTS"] = "RADIUS Accounting Input Packets",
["RADIUS_ACCT_OUT_PKTS"] = "RADIUS Accounting Output Packets",
-- VoIP
['RTP_MOS'] = "Rtp Voice Quality",
['RTP_R_FACTOR'] = "Rtp Voice Quality Metric (%)", --http://tools.ietf.org/html/rfc3611#section-4.7.5
['RTP_RTT'] = "Rtp Round Trip Time",
['RTP_IN_TRANSIT'] = "RTP Transit (value * 100) (src->dst)",
['RTP_OUT_TRANSIT'] = "RTP Transit (value * 100) (dst->src)",
['RTP_FIRST_SSRC'] = "First flow RTP Sync Source ID",
['RTP_FIRST_TS'] = "First flow RTP timestamp",
['RTP_LAST_SSRC'] = "Last flow RTP Sync Source ID",
['RTP_LAST_TS'] = "Last flow RTP timestamp",
['RTP_IN_JITTER'] = "Rtp Incoming Packet Delay Variation",
['RTP_OUT_JITTER'] = "Rtp Out Coming Packet Delay Variation",
['RTP_IN_PKT_LOST'] = "Rtp Incoming Packets Lost",
['RTP_OUT_PKT_LOST'] = "Rtp Out Coming Packets Lost",
['RTP_OUT_PAYLOAD_TYPE'] = "Rtp Out Coming Payload Type",
['RTP_IN_MAX_DELTA'] = "Max delta (ms*100) between consecutive pkts (src->dst)",
['RTP_OUT_MAX_DELTA'] = "Max delta (ms*100) between consecutive pkts (dst->src)",
['RTP_IN_PAYLOAD_TYPE'] = "Rtp Incoming Payload Type",
['RTP_SIP_CALL_ID'] = "SIP call-id corresponding to this RTP stream",
['SIP_CALL_ID'] = "SIP call-id",
['SIP_CALLING_PARTY'] = "SIP Call initiator",
['SIP_CALLED_PARTY'] = "SIP Called party",
['SIP_RTP_CODECS'] = "SIP RTP codecs",
['SIP_INVITE_TIME'] = "SIP time (epoch) of INVITE",
['SIP_TRYING_TIME'] = "SIP time (epoch) of Trying",
['SIP_RINGING_TIME'] = "SIP time (epoch) of RINGING",
['SIP_INVITE_OK_TIME'] = "SIP time (epoch) of INVITE OK",
['SIP_INVITE_FAILURE_TIME'] = "SIP time (epoch) of INVITE FAILURE",
['SIP_BYE_TIME'] = "SIP time (epoch) of BYE",
['SIP_BYE_OK_TIME'] = "SIP time (epoch) of BYE OK",
['SIP_CANCEL_TIME'] = "SIP time (epoch) of CANCEL",
['SIP_CANCEL_OK_TIME'] = "SIP time (epoch) of CANCEL OK",
['SIP_RTP_IPV4_SRC_ADDR'] = "SIP RTP stream source IP",
['SIP_RTP_L4_SRC_PORT'] = "SIP RTP stream source port",
['SIP_RTP_IPV4_DST_ADDR'] = "SIP RTP stream dest IP",
['SIP_RTP_L4_DST_PORT'] = "SIP RTP stream dest port",
['SIP_FAILURE_CODE'] = "SIP failure response code",
['SIP_RESPONSE_CODE'] = "SIP failure response code",
['SIP_REASON_CAUSE'] = "SIP Cancel/Bye/Failure reason cause",
['SIP_C_IP'] = "SIP C IP adresses",
['SIP_CALL_STATE'] = "Sip Call State",
-- S1AP
["S1AP_ENB_UE_S1AP_ID"] = "S1AP ENB Identifier",
["S1AP_MME_UE_S1AP_ID"] = "S1AP MME Identifier",
["S1AP_MSG_EMM_TYPE_MME_TO_ENB"] = "S1AP EMM Message Type from MME to ENB",
["S1AP_MSG_ESM_TYPE_MME_TO_ENB"] = "S1AP ESM Message Type from MME to ENB",
["S1AP_MSG_EMM_TYPE_ENB_TO_MME"] = "S1AP EMM Message Type from ENB to MME",
["S1AP_MSG_ESM_TYPE_ENB_TO_MME"] = "S1AP ESM Message Type from ENB to MME",
["S1AP_CAUSE_ENB_TO_MME"] = "S1AP Cause from ENB to MME",
["S1AP_DETAILED_CAUSE_ENB_TO_MME"] = "S1AP Detailed Cause from ENB to MME",
-- Mail
["SMTP_MAIL_FROM"] = "Mail sender",
["SMTP_RCPT_TO"] = "Mail recipient",
["POP_USER"] = "POP3 user login",
["IMAP_LOGIN"] = "Mail sender",
-- WHOIS
["WHOIS_DAS_DOMAIN"] = "Whois/DAS Domain name",
}
-- #######################
function getFlowKey(name)
v = rtemplate[tonumber(name)]
if(v == nil) then return(name) end
s = flow_fields_description[v]
if(s ~= nil) then
s = string.gsub(s, "<", "&lt;")
s = string.gsub(s, ">", "&gt;")
return(s)
else
return(name)
end
end
-- #######################

View file

@ -0,0 +1,26 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
sendHTTPHeader('text/html; charset=iso-8859-1')
ifid = getInterfaceId(ifname)
epoch = _GET["epoch"]
if (epoch == nil) then epoch = os.time() end
epoch = tonumber(epoch)
epoch_now = ntop.getMinuteRealEpoch(ifid, epoch)
if (epoch_now == 0) then
epoch_now = os.time()
end
epoch_before = ntop.getMinuteRealEpoch(ifid, epoch_now - 60)
if (epoch_before == 0) then
epoch_before = os.time() - 60
end
print(tostring(epoch_now).." "..tostring(epoch_before))

View file

@ -0,0 +1,931 @@
--
-- (C) 2013-15 - ntop.org
--
top_rrds = {
["bytes.rrd"] = "Traffic",
["packets.rrd"] = "Packets",
["drops.rrd"] = "Packet Drops",
["num_flows.rrd"] = "Active Flows",
["num_hosts.rrd"] = "Active Hosts",
["num_http_hosts.rrd"] = "Active HTTP Servers"
}
-- ########################################################
if(ntop.isPro()) then
package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path
require "nv_graph_utils"
end
-- ########################################################
function navigatedir(url, label, base, path, go_deep, print_html)
local shown = false
local to_skip = false
--print("<li> <b>(d)</b> "..path.." </li>\n")
local ret = { }
local do_debug = false
rrds = ntop.readdir(path)
table.sort(rrds)
for k,v in pairsByKeys(rrds, asc) do
if(v ~= nil) then
p = fixPath(path .. "/" .. v)
if(ntop.isdir(p)) then
if(go_deep) then
r = navigatedir(url, label.."/"..v, base, p, print_html)
for k,v in pairs(r) do
ret[k] = v
if(do_debug) then print(v.."<br>\n") end
end
end
else
if(top_rrds[v] == nil) then
if(label == "*") then
to_skip = true
else
if(not(shown) and not(to_skip)) then
if(print_html) then
print('<li class="dropdown-submenu"><a tabindex="-1" href="#">'..label..'</a>\n<ul class="dropdown-menu">\n')
end
shown = true
end
end
what = string.sub(path.."/"..v, string.len(base)+2)
label = string.sub(v, 1, string.len(v)-4)
label = l4Label(string.gsub(label, "_", " "))
ret[label] = what
if(do_debug) then print(what.."<br>\n") end
if(print_html) then print("<li> <A HREF="..url..what..">"..label.."</A> </li>\n") end
end
end
end
end
if(shown) then
if(print_html) then print('</ul></li>\n') end
end
return(ret)
end
-- ########################################################
function breakdownBar(sent, sentLabel, rcvd, rcvdLabel)
if((sent+rcvd) > 0) then
sent2rcvd = round((sent * 100) / (sent+rcvd), 0)
print('<div class="progress"><div class="progress-bar progress-bar-warning" aria-valuenow="'.. sent2rcvd..'" aria-valuemin="0" aria-valuemax="100" style="width: ' .. sent2rcvd.. '%;">'..sentLabel)
print('</div><div class="progress-bar progress-bar-info" aria-valuenow="'.. (100 -sent2rcvd)..'" aria-valuemin="0" aria-valuemax="100" style="width: ' .. (100-sent2rcvd) .. '%;">' .. rcvdLabel .. '</div></div>')
else
print('&nbsp;')
end
end
-- ########################################################
function percentageBar(total, value, valueLabel)
if(total > 0) then
pctg = round((value * 100) / total, 0)
print('<div class="progress"><div class="progress-bar progress-bar-warning" aria-valuenow="'.. pctg..'" aria-valuemin="0" aria-valuemax="100" style="width: ' .. pctg.. '%;">'..valueLabel)
print('</div></div>')
else
print('&nbsp;')
end
end
-- ########################################################
function getRRDName(ifid, host, rrdFile)
rrdname = fixPath(dirs.workingdir .. "/" .. ifid .. "/rrd/")
if(host ~= nil) then
rrdname = rrdname .. getPathFromKey(host) .. "/"
end
return(rrdname .. rrdFile)
end
-- ########################################################
zoom_vals = {
{ "5m", "now-300s", 60*5 },
{ "10m", "now-600s", 60*10 },
{ "1h", "now-1h", 60*60*1 },
{ "3h", "now-3h", 60*60*3 },
{ "6h", "now-6h", 60*60*6 },
{ "12h", "now-12h", 60*60*12 },
{ "1d", "now-1d", 60*60*24 },
{ "1w", "now-1w", 60*60*24*7 },
{ "2w", "now-2w", 60*60*24*14 },
{ "1M", "now-1mon", 60*60*24*31 },
{ "6M", "now-6mon", 60*60*24*31*6 },
{ "1Y", "now-1y", 60*60*24*366 }
}
function getZoomAtPos(cur_zoom, pos_offset)
local pos = 1
local new_zoom_level = cur_zoom
for k,v in pairs(zoom_vals) do
if(zoom_vals[k][1] == cur_zoom) then
if (pos+pos_offset >= 1 and pos+pos_offset < 13) then
new_zoom_level = zoom_vals[pos+pos_offset][1]
break
end
end
pos = pos + 1
end
return new_zoom_level
end
-- ########################################################
function drawPeity(ifid, host, rrdFile, zoomLevel, selectedEpoch)
rrdname = getRRDName(ifid, host, rrdFile)
if(zoomLevel == nil) then
zoomLevel = "1h"
end
nextZoomLevel = zoomLevel;
epoch = tonumber(selectedEpoch);
for k,v in ipairs(zoom_vals) do
if(zoom_vals[k][1] == zoomLevel) then
if(k > 1) then
nextZoomLevel = zoom_vals[k-1][1]
end
if(epoch) then
start_time = epoch - zoom_vals[k][3]/2
end_time = epoch + zoom_vals[k][3]/2
else
start_time = zoom_vals[k][2]
end_time = "now"
end
end
end
--print("=> Found "..rrdname.."<p>\n")
if(ntop.notEmptyFile(rrdname)) then
--io.write("=> Found ".. start_time .. "|" .. end_time .. "<p>\n")
local fstart, fstep, fnames, fdata = ntop.rrd_fetch(rrdname, 'AVERAGE', start_time..", end_time..")
local max_num_points = 512 -- This is to avoid having too many points and thus a fat graph
local num_points_found = table.getn(fdata)
local sample_rate = round(num_points_found / max_num_points)
local num_points = 0
local step = 1
local series = {}
if(sample_rate < 1) then
sample_rate = 1
end
-- print("=> "..num_points_found.."[".. sample_rate .."]["..fstart.."]<p>")
id = 0
num = 0
total = 0
sample_rate = sample_rate-1
points = {}
for i, v in ipairs(fdata) do
timestamp = fstart + (i-1)*fstep
num_points = num_points + 1
local elemId = 1
for _, w in ipairs(v) do
if(w ~= w) then
-- This is a NaN
v = 0
else
v = tonumber(w)
if(v < 0) then
v = 0
end
end
value = v*8 -- bps
total = total + value
if(id == sample_rate) then
points[num] = round(value)..""
num = num+1
id = 0
else
id = id + 1
end
elemId = elemId + 1
end
end
end
print("<td class=\"text-right\">"..round(total).."</td><td> <span class=\"peity-line\">")
for i=0,10 do
if(i > 0) then print(",") end
print(points[i])
end
print("</span>\n")
end
-- ########################################################
function drawRRD(ifid, host, rrdFile, zoomLevel, baseurl, show_timeseries,
selectedEpoch, selected_epoch_sanitized, topArray)
local debug_rrd = false
if(ntop.isPro()) then
drawProGraph(ifid, host, rrdFile, zoomLevel, baseurl, show_timeseries, selectedEpoch, selected_epoch_sanitized, topArray)
return
end
dirs = ntop.getDirs()
rrdname = getRRDName(ifid, host, rrdFile)
names = {}
series = {}
if(zoomLevel == nil) then
zoomLevel = "1h"
end
nextZoomLevel = zoomLevel;
epoch = tonumber(selectedEpoch);
for k,v in ipairs(zoom_vals) do
if(zoom_vals[k][1] == zoomLevel) then
if(k > 1) then
nextZoomLevel = zoom_vals[k-1][1]
end
if(epoch) then
start_time = epoch - zoom_vals[k][3]/2
end_time = epoch + zoom_vals[k][3]/2
else
start_time = zoom_vals[k][2]
end_time = "now"
end
end
end
local maxval_bits_time = 0
local maxval_bits = 0
local minval_bits = 0
local minval_bits_time = 0
local lastval_bits = 0
local lastval_bits_time = 0
local total_bytes = 0
local num_points = 0
local step = 1
prefixLabel = l4Label(string.gsub(rrdFile, ".rrd", ""))
-- io.write(prefixLabel.."\n")
if(prefixLabel == "Bytes") then
prefixLabel = "Traffic"
end
if(ntop.notEmptyFile(rrdname)) then
-- print("=> Found "..rrdname.."<p>\n")
-- print("=> "..rrdname)
-- io.write("=> *** ".. start_time .. "|" .. end_time .. "<p>\n")
local fstart, fstep, fnames, fdata = ntop.rrd_fetch(rrdname, 'AVERAGE', start_time, end_time)
--print("=> here we go")
local max_num_points = 600 -- This is to avoid having too many points and thus a fat graph
local num_points_found = table.getn(fdata)
local sample_rate = round(num_points_found / max_num_points)
if(sample_rate < 1) then
sample_rate = 1
end
-- DEBUG
--tprint(fdata, 1)
step = fstep
num = 0
for i, n in ipairs(fnames) do
names[num] = prefixLabel
-- if(prefixLabel ~= firstToUpper(n)) then names[num] = names[num] .. " (" .. firstToUpper(n)..")" end
num = num + 1
--io.write(prefixLabel.."\n")
--print(num.."\n")
end
id = 0
sampling = 0
--sample_rate = 1
sample_rate = sample_rate-1
accumulated = 0
for i, v in ipairs(fdata) do
s = {}
s[0] = fstart + (i-1)*fstep
num_points = num_points + 1
local elemId = 1
for _, w in ipairs(v) do
if(w ~= w) then
-- This is a NaN
v = 0
else
--io.write(w.."\n")
v = tonumber(w)
if(v < 0) then
v = 0
end
end
if(v > 0) then
lastval_bits_time = s[0]
lastval_bits = v
end
s[elemId] = v*8 -- bps
--if(s[elemId] > 0) then io.write("[".. elemId .. "]=" .. s[elemId] .."\n") end
elemId = elemId + 1
end
total_bytes = total_bytes + v*fstep
--if((v*fstep) > 0) then io.write(" | " .. (v*fstep) .." | [sampling: ".. sampling .. "/" .. sample_rate.."]\n") end
if(sampling == sample_rate) then
if(sample_rate > 0) then
s[1] = accumulated / sample_rate
end
series[id] = s
id = id + 1
sampling = 0
accumulated = 0
else
accumulated = accumulated + s[1]
sampling = sampling + 1
end
end
for key, value in pairs(series) do
local t = 0
for elemId=0,(num-1) do
--io.write(key.."="..value[elemId+1].. "\n")
t = t + value[elemId+1] -- bps
end
t = t * step
if(((minval_bits_time == 0) or (minval_bits >= t)) and (value[0] < lastval_bits_time)) then
--io.write(value[0].."\t".. t .. "\t".. lastval_bits_time .. "\n")
minval_bits_time = value[0]
minval_bits = t
end
if((maxval_bits_time == 0) or (maxval_bits <= t)) then
maxval_bits_time = value[0]
maxval_bits = t
end
end
print [[
<style>
#chart_container {
display: inline-block;
font-family: Arial, Helvetica, sans-serif;
}
#chart {
float: left;
}
#legend {
float: left;
margin-left: 15px;
color: black;
background: white;
}
#y_axis {
float: left;
width: 40px;
}
</style>
<div>
]]
if(show_timeseries == 1) then
print [[
<div class="btn-group">
<button class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">Timeseries <span class="caret"></span></button>
<ul class="dropdown-menu">
]]
for k,v in pairs(top_rrds) do
print('<li><a href="'..baseurl .. '&rrd_file=' .. k .. '&graph_zoom=' .. zoomLevel .. '&epoch=' .. (selectedEpoch or '') .. '">'.. v ..'</a></li>\n')
end
print('<li class="divider"></li>\n')
dirs = ntop.getDirs()
p = dirs.workingdir .. "/" .. purifyInterfaceName(ifid) .. "/rrd/"
if(host ~= nil) then
p = p .. getPathFromKey(host)
go_deep = true
else
go_deep = false
end
d = fixPath(p)
navigatedir(baseurl .. '&graph_zoom=' .. zoomLevel .. '&epoch=' .. (selectedEpoch or '')..'&rrd_file=', "*", d, d, go_deep, true)
print [[
</ul>
</div><!-- /btn-group -->
]]
end
print('&nbsp;Timeframe: <div class="btn-group" data-toggle="buttons" id="graph_zoom">\n')
for k,v in ipairs(zoom_vals) do
print('<label class="btn btn-link ')
if(zoom_vals[k][1] == zoomLevel) then
print("active")
end
print('">')
print('<input type="radio" name="options" id="zoom_level_'..k..'" value="'..baseurl .. '&rrd_file=' .. rrdFile .. '&graph_zoom=' .. zoom_vals[k][1] .. '&epoch=' .. (selectedEpoch or '') ..'">'.. zoom_vals[k][1] ..'</input></label>\n')
end
print [[
</div>
</div>
<script>
$('input:radio[id^=zoom_level_]').change( function() {
window.open(this.value,'_self',false);
});
</script>
<br />
<p>
<div style="margin-left: 10px; display: table">
<div id="chart_container" style="display: table-row">
<table style="border: 0">
<table class="table table-bordered table-striped" style="border: 0; margin-right: 10px; display: table-cell">
]]
print(' <tr><th>&nbsp;</th><th>Time</th><th>Value</th></tr>\n')
if(string.contains(rrdFile, "num_") or string.contains(rrdFile, "packets") or string.contains(rrdFile, "drops")) then
if(string.contains(rrdFile, "num_")) then
formatter_fctn = "fint"
else
formatter_fctn = "fpackets"
end
print(' <tr><th>Min</th><td>' .. os.date("%x %X", minval_bits_time) .. '</td><td>' .. formatValue(round(minval_bits/step), 1) .. '</td></tr>\n')
print(' <tr><th>Max</th><td>' .. os.date("%x %X", maxval_bits_time) .. '</td><td>' .. formatValue(round(maxval_bits/step), 1) .. '</td></tr>\n')
print(' <tr><th>Last</th><td>' .. os.date("%x %X", last_time) .. '</td><td>' .. formatValue(round(lastval_bits/step), 1) .. '</td></tr>\n')
print(' <tr><th>Average</th><td colspan=2>' .. formatValue(round(total_bytes*8/(step*num_points), 2)) .. '</td></tr>\n')
print(' <tr><th>Total Number</th><td colspan=2>' .. formatValue(round(total_bytes)) .. '</td></tr>\n')
else
formatter_fctn = "fbits"
print(' <tr><th>Min</th><td>' .. os.date("%x %X", minval_bits_time) .. '</td><td>' .. bitsToSize(minval_bits/step) .. '</td></tr>\n')
print(' <tr><th>Max</th><td>' .. os.date("%x %X", maxval_bits_time) .. '</td><td>' .. bitsToSize(maxval_bits/step) .. '</td></tr>\n')
print(' <tr><th>Last</th><td>' .. os.date("%x %X", last_time) .. '</td><td>' .. bitsToSize(lastval_bits/step) .. '</td></tr>\n')
print(' <tr><th>Average</th><td colspan=2>' .. bitsToSize(total_bytes*8/(step*num_points)) .. '</td></tr>\n')
print(' <tr><th>Total Traffic</th><td colspan=2>' .. bytesToSize(total_bytes) .. '</td></tr>\n')
end
print(' <tr><th>Selection Time</th><td colspan=2><div id=when></div></td></tr>\n')
print(' <tr><th>Minute<br>Top Talkers</th><td colspan=2><div id=talkers></div></td></tr>\n')
print [[
</table>
</td></tr>
<tr><td><div id="legend"></div></td><td><div id="chart_legend"></div></td></tr>
<tr><td colspan=2>
</table>
<p><font color=lightgray><small>NOTE: Click on the graph to zoom.</small></font>
<div id="y_axis"></div>
<div id="chart" style="margin-right: 50px; margin-left: 10px; display: table-cell"></div>
</div>
</div>
<script>
var palette = new Rickshaw.Color.Palette();
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 600,
height: 300,
renderer: 'area',
series: [
]]
if(names ~= nil) then
for elemId=0,(num-1) do
if(elemId > 0) then
print ","
end
print ("{\nname: '".. names[elemId] .. "',\n")
print("color: palette.color(),\ndata: [\n")
n = 0
for key, value in pairs(series) do
if(n > 0) then
print(",\n")
end
print ("\t{ x: ".. value[0] .. ", y: ".. value[elemId+1] .. " }")
n = n + 1
end
print("\n]}\n")
end
end
print [[
]
} );
graph.render();
var chart_legend = document.querySelector('#chart_legend');
function fdate(when) {
var epoch = when*1000;
var d = new Date(epoch);
return(d);
}
function fbits(bits) {
var sizes = ['bps', 'Kbit/s', 'Mbit/s', 'Gbit/s', 'Tbit/s'];
if(bits == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bits) / Math.log(1024)));
return Math.round(bits / Math.pow(1024, i), 2) + ' ' + sizes[i];
}
function capitaliseFirstLetter(string)
{
return string.charAt(0).toUpperCase() + string.slice(1);
}
/**
* Convert number of bytes into human readable format
*
* @param integer bytes Number of bytes to convert
* @param integer precision Number of digits after the decimal separator
* @return string
*/
function formatBytes(bytes, precision)
{
var kilobyte = 1024;
var megabyte = kilobyte * 1024;
var gigabyte = megabyte * 1024;
var terabyte = gigabyte * 1024;
if((bytes >= 0) && (bytes < kilobyte)) {
return bytes + ' B';
} else if((bytes >= kilobyte) && (bytes < megabyte)) {
return (bytes / kilobyte).toFixed(precision) + ' KB';
} else if((bytes >= megabyte) && (bytes < gigabyte)) {
return (bytes / megabyte).toFixed(precision) + ' MB';
} else if((bytes >= gigabyte) && (bytes < terabyte)) {
return (bytes / gigabyte).toFixed(precision) + ' GB';
} else if(bytes >= terabyte) {
return (bytes / terabyte).toFixed(precision) + ' TB';
} else {
return bytes + ' B';
}
}
var Hover = Rickshaw.Class.create(Rickshaw.Graph.HoverDetail, {
graph: graph,
xFormatter: function(x) { return new Date( x * 1000 ); },
yFormatter: function(bits) { return(]] print(formatter_fctn) print [[(bits)); },
render: function(args) {
var graph = this.graph;
var points = args.points;
var point = points.filter( function(p) { return p.active } ).shift();
if(point.value.y === null) return;
var formattedXValue = fdate(point.value.x); // point.formattedXValue;
var formattedYValue = ]]
print(formatter_fctn)
print [[(point.value.y); // point.formattedYValue;
var infoHTML = "";
var seconds;
$.ajax ({
type: 'GET',
url: ']]
print(ntop.getHttpPrefix().."/lua/modules/get_real_epochs.lua?epoch='+point.value.x,")
print[[
data: { epoch: point.value.x },
async: false,
success: function(content) {
var res = content.split(" ");
seconds = parseInt(res[0]) - parseInt(res[1]);
}
});
infoHTML += "<ul>";
]]
if(topArray ~= nil) then
for n,v in pairs(topArray) do
modulename = n
sectionname = v["name"]
levels = v["levels"]
scriptname = v["script"]
key = v["key"]
if (string.lower(sectionname) ~= "top talkers") then
goto continue
end
-- Support only 1 or 2 levels by now
if (levels < 1 or levels > 2) then goto continue end
print [[
$.ajax({
type: 'GET',
url: ']]
print(ntop.getHttpPrefix().."/lua/top_generic.lua?m="..modulename.."&epoch='+point.value.x+'&addvlan=true")
if (levels == 2) then
print [[',
data: { epoch: point.value.x },
async: false,
success: function(content) {
var info = jQuery.parseJSON(content);]]
print [[
var elements = 0;
$.each(info, function(i, n) {
elements++;
return false;
});
if (elements > 0)
infoHTML += "<li>]]print(sectionname)print[[<ul>";]]
print[[
$.each(info, function(i, n) {
var nonempty = 0;
$.each(n, function(j, m) {
nonempty++;
return false;
});
if (nonempty != 0)
infoHTML += "<li>"+capitaliseFirstLetter(i)+" [Avg Traffic/sec]<ol>";
var items = 0;
$.each(n, function(j, m) {
if(items < 3) {
infoHTML += "<li><a href=']]
print(scriptname.."?"..key.."=")
print[["+m.address+"'>"+m.label; if ("]]print(sectionname)print[[".toLowerCase() == "Operating Systems") infoHTML += getOSIcon(m.label); if ("]]print(sectionname)print[[".toLowerCase() == "countries") infoHTML += " <img src=']] print(ntop.getHttpPrefix()) print [[/img/blank.gif' class='flag flag-"+m.label.toLowerCase()+"'>"; infoHTML += "</a>"; if (m.vlan != "0") infoHTML += " ("+m.vlanm+")"; infoHTML += " ("+]] print(formatter_fctn) print [[((m.value*8)/seconds)+")</li>";
items++;
}
});
if (nonempty != 0)
infoHTML += "</ol></li>";
});
infoHTML += "</ul></li></li>";
}
});
]]
elseif (levels == 1) then
print [[',
data: { epoch: point.value.x },
async: false,
success: function(content) {
var info = jQuery.parseJSON(content);
var items = 0;
$.each(info, function(i, n) {
]]
print('if(items == 0) infoHTML += "<li>'..sectionname..' [Avg Traffic/sec]<ol>";')
print[[
if(items < 3)
infoHTML += "<li><a href=']]
print(scriptname.."?"..key.."=")
print[["+n.label+"'>"+n.name+"</a>";]]
if (sectionname ~= "VLANs") then
print[[if (n.vlan != "0") infoHTML += " ("+n.vlanm+")"+]]
else
print[[infoHTML +=]]
end
print[[" ("+]] print(formatter_fctn) print [[((n.value*8)/seconds)+")</li>";
items++;
});
if(items > 0)
infoHTML += "</ol></li></ul>";
}
});
]]
end
::continue::
end
print[[infoHTML += "</ul>";]]
print [[
this.element.innerHTML = '';
this.element.style.left = graph.x(point.value.x) + 'px';
/*var xLabel = document.createElement('div');
xLabel.setAttribute("style", "opacity: 0.5; background-color: #EEEEEE; filter: alpha(opacity=0.5)");
xLabel.className = 'x_label';
xLabel.innerHTML = formattedXValue + infoHTML;
this.element.appendChild(xLabel);
*/
$('#when').html(formattedXValue);
$('#talkers').html(infoHTML);
var item = document.createElement('div');
item.className = 'item';
item.innerHTML = this.formatter(point.series, point.value.x, point.value.y, formattedXValue, formattedYValue, point);
item.style.top = this.graph.y(point.value.y0 + point.value.y) + 'px';
this.element.appendChild(item);
var dot = document.createElement('div');
dot.className = 'dot';
dot.style.top = item.style.top;
dot.style.borderColor = point.series.color;
this.element.appendChild(dot);
if(point.active) {
item.className = 'item active';
dot.className = 'dot active';
}
this.show();
if(typeof this.onRender == 'function') {
this.onRender(args);
}
// Put the selected graph epoch into the legend
//chart_legend.innerHTML = point.value.x; // Epoch
this.selected_epoch = point.value.x;
//event
}
} );
var hover = new Hover( { graph: graph } );
var legend = new Rickshaw.Graph.Legend( {
graph: graph,
element: document.getElementById('legend')
} );
//var axes = new Rickshaw.Graph.Axis.Time( { graph: graph } ); axes.render();
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph,
tickFormat: ]] print(formatter_fctn) print [[
});
yAxis.render();
$("#chart").click(function() {
if(hover.selected_epoch)
window.location.href = ']]
print(baseurl .. '&rrd_file=' .. rrdFile .. '&graph_zoom=' .. nextZoomLevel .. '&epoch=')
print[['+hover.selected_epoch;
});
</script>
]]
end
else
print("<div class=\"alert alert-danger\"><img src=".. ntop.getHttpPrefix() .. "/img/warning.png> File "..rrdname.." cannot be found</div>")
end
end
-- ########################################################
function create_rrd(name, step, ds)
if(not(ntop.exists(name))) then
if(enable_second_debug == 1) then io.write('Creating RRD ', name, '\n') end
ntop.rrd_create(
name,
step, -- step
'DS:' .. ds .. ':DERIVE:5:U:U',
'RRA:AVERAGE:0.5:1:86400', -- raw: 1 day = 86400
'RRA:AVERAGE:0.5:60:8096', -- 1 min resolution = 1 month
'RRA:AVERAGE:0.5:3600:2400', -- 1h resolution (3600 points) 2400 hours = 100 days
'RRA:AVERAGE:0.5:86400:365' -- 1d resolution (86400 points) 365 days
-- 'RRA:HWPREDICT:1440:0.1:0.0035:20'
)
end
end
function create_rrd_num(name, ds)
if(not(ntop.exists(name))) then
if(enable_second_debug == 1) then io.write('Creating RRD ', name, '\n') end
ntop.rrd_create(
name,
1, -- step
'DS:' .. ds .. ':GAUGE:5:0:U',
'RRA:AVERAGE:0.5:1:86400', -- raw: 1 day = 86400
'RRA:AVERAGE:0.5:3600:2400', -- 1h resolution (3600 points) 2400 hours = 100 days
'RRA:AVERAGE:0.5:86400:365' -- 1d resolution (86400 points) 365 days
-- 'RRA:HWPREDICT:1440:0.1:0.0035:20'
)
end
end
function makeRRD(basedir, ifname, rrdname, step, value)
name = fixPath(basedir .. "/" .. rrdname .. ".rrd")
if(string.contains(rrdname, "num_")) then
create_rrd_num(name, rrdname)
else
create_rrd(name, 1, rrdname)
end
ntop.rrd_update(name, "N:".. value)
if(enable_second_debug == 1) then io.write('Updating RRD ['.. ifname..'] '.. name .. " " .. value ..'\n') end
end
function createRRDcounter(path, step, verbose)
if(not(ntop.exists(name))) then
if(verbose) then print('Creating RRD ', name, '\n') end
ntop.rrd_create(
name,
step, -- step
'DS:sent:DERIVE:600:U:U',
'DS:rcvd:DERIVE:600:U:U',
'RRA:AVERAGE:0.5:1:7200', -- raw: 1 day = 1 * 24 = 24 * 300 sec = 7200
'RRA:AVERAGE:0.5:12:2400', -- 1h resolution (12 points) 2400 hours = 100 days
'RRA:AVERAGE:0.5:288:365' -- 1d resolution (288 points) 365 days
--'RRA:HWPREDICT:1440:0.1:0.0035:20'
)
end
end
-- ########################################################
function createSingleRRDcounter(path, verbose)
if(not(ntop.exists(path))) then
if(verbose) then print('Creating RRD ', path, '\n') end
ntop.rrd_create(
path,
300, -- step
'DS:num:DERIVE:600:U:U',
'RRA:AVERAGE:0.5:1:7200', -- raw: 1 day = 1 * 24 = 24 * 300 sec = 7200
'RRA:AVERAGE:0.5:12:2400', -- 1h resolution (12 points) 2400 hours = 100 days
'RRA:AVERAGE:0.5:288:365', -- 1d resolution (288 points) 365 days
'RRA:HWPREDICT:1440:0.1:0.0035:20')
end
end
-- ########################################################
function dumpSingleTreeCounters(basedir, label, host, verbose)
what = host[label]
if(what ~= nil) then
for k,v in pairs(what) do
for k1,v1 in pairs(v) do
-- print("-->"..k1.."/".. type(v1).."<--\n")
if(type(v1) == "table") then
for k2,v2 in pairs(v1) do
dname = fixPath(basedir.."/"..label.."/"..k.."/"..k1)
if(not(ntop.exists(dname))) then
ntop.mkdir(dname)
end
fname = dname..fixPath("/"..k2..".rrd")
createSingleRRDcounter(fname, verbose)
ntop.rrd_update(fname, "N:"..v2)
if(verbose) then print("\t"..fname.."\n") end
end
else
dname = fixPath(basedir.."/"..label.."/"..k)
if(not(ntop.exists(dname))) then
ntop.mkdir(dname)
end
fname = dname..fixPath("/"..k1..".rrd")
createSingleRRDcounter(fname, verbose)
ntop.rrd_update(fname, "N:"..v1)
if(verbose) then print("\t"..fname.."\n") end
end
end
end
end
end

View file

@ -0,0 +1,68 @@
--
-- (C) 2014-15-15 - ntop.org
--
-- Enable/disable Influx DB
use_influx = false
influx_user = ""
influx_pwd = ""
influx_url = "http://localhost:8086/db/ntopng/series?u=ntopng&p=ntopng"
-- Local variables
local influx_debug = false
local influx_old_value = { }
local influx_curr_value = { }
local json = require ("dkjson")
function load_last_influx(cache_key)
influx_old_value = ntop.getCache(cache_key)
-- io.write(influx_old_value.."\n")
if((influx_old_value == nil) or (influx_old_value == "")) then
influx_old_value = { }
else
influx_old_value = json.decode(influx_old_value)
if(influx_old_value == nil) then influx_old_value = { } end
end
end
function save_curr_influx(cache_key)
local j = json.encode(influx_curr_value)
-- if(influx_debug) then io.write(j.."\n") end
ntop.setCache(cache_key, j)
end
function diff_value_influx(ifname, key, current_value)
local v
if(influx_debug) then
if(current_value > 0) then
io.write("["..__FILE__()..":"..__LINE__().."] "..ifname.."|"..key.."="..current_value.."\n")
end
end
if(influx_old_value[ifname] == nil) then
influx_old_value[ifname] = { }
end
if(influx_old_value[ifname][key] == nil) then
influx_old_value[ifname][key] = current_value
end
if(influx_curr_value[ifname] == nil) then
influx_curr_value[ifname] = {}
end
influx_curr_value[ifname][key] = current_value
v = current_value-influx_old_value[ifname][key]
if(influx_debug
-- and (v > 0)
) then
io.write("["..__FILE__()..":"..__LINE__().."] ***> "..ifname.."|"..key.."="..v.." [current: "..current_value.."][old: ".. influx_old_value[ifname][key].."]\n")
end
return(v)
end

View file

@ -0,0 +1,187 @@
--
-- (C) 2013-15 - ntop.org
--
--- Simple class for JSON parsing
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
local parseElement
local function skipWhitespaces(content, pos)
local _,nend = content:find("^[ \n\r\t]+", pos)
if (nend ~= nil) then
return nend+1
else
return pos
end
end
local function parseNumber(content, pos)
-- Integer part
local integer_part = content:match('^-?[1-9]%d*', pos)
or content:match("^-?0", pos)
if not integer_part then
return nil
end
-- Decimal part
local lstart = pos + integer_part:len()
local decimal_part = content:match('^%.%d+', i) or ""
lstart = lstart + decimal_part:len()
-- Exponential
local exponent_part = content:match('^[eE][-+]?%d+', i) or ""
lstart = lstart + exponent_part:len()
local full_number_text = integer_part .. decimal_part .. exponent_part
local cnumber = tonumber(full_number_text)
if not cnumber then
return nil
end
return cnumber, lstart
end
local function parseString(content, pos)
if (content:sub(pos, pos) ~= '"') then
return ""
end
local i = pos + 1
local clen = content:len()
local val = ""
while (i <= clen) do
local c = content:sub(i, i)
if (c == '"') then
return val, i+1
end
val = val..c
i = i + 1
end
return ""
end
local function parseObject(content, pos)
if (content:sub(pos, pos) ~= '{') then
return {}, pos
end
local lstart = skipWhitespaces(content, pos+1)
local val = {}
-- Handle empty array
if (content:sub(lstart, lstart) == '}') then
return val, lstart+1
end
local clen = content:len()
while (lstart <= clen) do
local key, nstart = parseString(content, lstart)
lstart = skipWhitespaces(content, nstart)
if (content == nil or lstart == nil or
content:sub(lstart, lstart) ~= ':') then
return {}, lstart
end
lstart = skipWhitespaces(content, lstart+1)
local nval, nstart = parseElement(content, lstart)
val[key] = nval
-- We have key and value, must have a } or a ,
lstart = skipWhitespaces(content, nstart)
if (content == nil or lstart == nil) then
return {}, clen
end
if (content:sub(lstart, lstart) == '}') then
return val, lstart+1
end
if (content:sub(lstart, lstart) ~= ',') then
return {}, lstart
end
lstart = skipWhitespaces(content, lstart+1) -- skip comma
end
return {}, lstart
end
local function parseArray(content, pos)
if (content:sub(pos, pos) ~= '[') then
return {}, pos
end
local lstart = skipWhitespaces(content, pos+1)
local val = {}
-- Handle empty array
if (content:sub(lstart, lstart) == ']') then
return val, lstart+1
end
local idx = 1 -- keep 1 to n convention
local clen = content:len()
while (lstart <= clen) do
local nval, nstart = parseElement(content, lstart)
val[idx] = nval
idx = idx + 1
lstart = skipWhitespaces(content, nstart)
-- Need a ] or a , now
if (content == nil or lstart == nil) then
return {}, clen
end
if (content:sub(lstart, lstart) == ']') then
return val, lstart+1
end
if (content:sub(lstart, lstart) ~= ',') then
return {}, lstart
end
lstart = skipWhitespaces(content, lstart+1)
end
return {}, lstart
end
parseElement = function(content, pos)
pos = skipWhitespaces(content, pos)
if (pos > content:len()) then
return {}, pos
end
if (content:find('^"', pos)) then
return parseString(content, pos)
elseif (content:find('^[-0123456789 ]', pos)) then
return parseNumber(content, pos)
elseif (content:find('^%{', pos)) then
return parseObject(content, pos)
elseif (content:find('^%[', pos)) then
return parseArray(content, pos)
else
return {}, pos
end
end
-- Exposed methods:
-- printTable: prints an indented version of a JSON parsing table
-- parseJSON: creates a table from a JSON
function printTable(tbl, indent)
if (tbl == nil) then return end
if not indent then indent = 0 end
for k, v in pairs(tbl) do
formatting = string.rep(" ", indent) .. k .. ": "
if type(v) == "table" then
io.write(formatting)
printTable(v, indent+1)
elseif type(v) == 'boolean' then
io.write(formatting .. tostring(v).."\n")
else
io.write(formatting .. v.."\n")
end
end
end
function parseJSON(content)
if (content == nil) then return {} end
local table = parseElement(content, 1)
--printTable(table)
return table
end

View file

@ -0,0 +1,86 @@
--
-- (C) 2014-15-15 - ntop.org
--
-- Trace Level
TRACE_LEVEL = 2
-- Login & session
debug_login = false
debug_session = false
debug_host = false
debug_flow_data = false
-------------------------------- Trace Event ----------------------------------
-- Trace level
TRACE_ERROR = 0
TRACE_WARNING = 1
TRACE_NORMAL = 2
TRACE_INFO = 3
TRACE_DEBUG = 4
MAX_TRACE_LEVEL = 4
-- Trace mode
TRACE_CONSOLE = 0
TRACE_WEB = 1
function traceError(p_trace_level, p_trace_mode,p_message)
currentline = debug.getinfo(2).currentline
what = debug.getinfo(2).what
src = debug.getinfo(2).short_src
traceback = debug.traceback()
for str in (string.gmatch(traceback, '([^\n]+)')) do
traceback = str
end
for str in (string.gmatch(traceback, '([^/]+)')) do
traceback = str
end
i = 0
for str in (string.gmatch(traceback, '([^:][^ ]+)')) do
if (i == 0) then traceback = str end
i = i + 1
end
traceback = traceback:sub(1, string.len(traceback)-1)
filename = src
for str in (string.gmatch(src, '([^/]+)')) do
filename = str
end
date = os.date("%d/%b/%Y %X")
trace_prefix = ''
if (p_trace_level == TRACE_ERROR) then trace_prefix = 'ERROR: ' end
if (p_trace_level == TRACE_WARNING) then trace_prefix = 'WARNING: ' end
if (p_trace_level == TRACE_INFO) then trace_prefix = 'INFO: ' end
if (p_trace_level == TRACE_DEBUG) then trace_prefix = 'DEBUG: ' end
if ((p_trace_level <= MAX_TRACE_LEVEL) and (p_trace_level <= TRACE_LEVEL) )then
if (p_trace_mode == TRACE_WEB) then
if (filename..':'..currentline ~= traceback) then
print('<b>'..date..' ['..traceback..'] ['..filename..':'..currentline..'] ' ..trace_prefix..p_message..'</b></br>')
else
print('<b>'..date..' ['..filename..':'..currentline..'] ' ..trace_prefix..p_message..'</b></br>')
end
elseif (p_trace_mode == TRACE_CONSOLE) then
if (filename..':'..currentline ~= traceback) then
io.write(date..' ['..traceback..'] ['..filename..':'..currentline..'] ' ..trace_prefix..p_message..'\n')
else
io.write(date..' ['..filename..':'..currentline..'] ' ..trace_prefix..p_message..'\n')
end
end
end
end
function setTraceLevel(p_trace_level)
if (p_trace_level <= MAX_TRACE_LEVEL) then
TRACE_LEVEL = p_trace_level
end
end
function resetTraceLevel()
TRACE_LEVEL = 1
end
--------------------------------

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,209 @@
-- Internal persistence library
--[[ Provides ]]
-- persistence.store(path, ...): Stores arbitrary items to the file at the given path
-- persistence.load(path): Loads files that were previously stored with store and returns them
--[[ Limitations ]]
-- Does not export userdata, threads or most function values
-- Function export is not portable
--[[ License: MIT (see bottom) ]]
-- Private methods
local write, writeIndent, writers, refCount;
persistence =
{
store = function (path, ...)
local file, e;
if type(path) == "string" then
-- Path, open a file
file, e = io.open(path, "w");
if not file then
return error(e);
end
else
-- Just treat it as file
file = path;
end
local n = select("#", ...);
-- Count references
local objRefCount = {}; -- Stores reference that will be exported
for i = 1, n do
refCount(objRefCount, (select(i,...)));
end;
-- Export Objects with more than one ref and assign name
-- First, create empty tables for each
local objRefNames = {};
local objRefIdx = 0;
file:write("-- Persistent Data\n");
file:write("local multiRefObjects = {\n");
for obj, count in pairs(objRefCount) do
if count > 1 then
objRefIdx = objRefIdx + 1;
objRefNames[obj] = objRefIdx;
file:write("{};"); -- table objRefIdx
end;
end;
file:write("\n} -- multiRefObjects\n");
-- Then fill them (this requires all empty multiRefObjects to exist)
for obj, idx in pairs(objRefNames) do
for k, v in pairs(obj) do
file:write("multiRefObjects["..idx.."][");
write(file, k, 0, objRefNames);
file:write("] = ");
write(file, v, 0, objRefNames);
file:write(";\n");
end;
end;
-- Create the remaining objects
for i = 1, n do
file:write("local ".."obj"..i.." = ");
write(file, (select(i,...)), 0, objRefNames);
file:write("\n");
end
-- Return them
if n > 0 then
file:write("return obj1");
for i = 2, n do
file:write(" ,obj"..i);
end;
file:write("\n");
else
file:write("return\n");
end;
file:close();
end;
load = function (path)
local f, e = loadfile(path);
if f then
return f();
else
return nil, e;
end;
end;
}
-- Private methods
-- write thing (dispatcher)
write = function (file, item, level, objRefNames)
writers[type(item)](file, item, level, objRefNames);
end;
-- write indent
writeIndent = function (file, level)
for i = 1, level do
file:write("\t");
end;
end;
-- recursively count references
refCount = function (objRefCount, item)
-- only count reference types (tables)
if type(item) == "table" then
-- Increase ref count
if objRefCount[item] then
objRefCount[item] = objRefCount[item] + 1;
else
objRefCount[item] = 1;
-- If first encounter, traverse
for k, v in pairs(item) do
refCount(objRefCount, k);
refCount(objRefCount, v);
end;
end;
end;
end;
-- Format items for the purpose of restoring
writers = {
["nil"] = function (file, item)
file:write("nil");
end;
["number"] = function (file, item)
file:write(tostring(item));
end;
["string"] = function (file, item)
file:write(string.format("%q", item));
end;
["boolean"] = function (file, item)
if item then
file:write("true");
else
file:write("false");
end
end;
["table"] = function (file, item, level, objRefNames)
local refIdx = objRefNames[item];
if refIdx then
-- Table with multiple references
file:write("multiRefObjects["..refIdx.."]");
else
-- Single use table
file:write("{\n");
for k, v in pairs(item) do
writeIndent(file, level+1);
file:write("[");
write(file, k, level+1, objRefNames);
file:write("] = ");
write(file, v, level+1, objRefNames);
file:write(";\n");
end
writeIndent(file, level);
file:write("}");
end;
end;
["function"] = function (file, item)
-- Does only work for "normal" functions, not those
-- with upvalues or c functions
local dInfo = debug.getinfo(item, "uS");
if dInfo.nups > 0 then
file:write("nil --[[functions with upvalue not supported]]");
elseif dInfo.what ~= "Lua" then
file:write("nil --[[non-lua function not supported]]");
else
local r, s = pcall(string.dump,item);
if r then
file:write(string.format("loadstring(%q)", s));
else
file:write("nil --[[function could not be dumped]]");
end
end
end;
["thread"] = function (file, item)
file:write("nil --[[thread]]\n");
end;
["userdata"] = function (file, item)
file:write("nil --[[userdata]]\n");
end;
}
return persistence
--[[
Copyright (c) 2010 Gerhard Roethlin
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
]]

View file

@ -0,0 +1,290 @@
--
-- (C) 2014-15-15 - ntop.org
--
-- This file contains the description of all functions
-- used to interact with sqlite
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
require "template"
local j = require ("dkjson")
local SqliteClass = {} -- the table representing the class, which will double as the metatable for the instances
SqliteClass.__index = SqliteClass -- failed table lookups on the instances should fallback to the class table, to get methods
-- syntax equivalent to "SqliteClass.new = function..."
function SqliteClass.new(init)
local self = setmetatable({}, SqliteClass)
self.debug = false
self.class_benchmark = os.clock()
self.query_benchmark = os.clock()
self.flows_benchmark = os.clock()
-- Template
self.flow_template = {
["IPV4_SRC_ADDR"] = function (table,val) table["cli.ip"] = val end,
["L4_SRC_PORT"] = function (table,val) table["cli.port"] = tonumber(val) end,
["IPV4_DST_ADDR"] = function (table,val) table["srv.ip"] = val end,
["L4_DST_PORT"] = function (table,val) table["srv.port"] = tonumber(val) end,
["PROTOCOL"] = function (table,val)
if (l4_template[tonumber(val)] ~= nil ) then
table["proto.l4"] = l4_template[tonumber(val)]
else
table["proto.l4"] = val
end
end,
-- ["SRC_VLAN"] = function (table,val) table["vlan"] = tonumber(val) end,
-- ["DST_VLAN"] = function (table,val) table["vlan"] = tonumber(val) end,
["L7_PROTO_NAME"] = function (table,val) table["proto.ndpi"] = val end,
["TCP_FLAGS"] = function (table,val) table["tcp_flags"] = tonumber(val) end,
["OUT_PKTS"] = function (table,val) table["cli2srv.packets"] = tonumber(val) end,
["OUT_BYTES"] = function (table,val) table["cli2srv.bytes"] = tonumber(val) end,
["IN_PKTS"] = function (table,val) table["srv2cli.packets"] = tonumber(val) end,
["IN_BYTES"] = function (table,val) table["srv2cli.bytes"] = tonumber(val) end,
}
-- Query
self.response = nil
self.db = nil;
self.query = nil;
self.number_rows = 0;
-- Flows
self.flows = nil
self.flows_num = 0
return self
end
-- ###################################
-- Getter and setter
function SqliteClass.setDebug(self, bool)
if (bool == nil) then bool = false end
self.debug = bool
return self.debug
end
function SqliteClass.getDebug(self) return self.debug end
function SqliteClass.getFlows(self) return self.flows end
function SqliteClass.getFlowsNum(self) return self.flows_num end
function SqliteClass.getResponse(self) return self.response end
function SqliteClass.getDB(self) return self.db end
function SqliteClass.getQuery(self) return self.query end
-- ###################################
function SqliteClass.execQuery(self, db ,query)
if (db == nil) then return -1 end
if (query == nil) then return -2 end
self.db = db;
self.query = query;
self.query_benchmark = os.clock()
-- io.write(dirs.workingdir ..db..'\n')
self.response = ntop.execQuery(dirs.workingdir ..db , query)
n_rows = ntop.execQuery(dirs.workingdir ..db , "SELECT COUNT (*) as rows_number FROM flows")
if (n_rows ~= nil) then
self.number_rows = n_rows[1]["rows_number"]
end
Sqlite:benchmark("query",os.clock())
return self.response
end
-- ###################################
function SqliteClass.getFlows(self)
if (self.response == nil) then return nil end
-- Init some parameters
self.flows_benchmark = os.clock()
self.flows = {}
num = 0
for _k,_v in pairs(self.response) do
-- init table of table
self.flows[num] = {}
self.flows[num]["ID"] = tonumber(self.response[_k]["ID"])
self.flows[num]["vlan"] = tonumber(self.response[_k]["vlan_id"])
self.flows[num]["bytes"] = tonumber(self.response[_k]["bytes"])
self.flows[num]["duration"] = tonumber(self.response[_k]["duration"])
-- Throughput
-- io.write((self.flows[num]["bytes"] / self.flows[num]["duration"])..'\n')
self.flows[num]["throughput_bps"] = (self.flows[num]["bytes"] / 8 ) / (self.flows[num]["duration"])
self.flows[num]["throughput_trend_bps"] = 3
local info, pos, err = j.decode(self.response[_k]["json"], 1, nil)
if (info == nil) then
traceError(TRACE_ERROR,TRACE_CONSOLE,"Impossible read json form sqlite: ".. err)
else
for key,val in pairs(info) do
label_key = nil
-- Check if the option --jsonlabes is active
if (rtemplate[tonumber(key)] ~= nil) then label_key = rtemplate[tonumber(key)] end
if (template[key] ~= nil) then label_key = key end
-- Convert template id into template name
if (label_key ~= nil) then
if (self.flow_template[label_key] ~= nil) then
-- Call conversion function in order to convert some value to number if it is necessary
self.flow_template[label_key](self.flows[num],val)
else
-- Leave the default key and value
self.flows[num][key] = val
end
end
end -- info loop
-- Custom parameters
if (self.flows[num]["proto.ndpi"] == nil) then
self.flows[num]["proto.ndpi"] = "Unknown"
end
end -- info == nil
num = num + 1
end -- for
-- self.writeFlows(self)
self.flows_num = num
Sqlite:benchmark("flows",os.clock())
return self.flows
end
-- ###################################
function SqliteClass.getRowsNumber(self)
return (self.number_rows);
end
-- ###################################
-- Utils
function SqliteClass.benchmark(self,type,time)
if ((time ~= nil) and (self.debug))then
bk_text = "class"
bk = self.class_benchmark
if (type == "query") then
bk = self.query_benchmark
bk_text = type
elseif (type == "flows") then
bk = self.flows_benchmark
bk_text = type
end
traceError(TRACE_DEBUG,TRACE_CONSOLE,string.format(bk_text .. ": elapsed time: %.4f", time - bk))
end
end
---------------------------------------
function SqliteClass.writeFlows(self)
if (self.flows ~= nil) then
for key,val in pairs(self.flows) do
traceError(TRACE_DEBUG,TRACE_CONSOLE,'Flow: '..key)
for k,v in pairs(self.flows[key]) do
traceError(TRACE_DEBUG,TRACE_CONSOLE,'\t'..k..' - '..v)
end
end
end
end
function getParameters(datetime,action)
datetime_tbl = cleanDateTime(datetime, action)
datetime_tbl["displayed"] = os.date("%m/%d/%Y %I:%M %p",datetime_tbl["epoch"])
traceError(TRACE_DEBUG,TRACE_CONSOLE,'Displayed: ['..datetime_tbl["displayed"] .. ']')
datetime_tbl["query"] = os.date("/%Y/%m/%d/%H/%M",datetime_tbl["epoch"])
traceError(TRACE_DEBUG,TRACE_CONSOLE,'query: ['..datetime_tbl["query"] .. ']')
return datetime_tbl
end
function cleanDateTime(datetime,action)
if (datetime == nil) then return {} end
traceError(TRACE_DEBUG,TRACE_CONSOLE,'Initial date and time: '..datetime)
tbl = split(datetime," ")
q_date = tbl[1]
q_time = tbl[2]
q_type = tbl[3]
traceError(TRACE_DEBUG,TRACE_CONSOLE,'Default value: ['..q_date..']['..q_time .. '][' .. q_type..']')
date_tbl = split(q_date,"/")
q_month = tonumber(date_tbl[1])
q_day = tonumber(date_tbl[2])
q_year = tonumber(date_tbl[3])
traceError(TRACE_DEBUG,TRACE_CONSOLE,'Default value: ['..q_day..']['..q_month .. '][' .. q_year..']')
time_tbl = split(q_time,":")
q_hour = tonumber(time_tbl[1])
q_min = tonumber(time_tbl[2])
if (q_type == "PM") then q_hour = q_hour + 12 end
traceError(TRACE_DEBUG,TRACE_CONSOLE,'Default value: ['..q_hour..']['..q_min .. ']')
q_epoch = os.time({year=q_year, month=q_month, day=q_day, hour=q_hour, min=q_min})
traceError(TRACE_DEBUG,TRACE_CONSOLE,'epoch: ['.. q_epoch ..']')
if (action ~= nil) then
if (action == "newer") then
q_epoch = q_epoch + 300 -- plus 5 min
else
q_epoch = q_epoch - 300 -- min 5 min
end
end
mktime = os.date("%m/%d/%Y %I:%M %p", q_epoch)
traceError(TRACE_DEBUG,TRACE_CONSOLE,'time: ['.. mktime ..']')
ret_tbl = {}
ret_tbl["year"] = q_year
ret_tbl["month"] = month
ret_tbl["day"] = q_day
ret_tbl["q_hour"] = q_q_hour
ret_tbl["q_min"] = q_q_min
ret_tbl["epoch"] = q_epoch
return ret_tbl
end
-- ###################################
-- Don't remove below line
Sqlite = SqliteClass.new()
-- Sqlite:benchmark(os.clock())
Sqlite:setDebug(false)

View file

@ -0,0 +1,494 @@
--
-- (C) 2013 - ntop.org
--
local NTOP_BASE_ID = 57472
local NTOP_BASE_NETFLOW_ID = NTOP_BASE_ID+1024
-- template name to id
template = {
['IN_BYTES'] = 1,
--['SYSTEM_ID'] = 1,
['IN_PKTS'] = 2,
--['INTERFACE_ID'] = 2,
['FLOWS'] = 3,
--['LINE_CARD'] = 3,
['PROTOCOL'] = 4,
['PROTOCOL_MAP'] = NTOP_BASE_NETFLOW_ID+4,
--['NETFLOW_CACHE'] = 4,
['SRC_TOS'] = 5,
--['TEMPLATE_ID'] = 5,
['TCP_FLAGS'] = 6,
['L4_SRC_PORT'] = 7,
['L4_SRC_PORT_MAP'] = NTOP_BASE_NETFLOW_ID+7,
['IPV4_SRC_ADDR'] = 8,
['IPV4_SRC_MASK'] = 9,
['INPUT_SNMP'] = 10,
['L4_DST_PORT'] = 11,
['L4_DST_PORT_MAP'] = NTOP_BASE_NETFLOW_ID+11,
['L4_SRV_PORT'] = NTOP_BASE_NETFLOW_ID+12,
['L4_SRV_PORT_MAP'] = NTOP_BASE_NETFLOW_ID+13,
['IPV4_DST_ADDR'] = 12,
['IPV4_DST_MASK'] = 13,
['OUTPUT_SNMP'] = 14,
['IPV4_NEXT_HOP'] = 15,
['SRC_AS'] = 16,
['DST_AS'] = 17,
['BGP_IPV4_NEXT_HOP'] = 18,
['MUL_DST_PKTS'] = 19,
['MUL_DST_BYTES'] = 20,
['LAST_SWITCHED'] = 21,
['FIRST_SWITCHED'] = 22,
['OUT_BYTES'] = 23,
['OUT_PKTS'] = 24,
['IPV6_SRC_ADDR'] = 27,
['IPV6_DST_ADDR'] = 28,
['IPV6_SRC_MASK'] = 29,
['IPV6_DST_MASK'] = 30,
['IPV6_FLOW_LABEL'] = 31,
['ICMP_TYPE'] = 32,
['MUL_IGMP_TYPE'] = 33,
['SAMPLING_INTERVAL'] = 34,
['SAMPLING_ALGORITHM'] = 35,
['FLOW_ACTIVE_TIMEOUT'] = 36,
['FLOW_INACTIVE_TIMEOUT'] = 37,
['ENGINE_TYPE'] = 38,
['ENGINE_ID'] = 39,
['TOTAL_BYTES_EXP'] = 40,
['TOTAL_PKTS_EXP'] = 41,
['TOTAL_FLOWS_EXP'] = 42,
['MIN_TTL'] = 52,
['MAX_TTL'] = 53,
['IN_SRC_MAC'] = 56,
['SRC_VLAN'] = 58,
['DST_VLAN'] = 59,
['IP_PROTOCOL_VERSION'] = 60,
['DIRECTION'] = 61,
['IPV6_NEXT_HOP'] = 62,
['BPG_IPV6_NEXT_HOP'] = 63,
['IPV6_OPTION_HEADERS'] = 64,
['MPLS_LABEL_1'] = 70,
['MPLS_LABEL_2'] = 71,
['MPLS_LABEL_3'] = 72,
['MPLS_LABEL_4'] = 73,
['MPLS_LABEL_5'] = 74,
['MPLS_LABEL_6'] = 75,
['MPLS_LABEL_7'] = 76,
['MPLS_LABEL_8'] = 77,
['MPLS_LABEL_9'] = 78,
['MPLS_LABEL_10'] = 79,
['OUT_DST_MAC'] = 80,
['APPLICATION_ID'] = 95,
['PACKET_SECTION_OFFSET'] = 102,
['SAMPLED_PACKET_SIZE'] = 103,
['SAMPLED_PACKET_ID'] = 104,
['EXPORTER_IPV4_ADDRESS'] = 130,
['EXPORTER_IPV6_ADDRESS'] = 131,
['FLOW_ID'] = 148,
['FLOW_START_SEC'] = 150,
['FLOW_END_SEC'] = 151,
['FLOW_START_MILLISECONDS'] = 152,
['FLOW_END_MILLISECONDS'] = 153,
['BIFLOW_DIRECTION'] = 239,
['OBSERVATION_POINT_TYPE'] = 277,
['OBSERVATION_POINT_ID'] = 300,
['SELECTOR_ID'] = 302,
['IPFIX_SAMPLING_ALGORITHM'] = 304,
['SAMPLING_SIZE'] = 309,
['SAMPLING_POPULATION'] = 310,
['FRAME_LENGTH'] = 312,
['PACKETS_OBSERVED'] = 318,
['PACKETS_SELECTED'] = 319,
['SELECTOR_NAME'] = 335,
['FRAGMENTS'] = NTOP_BASE_ID+80,
['CLIENT_NW_DELAY_SEC'] = NTOP_BASE_ID+82,
['CLIENT_NW_DELAY_USEC'] = NTOP_BASE_ID+83,
['SERVER_NW_DELAY_SEC'] = NTOP_BASE_ID+84,
['SERVER_NW_DELAY_USEC'] = NTOP_BASE_ID+85,
['APPL_LATENCY_SEC'] = NTOP_BASE_ID+86,
['APPL_LATENCY_USEC'] = NTOP_BASE_ID+87,
['NUM_PKTS_UP_TO_128_BYTES'] = NTOP_BASE_ID+88,
['NUM_PKTS_128_TO_256_BYTES'] = NTOP_BASE_ID+89,
['NUM_PKTS_256_TO_512_BYTES'] = NTOP_BASE_ID+90,
['NUM_PKTS_512_TO_1024_BYTES'] = NTOP_BASE_ID+91,
['NUM_PKTS_1024_TO_1514_BYTES'] = NTOP_BASE_ID+92,
['NUM_PKTS_OVER_1514_BYTES'] = NTOP_BASE_ID+93,
['CUMULATIVE_ICMP_TYPE'] = NTOP_BASE_ID+98,
['SRC_IP_COUNTRY'] = NTOP_BASE_ID+101,
['SRC_IP_CITY'] = NTOP_BASE_ID+102,
['DST_IP_COUNTRY'] = NTOP_BASE_ID+103,
['DST_IP_CITY'] = NTOP_BASE_ID+104,
['FLOW_PROTO_PORT'] = NTOP_BASE_ID+105,
['UPSTREAM_TUNNEL_ID'] = NTOP_BASE_ID+106,
['LONGEST_FLOW_PKT'] = NTOP_BASE_ID+107,
['SHORTEST_FLOW_PKT'] = NTOP_BASE_ID+108,
['RETRANSMITTED_IN_PKTS'] = NTOP_BASE_ID+109,
['RETRANSMITTED_OUT_PKTS'] = NTOP_BASE_ID+110,
['OOORDER_IN_PKTS'] = NTOP_BASE_ID+111,
['OOORDER_OUT_PKTS'] = NTOP_BASE_ID+112,
['UNTUNNELED_PROTOCOL'] = NTOP_BASE_ID+113,
['UNTUNNELED_IPV4_SRC_ADDR'] = NTOP_BASE_ID+114,
['UNTUNNELED_L4_SRC_PORT'] = NTOP_BASE_ID+115,
['UNTUNNELED_IPV4_DST_ADDR'] = NTOP_BASE_ID+116,
['UNTUNNELED_L4_DST_PORT'] = NTOP_BASE_ID+117,
['L7_PROTO'] = NTOP_BASE_ID+118,
['L7_PROTO_NAME'] = NTOP_BASE_ID+119,
['DOWNSTREAM_TUNNEL_ID'] = NTOP_BASE_ID+120,
['FLOW_USER_NAME'] = NTOP_BASE_ID+121,
['FLOW_SERVER_NAME'] = NTOP_BASE_ID+122,
['CLIENT_NW_DELAY_MS'] = NTOP_BASE_ID+123,
['SERVER_NW_DELAY_MS'] = NTOP_BASE_ID+124,
['APPL_LATENCY_MS'] = NTOP_BASE_ID+125,
['PLUGIN_NAME'] = NTOP_BASE_ID+126,
['NUM_PKTS_TTL_EQ_1'] = NTOP_BASE_ID+347,
['NUM_PKTS_TTL_2_5'] = NTOP_BASE_ID+346,
['NUM_PKTS_TTL_5_32'] = NTOP_BASE_ID+334,
['NUM_PKTS_TTL_32_64'] = NTOP_BASE_ID+335,
['NUM_PKTS_TTL_64_96'] = NTOP_BASE_ID+336,
['NUM_PKTS_TTL_96_128'] = NTOP_BASE_ID+337,
['NUM_PKTS_TTL_128_160'] = NTOP_BASE_ID+338,
['NUM_PKTS_TTL_160_192'] = NTOP_BASE_ID+339,
['NUM_PKTS_TTL_192_224'] = NTOP_BASE_ID+340,
['NUM_PKTS_TTL_224_255'] = NTOP_BASE_ID+341,
['IN_SRC_OSI_SAP'] = NTOP_BASE_ID+349,
['OUT_DST_OSI_SAP'] = NTOP_BASE_ID+350,
-- SIP
['SIP_CALL_ID'] = NTOP_BASE_ID+130,
['SIP_CALLING_PARTY'] = NTOP_BASE_ID+131,
['SIP_CALLED_PARTY'] = NTOP_BASE_ID+132,
['SIP_RTP_CODECS'] = NTOP_BASE_ID+133,
['SIP_INVITE_TIME'] = NTOP_BASE_ID+134,
['SIP_TRYING_TIME'] = NTOP_BASE_ID+135,
['SIP_RINGING_TIME'] = NTOP_BASE_ID+136,
['SIP_INVITE_OK_TIME'] = NTOP_BASE_ID+137,
['SIP_INVITE_FAILURE_TIME'] = NTOP_BASE_ID+138,
['SIP_BYE_TIME'] = NTOP_BASE_ID+139,
['SIP_BYE_OK_TIME'] = NTOP_BASE_ID+140,
['SIP_CANCEL_TIME'] = NTOP_BASE_ID+141,
['SIP_CANCEL_OK_TIME'] = NTOP_BASE_ID+142,
['SIP_RTP_IPV4_SRC_ADDR'] = NTOP_BASE_ID+143,
['SIP_RTP_L4_SRC_PORT'] = NTOP_BASE_ID+144,
['SIP_RTP_IPV4_DST_ADDR'] = NTOP_BASE_ID+145,
['SIP_RTP_L4_DST_PORT'] = NTOP_BASE_ID+146,
['SIP_FAILURE_CODE'] = NTOP_BASE_ID+147,
['SIP_REASON_CAUSE'] = NTOP_BASE_ID+148,
['SIP_C_IP'] = NTOP_BASE_ID+362,
['SIP_CALL_STATE'] = NTOP_BASE_ID+363,
-- RTP
['RTP_FIRST_SSRC'] = NTOP_BASE_ID+150,
['RTP_FIRST_TS'] = NTOP_BASE_ID+151,
['RTP_LAST_SSRC'] = NTOP_BASE_ID+152,
['RTP_LAST_TS'] = NTOP_BASE_ID+153,
['RTP_IN_JITTER'] = NTOP_BASE_ID+154,
['RTP_OUT_JITTER'] = NTOP_BASE_ID+155,
['RTP_IN_PKT_LOST'] = NTOP_BASE_ID+156,
['RTP_OUT_PKT_LOST'] = NTOP_BASE_ID+157,
['RTP_OUT_PAYLOAD_TYPE'] = NTOP_BASE_ID+158,
['RTP_IN_MAX_DELTA'] = NTOP_BASE_ID+159,
['RTP_OUT_MAX_DELTA'] = NTOP_BASE_ID+160,
['RTP_IN_PAYLOAD_TYPE'] = NTOP_BASE_ID+161,
['RTP_SIP_CALL_ID'] = NTOP_BASE_ID+348,
['RTP_MOS'] = NTOP_BASE_ID+370,
['RTP_R_FACTOR'] = NTOP_BASE_ID+371,
['RTP_RTT'] = NTOP_BASE_ID+380,
['RTP_IN_TRANSIT'] = NTOP_BASE_ID+381,
['RTP_OUT_TRANSIT'] = NTOP_BASE_ID+382,
-- Process
['SRC_PROC_PID'] = NTOP_BASE_ID+168,
['SRC_PROC_NAME'] = NTOP_BASE_ID+169,
['SRC_PROC_USER_NAME'] = NTOP_BASE_ID+372,
['SRC_FATHER_PROC_PID'] = NTOP_BASE_ID+373,
['SRC_FATHER_PROC_NAME'] = NTOP_BASE_ID+374,
['SRC_PROC_ACTUAL_MEMORY'] = NTOP_BASE_ID+383,
['SRC_PROC_PEAK_MEMORY'] = NTOP_BASE_ID+384,
['SRC_PROC_AVERAGE_CPU_LOAD'] = NTOP_BASE_ID+385,
['SRC_PROC_NUM_PAGE_FAULTS'] = NTOP_BASE_ID+386,
['DST_PROC_PID'] = NTOP_BASE_ID+375,
['DST_PROC_NAME'] = NTOP_BASE_ID+376,
['DST_PROC_USER_NAME'] = NTOP_BASE_ID+377,
['DST_FATHER_PROC_PID'] = NTOP_BASE_ID+378,
['DST_FATHER_PROC_NAME'] = NTOP_BASE_ID+379,
['DST_PROC_ACTUAL_MEMORY'] = NTOP_BASE_ID+387,
['DST_PROC_PEAK_MEMORY'] = NTOP_BASE_ID+388,
['DST_PROC_AVERAGE_CPU_LOAD'] = NTOP_BASE_ID+389,
['DST_PROC_NUM_PAGE_FAULTS'] = NTOP_BASE_ID+390,
-- HTTP
['HTTP_URL'] = NTOP_BASE_ID+180,
['HTTP_RET_CODE'] = NTOP_BASE_ID+181,
['HTTP_REFERER'] = NTOP_BASE_ID+182,
['HTTP_UA'] = NTOP_BASE_ID+183,
['HTTP_MIME'] = NTOP_BASE_ID+184,
['HTTP_HOST'] = NTOP_BASE_ID+187,
['HTTP_FBOOK_CHAT'] = NTOP_BASE_ID+188,
-- SMTP
['SMTP_MAIL_FROM'] = NTOP_BASE_ID+185,
['SMTP_RCPT_TO'] = NTOP_BASE_ID+186,
-- MySQL
['MYSQL_SRV_VERSION'] = NTOP_BASE_ID+195,
['MYSQL_USERNAME'] = NTOP_BASE_ID+196,
['MYSQL_DB'] = NTOP_BASE_ID+197,
['MYSQL_QUERY'] = NTOP_BASE_ID+198,
['MYSQL_RESPONSE'] = NTOP_BASE_ID+199,
['MYSQL_APPL_LATENCY_USEC'] = NTOP_BASE_ID+320,
-- Oracle
['ORACLE_USERNAME'] = NTOP_BASE_ID+200,
['ORACLE_QUERY'] = NTOP_BASE_ID+201,
['ORACLE_RSP_CODE'] = NTOP_BASE_ID+202,
['ORACLE_RSP_STRING'] = NTOP_BASE_ID+203,
['ORACLE_QUERY_DURATION'] = NTOP_BASE_ID+204,
-- DNS
['DNS_QUERY'] = NTOP_BASE_ID+205,
['DNS_QUERY_ID'] = NTOP_BASE_ID+206,
['DNS_QUERY_TYPE'] = NTOP_BASE_ID+207,
['DNS_RET_CODE'] = NTOP_BASE_ID+208,
['DNS_NUM_ANSWERS'] = NTOP_BASE_ID+209,
-- POP
['POP_USER'] = NTOP_BASE_ID+210,
-- GTPv1
['GTPV1_REQ_MSG_TYPE'] = NTOP_BASE_ID+220,
['GTPV1_RSP_MSG_TYPE'] = NTOP_BASE_ID+221,
['GTPV1_C2S_TEID_DATA'] = NTOP_BASE_ID+222,
['GTPV1_C2S_TEID_CTRL'] = NTOP_BASE_ID+223,
['GTPV1_S2C_TEID_DATA'] = NTOP_BASE_ID+224,
['GTPV1_S2C_TEID_CTRL'] = NTOP_BASE_ID+225,
['GTPV1_END_USER_IP'] = NTOP_BASE_ID+226,
['GTPV1_END_USER_IMSI'] = NTOP_BASE_ID+227,
['GTPV1_END_USER_MSISDN'] = NTOP_BASE_ID+228,
['GTPV1_END_USER_IMEI'] = NTOP_BASE_ID+229,
['GTPV1_APN_NAME'] = NTOP_BASE_ID+230,
['GTPV1_RAI_MCC'] = NTOP_BASE_ID+231,
['GTPV1_RAI_MNC'] = NTOP_BASE_ID+232,
['GTPV1_RAI_LAC'] = NTOP_BASE_ID+342,
['GTPV1_RAI_RAC'] = NTOP_BASE_ID+343,
['GTPV1_ULI_MCC'] = NTOP_BASE_ID+344,
['GTPV1_ULI_MNC'] = NTOP_BASE_ID+345,
['GTPV1_ULI_CELL_LAC'] = NTOP_BASE_ID+233,
['GTPV1_ULI_CELL_CI'] = NTOP_BASE_ID+234,
['GTPV1_ULI_SAC'] = NTOP_BASE_ID+235,
['GTPV1_RESPONSE_CAUSE'] = NTOP_BASE_ID+332,
-- Radius
['RADIUS_REQ_MSG_TYPE'] = NTOP_BASE_ID+240,
['RADIUS_RSP_MSG_TYPE'] = NTOP_BASE_ID+241,
['RADIUS_USER_NAME'] = NTOP_BASE_ID+242,
['RADIUS_CALLING_STATION_ID'] = NTOP_BASE_ID+243,
['RADIUS_CALLED_STATION_ID'] = NTOP_BASE_ID+244,
['RADIUS_NAS_IP_ADDR'] = NTOP_BASE_ID+245,
['RADIUS_NAS_IDENTIFIER'] = NTOP_BASE_ID+246,
['RADIUS_USER_IMSI'] = NTOP_BASE_ID+247,
['RADIUS_USER_IMEI'] = NTOP_BASE_ID+248,
['RADIUS_FRAMED_IP_ADDR'] = NTOP_BASE_ID+249,
['RADIUS_ACCT_SESSION_ID'] = NTOP_BASE_ID+250,
['RADIUS_ACCT_STATUS_TYPE'] = NTOP_BASE_ID+251,
['RADIUS_ACCT_IN_OCTETS'] = NTOP_BASE_ID+252,
['RADIUS_ACCT_OUT_OCTETS'] = NTOP_BASE_ID+253,
['RADIUS_ACCT_IN_PKTS'] = NTOP_BASE_ID+254,
['RADIUS_ACCT_OUT_PKTS'] = NTOP_BASE_ID+255,
-- IMAP
['IMAP_LOGIN'] = NTOP_BASE_ID+260,
-- GTPv2
['GTPV2_REQ_MSG_TYPE'] = NTOP_BASE_ID+270,
['GTPV2_RSP_MSG_TYPE'] = NTOP_BASE_ID+271,
['GTPV2_C2S_S1U_GTPU_TEID'] = NTOP_BASE_ID+272,
['GTPV2_C2S_S1U_GTPU_IP'] = NTOP_BASE_ID+273,
['GTPV2_S2C_S1U_GTPU_TEID'] = NTOP_BASE_ID+274,
['GTPV2_S2C_S1U_GTPU_IP'] = NTOP_BASE_ID+275,
['GTPV2_END_USER_IMSI'] = NTOP_BASE_ID+276,
['GTPV2_END_USER_MSISDN'] = NTOP_BASE_ID+277,
['GTPV2_APN_NAME'] = NTOP_BASE_ID+278,
['GTPV2_ULI_MCC'] = NTOP_BASE_ID+279,
['GTPV2_ULI_MNC'] = NTOP_BASE_ID+280,
['GTPV2_ULI_CELL_TAC'] = NTOP_BASE_ID+281,
['GTPV2_ULI_CELL_ID'] = NTOP_BASE_ID+282,
['GTPV2_RESPONSE_CAUSE'] = NTOP_BASE_ID+333,
-- BGP
['SRC_AS_PATH_1'] = NTOP_BASE_ID+290,
['SRC_AS_PATH_2'] = NTOP_BASE_ID+291,
['SRC_AS_PATH_3'] = NTOP_BASE_ID+292,
['SRC_AS_PATH_4'] = NTOP_BASE_ID+293,
['SRC_AS_PATH_5'] = NTOP_BASE_ID+294,
['SRC_AS_PATH_6'] = NTOP_BASE_ID+295,
['SRC_AS_PATH_7'] = NTOP_BASE_ID+296,
['SRC_AS_PATH_8'] = NTOP_BASE_ID+297,
['SRC_AS_PATH_9'] = NTOP_BASE_ID+298,
['SRC_AS_PATH_10'] = NTOP_BASE_ID+299,
['DST_AS_PATH_1'] = NTOP_BASE_ID+300,
['DST_AS_PATH_2'] = NTOP_BASE_ID+301,
['DST_AS_PATH_3'] = NTOP_BASE_ID+302,
['DST_AS_PATH_4'] = NTOP_BASE_ID+303,
['DST_AS_PATH_5'] = NTOP_BASE_ID+304,
['DST_AS_PATH_6'] = NTOP_BASE_ID+305,
['DST_AS_PATH_7'] = NTOP_BASE_ID+306,
['DST_AS_PATH_8'] = NTOP_BASE_ID+307,
['DST_AS_PATH_9'] = NTOP_BASE_ID+308,
['DST_AS_PATH_10'] = NTOP_BASE_ID+309,
-- GTPv0
['GTPV0_REQ_MSG_TYPE'] = NTOP_BASE_ID+321,
['GTPV0_RSP_MSG_TYPE'] = NTOP_BASE_ID+322,
['GTPV0_TID'] = NTOP_BASE_ID+323,
['GTPV0_END_USER_IP'] = NTOP_BASE_ID+324,
['GTPV0_END_USER_MSISDN'] = NTOP_BASE_ID+325,
['GTPV0_APN_NAME'] = NTOP_BASE_ID+326,
['GTPV0_RAI_MCC'] = NTOP_BASE_ID+327,
['GTPV0_RAI_MNC'] = NTOP_BASE_ID+328,
['GTPV0_RAI_CELL_LAC'] = NTOP_BASE_ID+329,
['GTPV0_RAI_CELL_RAC'] = NTOP_BASE_ID+330,
['GTPV0_RESPONSE_CAUSE'] = NTOP_BASE_ID+331
}
-- template id to name
rtemplate = {}
for key,value in pairs(template) do
rtemplate[tonumber(value)] = key
end
-- L4 protocols
l4_template = {
[0] = "IP",
[1] = "ICMP",
[2] = "IGMP",
[3] = "GGP",
[4] = "IPENCAP",
[5] = "ST2",
[6] = "TCP",
[7] = "CBT",
[8] = "EGP",
[9] = "IGP",
[10] = "BBN-RCC",
[11] = "NVP",
[12] = "PUP",
[13] = "ARGUS",
[14] = "EMCON",
[15] = "XNET",
[16] = "CHAOS",
[17] = "UDP",
[18] = "MUX",
[19] = "DCN",
[20] = "HMP",
[21] = "PRM",
[22] = "XNS-IDP",
[23] = "TRUNK-1",
[24] = "TRUNK-2",
[25] = "LEAF-1",
[26] = "LEAF-2",
[27] = "RDP",
[28] = "IRTP",
[29] = "ISO-TP4",
[30] = "NETBLT",
[31] = "MFE-NSP",
[32] = "MERIT-INP",
[33] = "SEP",
[34] = "3PC",
[35] = "IDPR",
[36] = "XTP",
[37] = "DDP",
[38] = "IDPR-CMTP",
[39] = "TP++",
[40] = "IL",
[41] = "IPV6",
[42] = "SDRP",
[43] = "IPV6-ROUTE",
[44] = "IPV6-FRAG",
[45] = "IDRP",
[46] = "RSVP",
[47] = "GRE",
[48] = "MHRP",
[49] = "BNA",
[50] = "ESP",
[51] = "AH",
[52] = "I-NLSP",
[53] = "SWIPE",
[54] = "NARP",
[55] = "MOBILE",
[56] = "TLSP",
[57] = "SKIP",
[58] = "IPV6-ICMP",
[59] = "IPV6-NONXT",
[60] = "IPV6-OPTS",
[62] = "CFTP",
[64] = "SAT-EXPAK",
[65] = "KRYPTOLAN",
[66] = "RVD",
[67] = "IPPC",
[69] = "SAT-MON",
[70] = "VISA",
[71] = "IPCV",
[72] = "CPNX",
[73] = "CPHB",
[74] = "WSN",
[75] = "PVP",
[76] = "BR-SAT-MON",
[77] = "SUN-ND",
[78] = "WB-MON",
[79] = "WB-EXPAK",
[80] = "ISO-IP",
[81] = "VMTP",
[82] = "SECURE-VMTP",
[83] = "VINES",
[84] = "TTP",
[85] = "NSFNET-IGP",
[86] = "DGP",
[87] = "TCF",
[88] = "EIGRP",
[89] = "OSPF",
[90] = "SPRITE-RPC",
[91] = "LARP",
[92] = "MTP",
[93] = "AX.25",
[94] = "IPIP",
[95] = "MICP",
[96] = "SCC-SP",
[97] = "ETHERIP",
[98] = "ENCAP",
[100] = "GMTP",
[101] = "IFMP",
[102] = "PNNI",
[103] = "PIM",
[104] = "ARIS",
[105] = "SCPS",
[106] = "QNX",
[107] = "A/N",
[108] = "IPCOMP",
[109] = "SNP",
[110] = "COMPAQ-PEER",
[111] = "IPX-IN-IP",
[112] = "VRRP",
[113] = "PGM",
[115] = "L2TP",
[116] = "DDX",
[117] = "IATP",
[118] = "ST",
[119] = "SRP",
[120] = "UTI",
[121] = "SMP",
[122] = "SM",
[123] = "PTP",
[124] = "ISIS",
[125] = "FIRE",
[126] = "CRTP",
[127] = "CRDUP",
[128] = "SSCOPMCE",
[129] = "IPLT",
[130] = "SPS",
[131] = "PIPE",
[132] = "SCTP",
[133] = "FC",
[254] = "DIVERT"
}

View file

@ -0,0 +1,221 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
require "json"
local top_asn_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_asn_intf[k] = v
end
end
local function getTopAS(ifid, ifname)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
nil, nil, top_asn_intf.key,
top_asn_intf.JSONkey, nil, true, nil, top_asn_intf.uniqueKey)
end
local function getTopASBy(ifid, ifname, filter_col, filter_val)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
filter_col, filter_val, top_asn_intf.key,
top_asn_intf.JSONkey, nil, true, nil, top_asn_intf.uniqueKey)
end
local function getTopASClean(ifid, ifname, param)
top = getCurrentTopGroups(ifid, ifname, 5, false, false,
nil, nil, top_asn_intf.key,
top_asn_intf.JSONkey, true, param, top_asn_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 topASSectionInTableOP(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 printTopASTable(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 getTopASFromJSONDirection(table, wantedDir, add_vlan)
local elements = ""
-- For each VLAN, get ASs and concatenate them
for i,vlan in pairs(table["vlan"]) do
local vlanid = vlan["label"]
local vlanname = vlan["name"]
-- XXX asn is an array of (senders, receivers) pairs?
for i2,asnpair in pairs(vlan[top_asn_intf.JSONkey]) do
-- asnpair is { "senders": [...], "receivers": [...] }
for k2,direction in pairs(asnpair) do
-- direction is "senders": [...] or "receivers": [...]
if (k2 ~= wantedDir) then goto continue end
-- scan ASs
for i2,asn in pairs(direction) do
-- asn is { "label": ..., "value": ..., "url": ... }
elements = elements.."{ "
local n_el = 0
for k3,v3 in pairs(asn) 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 printTopASFromTable(table, add_vlan)
if (table == nil or table["vlan"] == nil) then return "[ ]\n" end
local elements = "{\n"
elements = elements..'"senders": [\n'
local result = getTopASFromJSONDirection(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 = getTopASFromJSONDirection(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 getTopASFromJSON(content, add_vlan)
if(content == nil) then return("[ ]\n") end
local table = parseJSON(content)
local rsp = printTopASFromTable(table, add_vlan)
if (rsp == nil or rsp == "") then return "[ ]\n" end
return rsp
end
local function getHistoricalTopAS(ifid, ifname, epoch, add_vlan)
if (epoch == nil) then
return("[ ]\n")
end
return getTopASFromJSON(ntop.getMinuteSampling(ifid, tonumber(epoch)), add_vlan)
end
top_asn_intf.name = "ASN"
top_asn_intf.infoScript = "hosts_stats.lua"
top_asn_intf.infoScriptKey = "asn"
top_asn_intf.key = "asn"
top_asn_intf.JSONkey = "asn"
top_asn_intf.uniqueKey = "top_asn"
top_asn_intf.getTop = getTopAS
top_asn_intf.getTopBy = getTopASBy
top_asn_intf.getTopClean = getTopASClean
top_asn_intf.getTopFromJSON = getTopASFromJSON
top_asn_intf.printTopTable = printTopASTable
top_asn_intf.getHistoricalTop = getHistoricalTopAS
top_asn_intf.topSectionInTableOp = topASSectionInTableOP
top_asn_intf.numLevels = 2
return top_asn_intf

View file

@ -0,0 +1,224 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
require "json"
local top_countries_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_countries_intf[k] = v
end
end
local function getTopCountries(ifid, ifname)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
nil, nil, top_countries_intf.key,
top_countries_intf.JSONkey, nil, true, nil,
top_countries_intf.uniqueKey)
end
local function getTopCountriesBy(ifid, ifname, filter_col, filter_val)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
filter_col, filter_val, top_countries_intf.key,
top_countries_intf.JSONkey, nil, true, nil,
top_countries_intf.uniqueKey)
end
local function getTopCountriesClean(ifid, ifname, param)
top = getCurrentTopGroups(ifid, ifname, 5, false, false,
nil, nil, top_countries_intf.key,
top_countries_intf.JSONkey, true, param,
top_countries_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 topCountriesSectionInTableOP(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 printTopCountriesTable(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 getTopCountriesFromJSONDirection(table, wantedDir, add_vlan)
local elements = ""
-- For each VLAN, get countries and concatenate them
for i,vlan in pairs(table["vlan"]) do
local vlanid = vlan["label"]
local vlanname = vlan["name"]
-- XXX countries is an array of (senders, receivers) pairs?
for i2,countriespair in pairs(vlan[top_countries_intf.JSONkey]) do
-- countriespair is { "senders": [...], "receivers": [...] }
for k2,direction in pairs(countriespair) do
-- direction is "senders": [...] or "receivers": [...]
if (k2 ~= wantedDir) then goto continue end
-- scan countries
for i2,country in pairs(direction) do
-- country is { "label": ..., "value": ..., "url": ... }
elements = elements.."{ "
local n_el = 0
for k3,v3 in pairs(country) 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 printTopCountriesFromTable(table, add_vlan)
if (table == nil or table["vlan"] == nil) then return "[ ]\n" end
local elements = "{\n"
elements = elements..'"senders": [\n'
local result = getTopCountriesFromJSONDirection(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 = getTopCountriesFromJSONDirection(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 getTopCountriesFromJSON(content, add_vlan)
if(content == nil) then return("[ ]\n") end
local table = parseJSON(content)
local rsp = printTopCountriesFromTable(table, add_vlan)
if (rsp == nil or rsp == "") then return "[ ]\n" end
return rsp
end
local function getHistoricalTopCountries(ifid, ifname, epoch, add_vlan)
if (epoch == nil) then
return("[ ]\n")
end
return getTopCountriesFromJSON(ntop.getMinuteSampling(ifid, tonumber(epoch)), add_vlan)
end
top_countries_intf.name = "Countries"
top_countries_intf.infoScript = "hosts_stats.lua"
top_countries_intf.infoScriptKey = "country"
top_countries_intf.key = "country"
top_countries_intf.JSONkey = "countries"
top_countries_intf.uniqueKey = "top_countries"
top_countries_intf.getTop = getTopCountries
top_countries_intf.getTopBy = getTopCountriesBy
top_countries_intf.getTopClean = getTopCountriesClean
top_countries_intf.getTopFromJSON = getTopCountriesFromJSON
top_countries_intf.printTopTable = printTopCountriesTable
top_countries_intf.getHistoricalTop = getHistoricalTopCountries
top_countries_intf.topSectionInTableOp = topCountriesSectionInTableOP
top_countries_intf.numLevels = 2
return top_countries_intf

View file

@ -0,0 +1,224 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
require "json"
local top_networks_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_networks_intf[k] = v
end
end
local function getTopNetworks(ifid, ifname)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
nil, nil, top_networks_intf.key,
top_networks_intf.JSONkey, nil, true, nil,
top_networks_intf.uniqueKey)
end
local function getTopNetworksBy(ifid, ifname, filter_col, filter_val)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
filter_col, filter_val, top_networks_intf.key,
top_networks_intf.JSONkey, nil, true, nil,
top_networks_intf.uniqueKey)
end
local function getTopNetworksClean(ifid, ifname, param)
top = getCurrentTopGroups(ifid, ifname, 5, false, false,
nil, nil, top_networks_intf.key,
top_networks_intf.JSONkey, true, param,
top_networks_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 topNetworksSectionInTableOP(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 printTopNetworksTable(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 getTopNetworksFromJSONDirection(table, wantedDir, add_vlan)
local elements = ""
-- For each VLAN, get networks and concatenate them
for i,vlan in pairs(table["vlan"]) do
local vlanid = vlan["label"]
local vlanname = vlan["name"]
-- XXX networks is an array of (senders, receivers) pairs?
for i2,networkspair in pairs(vlan[top_networks_intf.JSONkey]) do
-- networkspair is { "senders": [...], "receivers": [...] }
for k2,direction in pairs(networkspair) do
-- direction is "senders": [...] or "receivers": [...]
if (k2 ~= wantedDir) then goto continue end
-- scan networks
for i2,network in pairs(direction) do
-- network is { "label": ..., "value": ..., "url": ... }
elements = elements.."{ "
local n_el = 0
for k3,v3 in pairs(network) 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 printTopNetworksFromTable(table, add_vlan)
if (table == nil or table["vlan"] == nil) then return "[ ]\n" end
local elements = "{\n"
elements = elements..'"senders": [\n'
local result = getTopNetworksFromJSONDirection(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 = getTopNetworksFromJSONDirection(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 getTopNetworksFromJSON(content, add_vlan)
if(content == nil) then return("[ ]\n") end
local table = parseJSON(content)
local rsp = printTopNetworksFromTable(table, add_vlan)
if (rsp == nil or rsp == "") then return "[ ]\n" end
return rsp
end
local function getHistoricalTopNetworks(ifid, ifname, epoch, add_vlan)
if (epoch == nil) then
return("[ ]\n")
end
return getTopNetworksFromJSON(ntop.getMinuteSampling(ifid, tonumber(epoch)), add_vlan)
end
top_networks_intf.name = "Networks"
top_networks_intf.infoScript = "hosts_stats.lua"
top_networks_intf.infoScriptKey = "network"
top_networks_intf.key = "local_network_id"
top_networks_intf.JSONkey = "networks"
top_networks_intf.uniqueKey = "top_local_nets"
top_networks_intf.getTop = getTopNetworks
top_networks_intf.getTopBy = getTopNetworksBy
top_networks_intf.getTopClean = getTopNetworksClean
top_networks_intf.getTopFromJSON = getTopNetworksFromJSON
top_networks_intf.printTopTable = printTopNetworksTable
top_networks_intf.getHistoricalTop = getHistoricalTopNetworks
top_networks_intf.topSectionInTableOp = topNetworksSectionInTableOP
top_networks_intf.numLevels = 2
return top_networks_intf

View file

@ -0,0 +1,224 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
require "json"
local top_os_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_os_intf[k] = v
end
end
local function getTopOS(ifid, ifname)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
nil, nil, top_os_intf.key,
top_os_intf.JSONkey, false, true, nil,
top_os_intf.uniqueKey)
end
local function getTopOSBy(ifid, ifname, filter_col, filter_val)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
filter_col, filter_val, top_os_intf.key,
top_os_intf.JSONkey, false, true, nil,
top_os_intf.uniqueKey)
end
local function getTopOSClean(ifid, ifname, param)
top = getCurrentTopGroups(ifid, ifname, 5, false, false,
nil, nil, top_os_intf.key,
top_os_intf.JSONkey, true, param,
top_os_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 topOSSectionInTableOP(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 printTopOSTable(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 getTopOSFromJSONDirection(table, wantedDir, add_vlan)
local elements = ""
-- For each VLAN, get os and concatenate them
for i,vlan in pairs(table["vlan"]) do
local vlanid = vlan["label"]
local vlanname = vlan["name"]
-- XXX os is an array of (senders, receivers) pairs?
for i2,os in pairs(vlan[top_os_intf.JSONkey]) do
-- os is { "senders": [...], "receivers": [...] }
for k2,direction in pairs(os) do
-- direction is "senders": [...] or "receivers": [...]
if (k2 ~= wantedDir) then goto continue end
-- scan os
for i2,os in pairs(direction) do
-- os is { "label": ..., "value": ..., "url": ... }
elements = elements.."{ "
local n_el = 0
for k3,v3 in pairs(os) 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 printTopOSFromTable(table, add_vlan)
if (table == nil or table["vlan"] == nil) then return "[ ]\n" end
local elements = "{\n"
elements = elements..'"senders": [\n'
local result = getTopOSFromJSONDirection(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 = getTopOSFromJSONDirection(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 getTopOSFromJSON(content, add_vlan)
if(content == nil) then return("[ ]\n") end
local table = parseJSON(content)
local rsp = printTopOSFromTable(table, add_vlan)
if (rsp == nil or rsp == "") then return "[ ]\n" end
return rsp
end
local function getHistoricalTopOS(ifid, ifname, epoch, add_vlan)
if (epoch == nil) then
return("[ ]\n")
end
return getTopOSFromJSON(ntop.getMinuteSampling(ifid, tonumber(epoch)), add_vlan)
end
top_os_intf.name = "Operating Systems"
top_os_intf.infoScript = "hosts_stats.lua"
top_os_intf.infoScriptKey = "os"
top_os_intf.key = "os"
top_os_intf.JSONkey = "non-local os"
top_os_intf.uniqueKey = "top_os"
top_os_intf.getTop = getTopOS
top_os_intf.getTopBy = getTopOSBy
top_os_intf.getTopClean = getTopOSClean
top_os_intf.getTopFromJSON = getTopOSFromJSON
top_os_intf.printTopTable = printTopOSTable
top_os_intf.getHistoricalTop = getHistoricalTopOS
top_os_intf.topSectionInTableOp = topOSSectionInTableOP
top_os_intf.numLevels = 2
return top_os_intf

View file

@ -0,0 +1,224 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
require "json"
local top_os_local_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_os_local_intf[k] = v
end
end
local function getTopOSLocal(ifid, ifname)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
nil, nil, top_os_local_intf.key,
top_os_local_intf.JSONkey, true, true, nil,
top_os_local_intf.uniqueKey)
end
local function getTopOSLocalBy(ifid, ifname, filter_col, filter_val)
return getCurrentTopGroupsSeparated(ifid, ifname, 10, true, false,
filter_col, filter_val, top_os_local_intf.key,
top_os_local_intf.JSONkey, true, true, nil,
top_os_local_intf.uniqueKey)
end
local function getTopOSLocalClean(ifid, ifname, param)
top = getCurrentTopGroups(ifid, ifname, 5, false, false,
nil, nil, top_os_local_intf.key,
top_os_local_intf.JSONkey, true, param,
top_os_local_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 topOSLocalSectionInTableOP(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 printTopOSLocalTable(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 getTopOSLocalFromJSONDirection(table, wantedDir, add_vlan)
local elements = ""
-- For each VLAN, get os and concatenate them
for i,vlan in pairs(table["vlan"]) do
local vlanid = vlan["label"]
local vlanname = vlan["name"]
-- XXX os is an array of (senders, receivers) pairs?
for i2,os in pairs(vlan[top_os_local_intf.JSONkey]) do
-- os is { "senders": [...], "receivers": [...] }
for k2,direction in pairs(os) do
-- direction is "senders": [...] or "receivers": [...]
if (k2 ~= wantedDir) then goto continue end
-- scan os
for i2,os in pairs(direction) do
-- os is { "label": ..., "value": ..., "url": ... }
elements = elements.."{ "
local n_el = 0
for k3,v3 in pairs(os) 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 printTopOSLocalFromTable(table, add_vlan)
if (table == nil or table["vlan"] == nil) then return "[ ]\n" end
local elements = "{\n"
elements = elements..'"senders": [\n'
local result = getTopOSLocalFromJSONDirection(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 = getTopOSLocalFromJSONDirection(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 getTopOSFromJSON(content, add_vlan)
if(content == nil) then return("[ ]\n") end
local table = parseJSON(content)
local rsp = printTopOSLocalFromTable(table, add_vlan)
if (rsp == nil or rsp == "") then return "[ ]\n" end
return rsp
end
local function getHistoricalTopOSLocal(ifid, ifname, epoch, add_vlan)
if (epoch == nil) then
return("[ ]\n")
end
return getTopOSLocalFromJSON(ntop.getMinuteSampling(ifid, tonumber(epoch)), add_vlan)
end
top_os_local_intf.name = "Local Operating Systems"
top_os_local_intf.infoScript = "hosts_stats.lua"
top_os_local_intf.infoScriptKey = "os"
top_os_local_intf.key = "os"
top_os_local_intf.JSONkey = "local os"
top_os_local_intf.uniqueKey = "top_local_os"
top_os_local_intf.getTop = getTopOSLocal
top_os_local_intf.getTopBy = getTopOSLocalBy
top_os_local_intf.getTopClean = getTopOSLocalClean
top_os_local_intf.getTopFromJSON = getTopOSLocalFromJSON
top_os_local_intf.printTopTable = printTopOSLocalTable
top_os_local_intf.getHistoricalTop = getHistoricalTopOSLocal
top_os_local_intf.topSectionInTableOp = topOSLocalSectionInTableOP
top_os_local_intf.numLevels = 2
return top_os_local_intf

View file

@ -0,0 +1,218 @@
--
-- (C) 2013-15 - 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
return getTopTalkersFromJSON(ntop.getMinuteSampling(ifid, tonumber(epoch)), add_vlan)
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.topSectionInTableOp = topTalkersSectionInTableOP
top_talkers_intf.numLevels = 2
return top_talkers_intf

View file

@ -0,0 +1,101 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
require "top_structure"
require "json"
local top_vlan_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_vlan_intf[k] = v
end
end
local function getTopVLAN(ifid, ifname)
return getCurrentTopGroups(ifid, ifname, 10, true, false,
nil, nil, top_vlan_intf.key,
top_vlan_intf.JSONkey, true, nil,
top_vlan_intf.uniqueKey)
end
local function getTopVlanClean(ifid, ifname, param)
top = getCurrentTopGroups(ifid, ifname, 10, true, false,
nil, nil, top_vlan_intf.key,
top_vlan_intf.JSONkey, false, nil,
top_vlan_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 getTopVLANFromJSON(content, add_vlan)
if(content == nil) then return("[ ]\n") end
local table = parseJSON(content)
if (table == nil or table[top_vlan_intf.JSONkey] == nil) then return "[ ]\n" end
local nr_elements = 0
local elements = "[\n"
for i,vlan in pairs(table[top_vlan_intf.JSONkey]) do
if (add_vlan ~= nil and tostring(vlan["label"]) == "0") then
goto continue
end
elements = elements.."{ "
for k,v in pairs(vlan) do
if (type(v) ~= "table") then
elements = elements..'"'..k..'": '
end
if (k == "value") then
elements = elements..tostring(v)
elseif (type(v) ~= "table") then
elements = elements..'"'..tostring(v)..'"'
end
if (type(v) ~= "table") then
elements = elements..", "
end
end
elements = string.sub(elements, 1, -3)
elements = elements.." },\n"
nr_elements = nr_elements + 1
::continue::
end
if (nr_elements > 0) then
elements = string.sub(elements, 1, -3)
end
elements = elements.."\n]"
return elements
end
local function getHistoricalTopVLAN(ifid, ifname, epoch, add_vlan)
if (epoch == nil) then
return("[ ]\n")
end
return getTopVLANFromJSON(ntop.getMinuteSampling(ifid, tonumber(epoch)), add_vlan)
end
top_vlan_intf.name = "VLANs"
top_vlan_intf.infoScript = "hosts_stats.lua"
top_vlan_intf.infoScriptKey = "vlan"
top_vlan_intf.key = "vlan"
top_vlan_intf.JSONkey = "vlan"
top_vlan_intf.uniqueKey = "top_vlan"
top_vlan_intf.getTop = getTopVLAN
-- No getTopBy method as it must not be same level with others in JSON
top_vlan_intf.getTopClean = getTopVLANClean
top_vlan_intf.getTopFromJSON = getTopVLANFromJSON
top_vlan_intf.getHistoricalTop = getHistoricalTopVLAN
top_vlan_intf.numLevels = 1
return top_vlan_intf

View file

@ -0,0 +1,55 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "top_talkers"
local function getVLANList(ifid, ifname)
interface.select(ifname)
hosts_stats = interface.getHostsInfo()
vlans,total = groupStatsByColumn(ifid, ifname, "vlan")
return vlans
end
function makeTopJSON(ifid, ifname)
path = dirs.installdir .. "/scripts/lua/modules/top_scripts"
path = fixPath(path)
local files = ntop.readdir(path)
local file_cnt = 0
vlan_list = getVLANList(ifid, ifname)
if (next(vlan_list) == nil) then return "[ ]\n" end
rsp = '{\n "vlan": [\n'
for key,value in pairs(vlan_list) do
rsp = rsp.."{\n"
rsp = rsp..'\n"label": "'..key..'",\n"url": "'
..ntop.getHttpPrefix()..
'/lua/hosts_stats.lua?vlan='..key..'",\n"name": "'
..vlan_list[key]["name"]..'",\n"value": '
..vlan_list[key]["vlan_bytes"]..",\n"
file_cnt = 0
for k,v in pairs(files) do
if (v ~= nil) then
fn,ext = v:match("([^.]+).lua")
local topClass = require("top_scripts."..fn)
if (topClass.getTopBy ~= nil) then
rsp = rsp..topClass.getTopBy(ifid, ifname, "vlan", key)
rsp = rsp..",\n"
file_cnt = file_cnt + 1
end
end
end
if (file_cnt > 0) then
-- Remove last return and comma to comply with JSON format
rsp = string.sub(rsp, 1, -3)
end
rsp = rsp.."}\n"
end
rsp = rsp.."\n]\n}"
return(rsp)
end

View file

@ -0,0 +1,366 @@
--
-- (C) 2013-15 - ntop.org
--
dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "persistence"
-- #################################################
function getTop(stats, sort_field_key, max_num_entries, lastdump_dir, lastdump_key, use_threshold)
local _filtered_stats, filtered_stats, counter, total,
threshold, low_threshold
if (use_threshold == nil) then use_threshold = true end
-- stats is a hash of hashes organized as follows:
-- { "id1" : { "key1": "value1", "key2": "value2", ...}, "id2 : { ... } }
-- filter out the needed values
_filtered_stats = {}
for id,content in pairs(stats) do
_filtered_stats[id] = content[sort_field_key]
end
local file_key = sort_field_key
if (lastdump_key ~= nil) then
file_key = file_key.."_"..lastdump_key
end
-- Read the lastdump; the name of the lastdump file has the following
-- format: <lastdump_dir>/.<sort_field_key>_lastdump
lastdump = lastdump_dir .. "/."..file_key.."_lastdump"
last = nil
if(ntop.exists(lastdump)) then
last = persistence.load(lastdump)
end
if(last == nil) then last = {} end
persistence.store(lastdump, _filtered_stats);
for key, value in pairs(_filtered_stats) do
if(last[key] ~= nil) then
v = _filtered_stats[key]-last[key]
if(v < 0) then v = 0 end
_filtered_stats[key] = v
end
end
-- order the filtered stats by using the value (bytes sent/received during
-- the last time interval) as key
filtered_stats = {}
for key, value in pairs(_filtered_stats) do
filtered_stats[value] = key
end
-- Compute traffic
total = 0
for _value,_ in pairsByKeys(filtered_stats, rev) do
total = total + _value
end
threshold = total / 10 -- 10 %
low_threshold = total * 0.05 -- 5%
-- build a new hashtable sorted by the required field
top_stats = {}
counter = 0
for _value,_id in pairsByKeys(filtered_stats, rev) do
if ((_value == 0) or (use_threshold == true and ((_value < low_threshold or
_value < threshold) and (counter > max_num_entries / 2)))) then
break
end
top_stats[_value] = _id -- still keep it in order
counter = counter + 1
if (counter == max_num_entries) then
break
end
end
return top_stats
end
function filterBy(stats, col, val)
local filtered_by = {}
if (col == "" or col == nil or val == nil) then
return stats
end
for id,content in pairs(stats) do
if (content[col] == val) then
filtered_by[id] = content
end
end
return filtered_by
end
-- #####################################################
function getCurrentTopTalkers(ifid, ifname, filter_col, filter_val, concat, mode, use_threshold, lastdump_key)
local max_num_entries = 10
local rsp = ""
local num = 0
interface.select(ifname)
hosts_stats = interface.getHostsInfo()
hosts_stats = filterBy(hosts_stats, filter_col, filter_val)
talkers_dir = fixPath(dirs.workingdir .. "/" .. ifid .. "/top_talkers")
if(not(ntop.exists(talkers_dir))) then
ntop.mkdir(talkers_dir)
end
if(concat == false and mode == nil) then
rsp = rsp.."{\n"
end
rsp = rsp..'\t"hosts": [\n'
if(mode == nil) then
rsp = rsp .. "{\n"
rsp = rsp .. '\t"senders": ['
end
--print("Hello\n")
if((mode == nil) or (mode == "senders")) then
top_talkers = getTop(hosts_stats, "bytes.sent", max_num_entries, talkers_dir, lastdump_key, use_threshold)
num = 0
for value,id in pairsByKeys(top_talkers, rev) do
if(num > 0) then rsp = rsp .. " }," end
rsp = rsp .. '\n\t\t { "address": "'..id.. '", "label": "'
..hosts_stats[id]["name"]..'", "url": "'
..ntop.getHttpPrefix()..
'/lua/host_details.lua?host='..id..'", "value": '..value..
', "local": "'..tostring(hosts_stats[id]["localhost"])..'"'
num = num + 1
end
end
if(mode == nil) then
if(num > 0) then rsp = rsp .. " }" end
rsp = rsp .. "\n\t],\n"
rsp = rsp .. '\t"receivers": ['
end
if((mode == nil) or (mode == "receivers")) then
top_listeners = getTop(hosts_stats, "bytes.rcvd", max_num_entries, talkers_dir, lastdump_key, use_threshold)
num = 0
for value,id in pairsByKeys(top_listeners, rev) do
if(num > 0) then rsp = rsp .. " }," end
rsp = rsp .. '\n\t\t { "address": "'..id.. '", "label": "'
..hosts_stats[id]["name"]..'", "url": "'
..ntop.getHttpPrefix()..
'/lua/host_details.lua?host='..id..'", "value": '..value..
', "local": "'..tostring(hosts_stats[id]["localhost"])..'"'
num = num + 1
end
end
if(mode == nil) then
if(num > 0) then rsp = rsp .. " }" end
rsp = rsp .. "\n\t]\n"
rsp = rsp .. "\n}\n"
else
if(num > 0) then rsp = rsp .. " }\n" end
end
rsp = rsp.."]"
if(concat == false and mode == nil) then
rsp = rsp.."\n}"
end
--print(rsp.."\n")
return(rsp)
end
-- #####################################################
function groupStatsByColumn(ifid, ifname, col)
local _group = {}
local total = 0
-- Group hosts info by the required column
for _key, value in pairs(hosts_stats) do
key = hosts_stats[_key][col]
if ((col == "country" and key == "") or
(col == "local_network_id" and key == -1) or
(col == "os" and key == "")) then goto continue end
if (_group[key] == nil) then
_group[key] = {}
old = 0
else
assert(_group[key][col.."_bytes.sent"] ~= nil)
assert(_group[key][col.."_bytes.rcvd"] ~= nil)
assert(_group[key][col.."_bytes"] ~= nil)
old = _group[key][col.."_bytes"]
end
if (col == "asn") then
if(key == 0) then
_group[key]["name"] = "0 [Local/Unknown]"
else
_group[key]["name"] = key .." ["..hosts_stats[_key]["asname"].."]"
end
elseif (col == "vlan") then
if (key == 0) then
_group[key]["name"] = "No VLAN"
else
_group[key]["name"] = "VLAN"..hosts_stats[_key]["vlan"]
end
elseif (col == "country") then
if (key == "") then
_group[key]["name"] = "Unknown"
else
_group[key]["name"] = key
end
elseif (col == "local_network_id") then
if (key == -1) then
_group[key]["name"] = "[Unknown]"
else
_group[key]["name"] = hosts_stats[_key]["local_network_name"]
end
elseif (col == "os") then
if (key == "") then
_group[key]["name"] = "[Unknown]"
else
_group[key]["name"] = hosts_stats[_key]["os"]
end
end
val = hosts_stats[_key]["bytes.sent"] + hosts_stats[_key]["bytes.rcvd"]
total = total + val
_group[key][col.."_bytes"] = old + val
_group[key][col.."_bytes"] = old + val
_group[key][col.."_bytes.sent"] = ternary(_group[key][col.."_bytes.sent"] ~= nil,
_group[key][col.."_bytes.sent"], 0)
+ hosts_stats[_key]["bytes.sent"]
_group[key][col.."_bytes.rcvd"] = ternary(_group[key][col.."_bytes.rcvd"] ~= nil,
_group[key][col.."_bytes.rcvd"], 0)
+ hosts_stats[_key]["bytes.rcvd"]
::continue::
end
return _group, total
end
function getCurrentTopGroupsSeparated(ifid, ifname, max_num_entries, use_threshold,
use_delta, filter_col, filter_val, col, key, loc, concat, mode, lastdump_key)
max_num_entries = 10
rsp = ""
interface.select(ifname)
hosts_stats = interface.getHostsInfo()
hosts_stats = filterBy(hosts_stats, filter_col, filter_val)
if (loc ~= nil) then
hosts_stats = filterBy(hosts_stats, "localhost", loc)
end
talkers_dir = fixPath(dirs.workingdir .. "/" .. ifid .. "/top_talkers")
if(not(ntop.exists(talkers_dir))) then
ntop.mkdir(talkers_dir)
end
_group, total = groupStatsByColumn(ifid, ifname, col)
if(concat == false and mode == nil) then
rsp = rsp.."{\n"
end
rsp = rsp..'\t"'..key..'": [\n'
if(mode == nil) then
rsp = rsp .. "{\n"
rsp = rsp .. '\t"senders": ['
end
if((mode == nil) or (mode == "senders")) then
top_talkers = getTop(_group, col.."_bytes.sent", max_num_entries, talkers_dir, lastdump_key)
num = 0
for value,id in pairsByKeys(top_talkers, rev) do
if(num > 0) then rsp = rsp .. " }," end
rsp = rsp .. '\n\t\t { "label": "'.._group[id]["name"].. '", "url": "'
..ntop.getHttpPrefix()..
'/lua/hosts_stats.lua?'..col..'='..id..'", "address": "'
..id..'", "value": '..value
num = num + 1
end
end
if(mode == nil) then
if(num > 0) then rsp = rsp .. " }" end
rsp = rsp .. "\n\t],\n"
rsp = rsp .. '\t"receivers": ['
end
if((mode == nil) or (mode == "receivers")) then
top_listeners = getTop(_group, col.."_bytes.rcvd", max_num_entries, talkers_dir, lastdump_key)
num = 0
for value,id in pairsByKeys(top_listeners, rev) do
if(num > 0) then rsp = rsp .. " }," end
rsp = rsp .. '\n\t\t { "label": "'.._group[id]["name"].. '", "url": "'
..ntop.getHttpPrefix()..
'/lua/hosts_stats.lua?'..col..'='..id..'", "address": "'
..id..'", "value": '..value
num = num + 1
end
end
if(mode == nil) then
if(num > 0) then rsp = rsp .. " }" end
rsp = rsp .. "\n\t]\n"
rsp = rsp .. "\n}\n"
else
if(num > 0) then rsp = rsp .. " }\n" end
end
rsp = rsp.."]"
if(concat == false and mode == nil) then
rsp = rsp.."\n}"
end
--print(rsp.."\n")
return(rsp)
end
function getCurrentTopGroups(ifid, ifname, max_num_entries, use_threshold,
use_delta, filter_col, filter_val, col, key, concat, mode, lastdump_key)
rsp = ""
--if(ifname == nil) then ifname = "any" end
interface.select(ifname)
hosts_stats = interface.getHostsInfo()
hosts_stats = filterBy(hosts_stats, filter_col, filter_val)
talkers_dir = fixPath(dirs.workingdir .. "/" .. ifid .. "/top_talkers")
if(not(ntop.exists(talkers_dir))) then
ntop.mkdir(talkers_dir)
end
_group, total = groupStatsByColumn(ifid, ifname, col)
if(concat == true) then
rsp = rsp..'"'..key..'": '
end
rsp = rsp .. "[\n"
-- Get top groups
top_groups = getTop(_group, col.."_bytes", max_num_entries, talkers_dir, lastdump_key, use_threshold)
num = 0
for _value,_key in pairsByKeys(top_groups, rev) do
if(num > 0) then rsp = rsp .. " }," end
rsp = rsp .. '\n\t\t { "label": "'.._key..'", "url": "'
..ntop.getHttpPrefix()..
'/lua/hosts_stats.lua?'..col..'='.._key..'", "name": "'
.._group[_key]["name"]..'", "value": '.._value
num = num + 1
end
if (num > 0) then
rsp = rsp .. " }\n"
end
rsp = rsp .. "\n]"
return(rsp)
end

View file

@ -0,0 +1,206 @@
--
-- (C) 2014-15-15 - ntop.org
--
-- ########
function updateKey(hash_name, key_name, value)
io.write("# "..key_name.." += "..value.."\n")
if(hash_name[key_name] == nil) then
hash_name[key_name] = value
else
hash_name[key_name] = hash_name[key_name] + value
end
end
-- ######
function hash2json(hash_name, label)
print "[\n"
n = 0
for k, v in pairs(hash_name) do
if(n > 0) then print(',\n') end
print('{ "label": "'..k..'", "url": "'..label..'='..k..'", "value": '..v..' }\n')
n = n + 1
end
print("]")
end
-- ######
function sliceHash(hash_name, max_num_entries, sort_direction, url, url_trailer)
local sortedKeys
if(sort_direction == "desc") then
sortedKeys = getKeysSortedByValue(hash_name, function(a, b) return a > b end)
else
sortedKeys = getKeysSortedByValue(hash_name, function(a, b) return a < b end)
end
print "[\n"
n = 0
for _, key in ipairs(sortedKeys) do
if((max_num_entries > 0) and (n > max_num_entries)) then
break
else
if(url == "") then
print('{ "label": "'..key..'", "url": "", "value": '..hash_name[key]..' }\n')
else
print('{ "label": "'..key..'", "url": "'..url..'='..key..url_trailer..'", "value": '..hash_name[key]..' }\n')
end
end
n = n + 1
end
print("]")
end
-- ######
-- host, vlan, unit (bytes/packets), mode (rcvd/sent/both), max_num_entries (10), sort(desc/asc)
function getTalkers(ifname, vlan, unit, mode, max_num_entries, sort_direction)
interface.select(ifname)
hosts_stats = interface.getHostsInfo()
hosts = { }
for key, value in pairs(hosts_stats) do
skip = false
io.write(key.."\n")
if(hosts_stats[key]["ip"] == nil) then
skip = true
else
if(vlan ~= 0) then
if(hosts_stats[key]["vlan"] ~= vlan) then
skip = true
end
end
end
if(skip == false) then
if((mode == "recv") or (mode == "sent")) then
v = hosts_stats[key][unit.."."..mode]
else
v = hosts_stats[key][unit..".sent"] + hosts_stats[key][unit..".rcvd"]
end
updateKey(hosts, key, v)
end
end
sliceHash(hosts, max_num_entries, sort_direction, "/lua/host_details.lua?host", "")
end
-- ########
-- vlan, unit (bytes/packets), mode (rcvd/sent/both), max_num_entries (10), sort(desc/asc)
function getVLANTraffic(ifname, vlan, unit, mode, max_num_entries, sort_direction)
interface.select(ifname)
hosts_stats = interface.getHostsInfo()
hosts = { }
for key, value in pairs(hosts_stats) do
skip = false
io.write(key.."\n")
if(hosts_stats[key]["ip"] == nil) then
skip = true
else
if(vlan ~= 0) then
if(hosts_stats[key]["vlan"] ~= vlan) then
skip = true
end
end
end
if(skip == false) then
if((mode == "recv") or (mode == "sent")) then
v = hosts_stats[key][unit.."."..mode]
else
v = hosts_stats[key][unit..".sent"] + hosts_stats[key][unit..".rcvd"]
end
updateKey(hosts, hosts_stats[key]["vlan"], v)
end
end
sliceHash(hosts, max_num_entries, sort_direction, "", "")
end
-- ########
-- AS, unit (bytes/packets), mode (rcvd/sent/both), max_num_entries (10), sort(desc/asc)
function getASTraffic(ifname, vlan, as, unit, mode, max_num_entries, sort_direction)
interface.select(ifname)
hosts_stats = interface.getHostsInfo()
hosts = { }
for key, value in pairs(hosts_stats) do
skip = false
io.write(key.."\n")
if(hosts_stats[key]["ip"] == nil) then
skip = true
else
if(vlan ~= 0) then
if(hosts_stats[key]["vlan"] ~= vlan) then
skip = true
end
end
end
if(skip == false) then
if((mode == "recv") or (mode == "sent")) then
v = hosts_stats[key][unit.."."..mode]
else
v = hosts_stats[key][unit..".sent"] + hosts_stats[key][unit..".rcvd"]
end
updateKey(hosts, hosts_stats[key]["asn"], v)
end
end
sliceHash(hosts, max_num_entries, sort_direction, "https://www.robtex.com/as/as", ".html")
end
-- host, vlan, unit (bytes/packets), mode (rcvd/sent/both), max_num_entries (10), sort(desc/asc)
function getFlowTalkers(ifname, vlan, unit, mode, max_num_entries, sort_direction)
interface.select(ifname)
hosts_stats = interface.getFlowsInfo()
hosts = { }
for key, value in pairs(hosts_stats) do
skip = false
if(vlan ~= 0) then
if(hosts_stats[key]["vlan"] ~= vlan) then
skip = true
end
end
if(skip == false) then
if(mode == "recv") then
updateKey(hosts, hosts_stats[key]["cli.ip"], hosts_stats[key]["srv2cli."..unit])
updateKey(hosts, hosts_stats[key]["srv.ip"], hosts_stats[key]["cli2srv."..unit])
elseif(mode == "sent") then
updateKey(hosts, hosts_stats[key]["cli.ip"], hosts_stats[key]["cli2srv."..unit])
updateKey(hosts, hosts_stats[key]["srv.ip"], hosts_stats[key]["srv2cli."..unit])
else
v = hosts_stats[key]["cli2srv."..unit] + hosts_stats[key]["srv2cli."..unit]
updateKey(hosts, hosts_stats[key]["cli.ip"], v)
updateKey(hosts, hosts_stats[key]["srv.ip"], v)
end
end
end
for k, v in pairs(hosts) do
io.write(k.."="..v.."\n")
end
end

View file

@ -0,0 +1,179 @@
--
-- (C) 2013-15 - ntop.org
--
-- ########################################################
require "flow_utils"
local payload_type = 0
function isVoip(key,value)
key_label = getFlowKey(key)
if (key_label == "Total number of exported flows") then return 1 end
if (key_label =='Rtp Voice Quality') then
print("<tr><th width=30%>" .. key_label .. '</th><td colspan=2>')
MosPercentageBar(value)
print("</td></tr>\n")
return 1
elseif (key_label=='Sip Call State') then
print("<tr><th width=30%>" .. key_label .. "</th><td colspan=2>")
SipCallStatePercentageBar(value)
print("</td></tr>\n")
return 1
elseif ((key_label == 'Rtp Out Coming Payload Type') or (key_label == "Rtp Incoming Payload Type")) then
if (payload_type == 0) then
payload_type = 1
print("<tr><th width=30%>Rtp Payload Type</th><td colspan=2>"..formatRtpPayloadType(value).."</td></tr>\n")
end
return 1
elseif ((key_label == 'Rtp Out Coming Packet Delay Variation') or (key_label == "Rtp Incoming Packet Delay Variation")) then
print("<tr><th width=30%>" .. key_label .. "</th><td colspan=2>"..((value/1000)/1000).." ms</td></tr>\n")
return 1
elseif ((key_label == 'SIP_CALLED_PARTY') or (key_label == "SIP_CALLING_PARTY")) then
print("<tr><th width=30%>" .. key_label .. "</th><td colspan=2>"..spiltSipID(value).."</td></tr>\n")
return 1
end
return 0
end
function spiltSipID( id )
id = string.gsub(id, "<sip:", "")
id = string.gsub(id, ">", "")
port = split(id,":")
sip_party = split(port[1],"@")
host = interface.getHostInfo(sip_party[2])
if (host ~= nil) then
return('<A HREF="'..ntop.getHttpPrefix()..'/lua/host_details.lua?host='.. sip_party[2]..'">'.. id.. '</A>')
end
return(id)
end
-- RTP
local rtp_payload_type = {
[0] = 'PCMU',
[1] = 'reserved',
[2] = 'reserved',
[3] = 'GSM',
[4] = 'G723',
[5] = 'DVI4',
[6] = 'DVI4',
[7] = 'LPC',
[8] = 'PCMA',
[9] = 'G722',
[10] = 'L16',
[11] = 'L16',
[12] = 'QCELP',
[13] = 'CN',
[14] = 'MPA',
[15] = 'G728',
[16] = 'DVI4',
[17] = 'DVI4',
[18] = 'G729',
[25] = 'CELB',
[26] = 'JPEG',
[28] = 'NV',
[31] = 'H261',
[32] = 'MPV',
[33] = 'MP2T',
[34] = 'H263',
[35] = 'unassigned',
[71] = 'unassigned',
[76] = 'Reserved for RTCP conflict avoidance',
[72] = 'Reserved for RTCP conflict avoidance',
[73] = 'Reserved for RTCP conflict avoidance',
[74] = 'Reserved for RTCP conflict avoidance',
[75] = 'Reserved for RTCP conflict avoidance',
[76] = 'Reserved for RTCP conflict avoidance',
[95] = 'unassigned',
[96] = 'dynamic',
[127] = 'dynamic'
}
-- ########################################################
function formatRtpPayloadType(flags)
flags = tonumber(flags)
if(rtp_payload_type[flags] ~= nil) then
return(rtp_payload_type[flags])
end
return flags;
end
-- ########################################################
function MosPercentageBar(value)
total = 5
bar_class = "bar-info"
value = value /100
value_type = ""
pctg = round((value * 100) / total, 0)
if ((value >= 4.0) and (value <= 5.0)) then
print('<span class="label label-success">'..value..' MOS - Desirable</span>')
end
if ((value >= 3.6) and (value < 4.0)) then
print('<span class="label label-info">'..value..' MOS - Acceptable</span>')
end
if ((value >= 2.6) and (value < 3.6)) then
print('<span class="label label-warning">'..value..' MOS - Reach Connection</span>')
end
if ((value > 0) and (value < 2.6)) then
print('<span class="label label-danger">'..value..' MOS - Not Recommended</span>')
end
end
-- ########################################################
function SipCallStatePercentageBar(state)
-- Wireshark use different state http://wiki.wireshark.org/VoIP_calls
label_class = "label-default"
if (state == "REGISTER") then
label_class = "label-info"
end
if (state == "CALL_STARTED") then
label_class = "label-info"
end
if (state == "CALL_IN_PROGRESS") then
label_class = "label-progress"
end
if (state == "CALL_COMPLETED") then
label_class = "label-success"
end
if (state == "CALL_ERROR") then
label_class = "label-danger"
end
if (state == "CALL_CANCELED") then
label_class = "label-warning"
end
if (state == "UNKNOWN") then
label_class = "bar-warning"
end
print('<span class="label '..label_class..'">'..state..'</span>')
end