ntopng/scripts/lua/modules/sqlite_utils.lua
Luca Deri 603c642469 Improved mac address support
Added host icons with their role in the netwokr
2016-10-03 23:16:40 +02:00

288 lines
8.5 KiB
Lua

--
-- (C) 2014-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)