File: get_historical_data.lua

package info (click to toggle)
ntopng 2.4%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 15,888 kB
  • ctags: 8,091
  • sloc: cpp: 21,442; ansic: 10,999; sh: 1,627; makefile: 423; pascal: 312; ruby: 34; exp: 4
file content (248 lines) | stat: -rw-r--r-- 8,308 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
--
-- (C) 2013-16 - ntop.org
--

dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
require "top_talkers"
require "db_utils"
local json = require ("dkjson")

sendHTTPHeader('text/html; charset=iso-8859-1')

ifid = getInterfaceId(ifname)

-- query parameters
local epoch_start = _GET["epoch_start"]
local epoch_end = _GET["epoch_end"]

-- use this two params to see statistics of a single host
-- or for a pair of them
local peer1 = _GET["peer1"]
local peer2 = _GET["peer2"]
if peer2 and not peer1 then
	peer1 = peer2
	peer2 = nil
end

-- this is to retrieve L7 appliation data
local l7_proto_id = _GET["l7_proto_id"]

-- and this to focus only on a certain l4 proto
local l4_proto_id = _GET["l4_proto_id"]

-- also add a port
local port = _GET["port"]

local host_info = url2hostinfo(_GET)
local host = nil
if host_info["host"] then
   host = interface.getHostInfo(host_info["host"],host_info["vlan"])
end


-- specify the type of stats
local stats_type = _GET["stats_type"]
if stats_type == nil or (stats_type ~= "top_talkers" and stats_type ~= "top_applications" and stats_type ~= "peers_traffic_histogram") then
	-- default to top traffic
	stats_type = "top_talkers"
end

-- datatable parameters
local current_page = _GET["currentPage"]
local per_page     = _GET["perPage"]
local sort_column  = _GET["sortColumn"]
local sort_order   = _GET["sortOrder"]
local total_rows   = _GET["totalRows"]

if not sort_column or sort_column == "" then
   sort_column = getDefaultTableSort("historical_stats_"..stats_type)
else
   if sort_column ~= "column_" then
      tablePreferences("sort_historical_stats_"..stats_type, sort_column)
   end
end

tablePreferences("sort_order_historical_stats_"..stats_type,sort_order)
--[[
if not sort_order or sort_order == "" then
   sort_order = getDefaultTableSortOrder("historical_stats_"..stats_type)
   io.write('got by default '..sort_order..'\n')
else
   tablePreferences("sort_order_historical_stats_"..stats_type,sort_order)
end
]]

if sort_order == "asc" then
   funct = asc
else
   funct = rev
end

if current_page == nil then
   current_page = 1
else
   current_page = tonumber(current_page)
end

if per_page == nil then
   per_page = getDefaultTableSize()
else
   per_page = tonumber(per_page)
   tablePreferences("historical_rows_number", per_page)
end
local to_skip = (current_page - 1) * per_page
if to_skip < 0 then to_skip = 0 end

-- prepare queries offset an limit depending on
-- received values. A received value total_rows = -1 (or total_rows == nil)
-- means that the interface doesn't know the number of rows
-- and thus it is up to this script to compute it, and
-- send it back to the caller

if total_rows == nil or tonumber(total_rows) == nil then
   total_rows = -1
else
   total_rows = tonumber(total_rows)
end

-- default: 100 rows starting from offset 0
local offset = 0
local limit = 100
if total_rows ~= -1 then
   offset = to_skip
   limit = per_page
end

-- start building the response
local res = {["status"] = "unable to parse the request, please check input parameters."}
if stats_type == "top_talkers" then
   if not peer1 and not peer2 and not l7_proto_id then
      -- CASE 01: compute interface-wide top-talkers for the selected time interval
      res = getOverallTopTalkers(ifid, l4_proto_id, port, nil, epoch_start, epoch_end, sort_column, sort_order, offset, limit)
      for _, record in pairs(res) do
	 record["label"] = ntop.getResolvedAddress(record["addr"])
      end
   elseif not peer1 and not peer2 and l7_proto_id and l7_proto_id ~= "" then
      -- CASE 02: compute top-talkers for the specified L7 protocol
      res = getAppTopTalkers(ifid, l7_proto_id, l4_proto_id, port, nil, epoch_start, epoch_end, sort_column, sort_order, offset, limit)

      for _, record in pairs(res) do
	 record["label"] = ntop.getResolvedAddress(record["addr"])
      end
   elseif peer1 and peer1 ~="" then
      -- CASE 03: compute top-talkers with the given peer1
      -- if l7_proto_id is specified and non-nil, then top-talkers are computed
      -- with reference to peer1 and restricted to the application identified by l7_proto_id
      res = getHostTopTalkers(ifid, peer1, l7_proto_id, l4_proto_id, port, nil, epoch_start, epoch_end, sort_column, sort_order, offset, limit)

      for _, record in pairs(res) do
	 record["label"] = ntop.getResolvedAddress(record["addr"])
      end
      -- tprint(res)
   end
   if res ~= nil then
      for _, record in pairs(res) do
	 record["label"] = shortenString(record["label"])
      end
   end
