File: custom_column_utils.lua

package info (click to toggle)
ntopng 5.2.1%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 121,832 kB
  • sloc: javascript: 143,431; cpp: 71,175; ansic: 11,108; sh: 4,687; makefile: 911; python: 587; sql: 512; pascal: 234; perl: 118; ruby: 52; exp: 4
file content (198 lines) | stat: -rw-r--r-- 7,741 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
--
-- (C) 2021 - ntop.org
--

local format_utils = require("format_utils")
local custom_column_utils = {}

local dirs = ntop.getDirs()

local custom_column_pref_key = "ntopng.prefs.custom_column"

-- IMPORTANT: keep it in sync with sortField (ntop_typedefs.h)
--            AND host_search_walker:NetworkInterface.cpp
--            AND NetworkInterface::getFlows()
custom_column_utils.available_custom_columns = {
   -- KEY  LABEL   Host::lua()_label  formatting  additonal_url  hidden
   { "mac", i18n("mac_address"), "mac", get_symbolic_mac --[[ Don't touch it, already formatted --]], "left" },
   { "traffic_sent", i18n("flows_page.total_bytes_sent"), "bytes.sent", bytesToSize, "right" },
   { "traffic_rcvd", i18n("flows_page.total_bytes_rcvd"), "bytes.rcvd", bytesToSize, "right" },
   { "traffic_unknown", i18n("flows_page.total_bytes_unknown"), "bytes.ndpi.unknown", bytesToSize, "right" },
   { "num_flows_as_client", i18n("flows_page.flows_as_client"), "active_flows.as_client", format_utils.formatValue, "center", {page = "flows"} },
   { "num_flows_as_server", i18n("flows_page.flows_as_server"), "active_flows.as_server", format_utils.formatValue, "center", {page = "flows"} },
   { "total_num_alerted_flows_as_client", i18n("total_outgoing_alerted_flows"), "alerted_flows.as_client", format_utils.formatValue, "center" },
   { "total_num_alerted_flows_as_server", i18n("total_incoming_alerted_flows"), "alerted_flows.as_server", format_utils.formatValue, "center" },
   { "total_num_unreachable_flows_as_client", i18n("total_outgoing_unreachable_flows"), "unreachable_flows.as_client", format_utils.formatValue, "center" },
   { "total_num_unreachable_flows_as_server", i18n("total_incoming_unreachable_flows"), "unreachable_flows.as_server", format_utils.formatValue, "center" },
   { "total_num_retx_sent", i18n("total_retransmissions_sent"), function(host_stats) return host_stats["tcpPacketStats.sent"]["retransmissions"] end, format_utils.formatValue, "center" },
   { "total_num_retx_rcvd", i18n("total_retransmissions_rcvd"), function(host_stats) return host_stats["tcpPacketStats.rcvd"]["retransmissions"] end, format_utils.formatValue, "center" },
   { "alerts", i18n("show_alerts.engaged_alerts"), "num_alerts", format_utils.formatValue, "center", {page = "alerts"} },
   { "total_alerts", i18n("alerts_dashboard.total_alerts"), "total_alerts", format_utils.formatValue, "center" },
   { "score", i18n("score"), "score", format_utils.formatValue, "center", nil, (not isScoreEnabled()) },
   { "score_as_client", i18n("score_as_client"), "score.as_client", format_utils.formatValue, "center", nil, (not isScoreEnabled()) },
   { "score_as_server", i18n("score_as_server"), "score.as_server", format_utils.formatValue, "center", nil, (not isScoreEnabled()) },
}
local available_custom_columns = custom_column_utils.available_custom_columns

-- ###########################################

-- @brief Getter for host_stats values
--        Need this getter as there are certain host keys which contain dots, so
--        lua is unhappy and doesn't allow us to use the dot-notation to access table keys.
--        For example host_stats["tcpPacketStats.sent"]["retransmissions"] has "tcpPacketStats.sent" which
--        contains a dot so we are unable to use the notation host_stats.tcpPacketStats.sent.retransmissions as
--        done for other keys. To access these keys, we need to use the [] notation inside a `key` function.
local function host_stats_getter(host_stats, key)
   if type(key) == "string" then
      return host_stats[key]
   elseif type(key) == "function" then
      return  key(host_stats)
   end
end

-- ###########################################

function custom_column_utils.hostStatsToColumnValue(host_stats, column, formatted)
   for _, c in ipairs(available_custom_columns) do
      if c[1] == column then
	 local val = nil

	 if formatted then
	    val = host_stats_getter(host_stats, c[3])

	    if not tonumber(val) or val > 0 then
	       val = c[4](val)
	    else
	       val = ""
	    end

	    if((c[6] ~= nil) and (tonumber(val) ~= 0)) then
	       val = hostinfo2detailshref(host_stats, c[6], val)
	   end
	 else
	    val = host_stats_getter(host_stats, c[3])
	 end

         return(val)
      end
   end
end

-- ###########################################

function custom_column_utils.label2criteriakey(what)
   what = what:gsub("^column_", "")
   local id

   for id, _ in ipairs(available_custom_columns) do
      local c        = available_custom_columns[id][1]
      local fnctn    = available_custom_columns[id][4]

      if(what == c) then
	 return what, fnctn
      end
   end

   return what, format_utils.formatValue
end

-- ###########################################

function custom_column_utils.getCustomColumnName()
   local cc = ntop.getPref(custom_column_pref_key)

   local res = ""

   for _, lg in ipairs(custom_column_utils.available_custom_columns) do
      local key   = lg[1]
      local label = lg[2]
      local align = lg[5]

      if cc == key then
	 return label, key, align
      end
   end

   return custom_column_utils.available_custom_columns[1][2], custom_column_utils.available_custom_columns[1][1], custom_column_utils.available_custom_columns[1][5]
end

-- ###########################################

local function setCustomColumnName(custom_column_name)
   local res

   for _, lg in ipairs(custom_column_utils.available_custom_columns) do
      local key   = lg[1]
      local label = lg[2]

      if custom_column_name == key then
	 ntop.setPref(custom_column_pref_key, custom_column_name)
	 return true
      end
   end

   return false
end

-- ###########################################

function custom_column_utils.updateCustomColumn()
   local _, current_column = custom_column_utils.getCustomColumnName()

   if not isEmptyString(_GET["custom_column"]) and (_GET["custom_column"] ~= current_column) then
      if setCustomColumnName(_GET["custom_column"]) then
	 local custom_column_key, custom_column_format = custom_column_utils.label2criteriakey(_GET["custom_column"])

	 tablePreferences("sort_hosts", "column_"..custom_column_key)
	 tablePreferences("sort_order_hosts", "desc")
      end
   end
end

-- ###########################################

function custom_column_utils.isCustomColumn(column)
   local c = column:gsub("^column_", "")

   for _, lg in ipairs(custom_column_utils.available_custom_columns) do
      if c == lg[1] then
	 return true
      end
   end

   return false
end

-- ###########################################

function custom_column_utils.printCustomColumnDropdown(base_url, page_params)
   local custom_column = custom_column_utils.getCustomColumnName()

   -- table.clone needed to modify some parameters while keeping the original unchanged
   local custom_column_params = table.clone(page_params)
   custom_column_params["custom_column"] = nil

   print[[\
      <button class="btn btn-link dropdown-toggle" data-bs-toggle="dropdown"><i class="fas fa-columns" aria-hidden="true"></i><span class="caret"></span></button>\
      <ul class="dropdown-menu scrollable-dropdown" role="menu" id="custom_column_dropdown">]]

   for _, lg in ipairs(custom_column_utils.available_custom_columns) do
      local key = lg[1]
      local label = lg[2]
      local hidden = lg[7]

      if hidden then
	 goto continue
      end

      print[[<li><a class="dropdown-item ]] print(custom_column == label and 'active' or '') print[[" href="]] custom_column_params["custom_column"] = key; print(getPageUrl(base_url, custom_column_params)); print[[">]] print(label) print[[</a></li>]]

      ::continue::
   end

   print[[</ul>]]
end

-- ###########################################

return custom_column_utils