elseif stats_type =="top_applications" then
   res = getTopApplications(ifid, peer1, peer2, l7_proto_id, l4_proto_id, port, nil, epoch_start, epoch_end, sort_column, sort_order, offset, limit)

   -- add protocol labels
   for _, record in pairs(res) do
      record["label"] = getApplicationLabel(interface.getnDPIProtoName(tonumber(record["application"])))
   end
   if res ~= nil then
      for _, record in pairs(res) do
      end
   end
   -- tprint(res)
elseif stats_type =="peers_traffic_histogram" and peer1 and peer2 then
   res = getPeersTrafficHistogram(ifid, peer1, peer2, nil, epoch_start + 60, epoch_end + 60)

   for _, record in pairs(res) do
      record["peer1_label"] = ntop.getResolvedAddress(record["peer1_addr"])
      record["peer2_label"] = ntop.getResolvedAddress(record["peer2_addr"])
   end
   -- tprint(res)
end

-- slice the result if the interface didn't know the total_rows
local res_sliced = {}
if total_rows ~= -1 then
   -- nothing to slice here, query has already sliced the result
   res_sliced = res
else --  i.e., total_rows == -1, that it, it was unknown
   -- slice the first page of the results
   -- and update total_rows
   local cur = 0
   for _, record in pairs(res) do
      if cur < per_page then
	 table.insert(res_sliced, record)
      end
      cur = cur + 1
   end
   total_rows = cur
end

-- make res_formatted compliant with column_ notation
-- also add hyperlinks, bytes format, etc.
local res_formatted = {}
for _, record in pairs(res_sliced) do
   local record_contents = {}
   if not record["label"] or record["label"] == "" then record["label"] = record["addr"] end
   record_contents["column_label"] = record["label"]
   record_contents["column_addr"] = record["addr"]
   if record["application"] then record_contents["column_application"] = record["application"] end
   -- 'normalize' possible different names, e.g., group bytes or tot_bytes in bytes
   -- and rename fields with the 'column_' prefix that is conventionally used in the interface
   if record["bytes"] then
      record_contents["column_bytes"] = bytesToSize(tonumber(record["bytes"]))
   elseif record["tot_bytes"] then
      record_contents["column_bytes"] = bytesToSize(tonumber(record["tot_bytes"]))
   else
      record_contents["column_bytes"] = "n.a."
   end
   if record["packets"] then
      record_contents["column_packets"] = formatValue(tonumber(record["packets"]))
   elseif record["tot_packets"] then
      record_contents["column_packets"] = formatValue(tonumber(record["tot_packets"]))
   else
      record_contents["column_packets"] = "n.a."
   end
   if record["bytes_sent"] then
      record_contents["column_bytes_sent"] = bytesToSize(tonumber(record["bytes_sent"]))
   else
      record_contents["column_bytes_sent"] = "n.a."
   end
   if record["bytes_rcvd"] then
      record_contents["column_bytes_rcvd"] = bytesToSize(tonumber(record["bytes_rcvd"]))
   else
      record_contents["column_bytes_rcvd"] = "n.a."
   end
   if record["flows"] then
      record_contents["column_flows"] = formatValue(tonumber(record["flows"]))
   elseif record["tot_flows"] then
      record_contents["column_flows"] = formatValue(tonumber(record["tot_flows"]))
   else
      record_contents["column_flows"] = "n.a."
   end
   if record["avg_flow_duration"] then
      record_contents["column_avg_flow_duration"] = secondsToTime(tonumber(record["avg_flow_duration"]))
   end
   table.insert(res_formatted, record_contents)
end

-- tprint(res_formatted)
-- tprint(res)

local result = {}
result["perPage"] = per_page
result["currentPage"] = current_page
result["totalRows"] = total_rows
result["data"] = res_formatted
result["sort"] = {{sort_column, sort_order}}

print(json.encode(result, nil))