diff --git a/include/NetworkInterface.h b/include/NetworkInterface.h
index 747cc0bdc0..4b0d55bc67 100644
--- a/include/NetworkInterface.h
+++ b/include/NetworkInterface.h
@@ -378,10 +378,7 @@ class NetworkInterface {
u_int32_t asnFilter, int16_t networkFilter,
u_int16_t pool_filter, bool filtered_hosts, u_int8_t ipver_filter,
bool hostsOnly, char *groupColumn);
- int getActiveASList(lua_State* vm,
- char *sortColumn, u_int32_t maxHits,
- u_int32_t toSkip, bool a2zSortOrder,
- DetailsLevel details_level);
+ int getActiveASList(lua_State* vm, const Paginator *p);
int getActiveVLANList(lua_State* vm,
char *sortColumn, u_int32_t maxHits,
u_int32_t toSkip, bool a2zSortOrder,
diff --git a/include/Paginator.h b/include/Paginator.h
index 2eb0abecb1..c5c3cfc148 100644
--- a/include/Paginator.h
+++ b/include/Paginator.h
@@ -36,6 +36,7 @@ class Paginator {
u_int16_t vlan_id_filter;
u_int8_t ip_version /* Either 4 or 6 */;
int8_t unicast_traffic, unidirectional_traffic, alerted_flows, filtered_flows;
+ u_int32_t client_asn, server_asn;
u_int32_t deviceIP;
u_int16_t inIndex, outIndex;
u_int16_t pool_filter;
@@ -116,6 +117,14 @@ class Paginator {
if(server_mode) { (*f) = server_mode; return true; } return false;
}
+ inline bool clientASN(u_int32_t *f) const {
+ if(client_asn != (u_int32_t)-1) { (*f) = client_asn; return true; } return false;
+ }
+
+ inline bool serverASN(u_int32_t *f) const {
+ if(server_asn != (u_int32_t)-1) { (*f) = server_asn; return true; } return false;
+ }
+
inline bool unidirectionalTraffic(bool *f) const {
if(unidirectional_traffic != -1) { (*f) = (unidirectional_traffic==1) ? true : false; return true; } return false;
}
diff --git a/scripts/callbacks/5min.lua b/scripts/callbacks/5min.lua
index 44c4dca51b..7784349345 100644
--- a/scripts/callbacks/5min.lua
+++ b/scripts/callbacks/5min.lua
@@ -237,7 +237,7 @@ callback_utils.foreachInterface(ifnames, interface_rrd_creation_enabled, functio
if asn_rrd_creation == "1" then
local basedir = fixPath(dirs.workingdir .. "/" .. ifstats.id..'/asnstats')
- local asn_info = interface.getASesInfo()
+ local asn_info = interface.getASesInfo({detailsLevel = "higher"})
for _, asn_stats in ipairs(asn_info["ASes"]) do
local asn = asn_stats["asn"]
diff --git a/scripts/locales/en.lua b/scripts/locales/en.lua
index 5d5fa56820..e3d2d4d081 100644
--- a/scripts/locales/en.lua
+++ b/scripts/locales/en.lua
@@ -83,6 +83,7 @@ local en = {
mac_address = "MAC Address",
as_number = "AS number",
asn = "ASN",
+ as = "AS",
peers = "Peers",
activities = "Activities",
dns = "DNS",
@@ -171,6 +172,9 @@ local en = {
all_outIfIdx = "All Output Interfaces",
vlan = "VLAN",
all_vlan_ids = "All VLANs",
+ client_as = "Client AS",
+ server_as = "Server AS",
+ all_ases = "All ASes",
actual_throughput = "Actual Thpt",
total_bytes = "Total Bytes",
applications = "Applications",
diff --git a/scripts/lua/flows_stats.lua b/scripts/lua/flows_stats.lua
index 81830a0934..4af2475558 100644
--- a/scripts/lua/flows_stats.lua
+++ b/scripts/lua/flows_stats.lua
@@ -42,6 +42,9 @@ local port = _GET["port"]
local network_id = _GET["network"]
+local client_asn = _GET["client_asn"]
+local server_asn = _GET["server_asn"]
+
local prefs = ntop.getPrefs()
interface.select(ifname)
local ifstats = interface.getStats()
@@ -151,6 +154,14 @@ if(network_id ~= nil) then
page_params["network"] = network_id
end
+if(client_asn ~= nil) then
+ page_params["client_asn"] = client_asn
+end
+
+if(server_asn ~= nil) then
+ page_params["server_asn"] = server_asn
+end
+
if(flowhosts_type ~= nil) then
page_params["flowhosts_type"] = flowhosts_type
flowhosts_type_filter = ' '
@@ -217,7 +228,6 @@ local function printDropdownEntries(entries, param_arr, param_filter, curr_filte
print[[>]] print(htype[2]) print[[ ]]
end
end
-
print[['\
\
]] print(i18n("flows_page.hosts")) print(flowhosts_type_filter) print[[ \
@@ -319,6 +329,11 @@ end
if ntop.isPro() and interface.isPacketInterface() == false then
printFlowDevicesFilterDropdown(base_url, vlan_params)
end
+
+if ntop.isEnterprise() then
+ printFlowASesFilterDropdown(base_url, table.clone(page_params))
+end
+
-- end buttons
print(" ],\n")
diff --git a/scripts/lua/get_ases_data.lua b/scripts/lua/get_ases_data.lua
index f26124f00b..cdc3cf956e 100644
--- a/scripts/lua/get_ases_data.lua
+++ b/scripts/lua/get_ases_data.lua
@@ -55,8 +55,9 @@ to_skip = (currentPage-1) * perPage
if(sortOrder == "desc") then sOrder = false else sOrder = true end
-local ases_stats = interface.getASesInfo(sortColumn, perPage, to_skip, sOrder,
- false --[[high, but not higher details as there's no need for nDPI here --]])
+local ases_stats = interface.getASesInfo({sortColumn = sortColumn,
+ maxHits = perPage, toSkip = to_skip,
+ a2zSortOrder = sOrder, detailsLevel = "high"})
local total_rows = 0
diff --git a/scripts/lua/get_flows_data.lua b/scripts/lua/get_flows_data.lua
index 0f6f42d84d..d809b87d7b 100644
--- a/scripts/lua/get_flows_data.lua
+++ b/scripts/lua/get_flows_data.lua
@@ -32,6 +32,9 @@ local deviceIP = _GET["deviceIP"]
local inIfIdx = _GET["inIfIdx"]
local outIfIdx = _GET["outIfIdx"]
+local client_asn = _GET["client_asn"]
+local server_asn = _GET["server_asn"]
+
local vhost = _GET["vhost"]
local flowhosts_type = _GET["flowhosts_type"]
local ipversion = _GET["version"]
@@ -167,6 +170,14 @@ if not isEmptyString(deviceIP) then
end
end
+if not isEmptyString(client_asn) then
+ pageinfo["clientASNFilter"] = tonumber(client_asn)
+end
+
+if not isEmptyString(server_asn) then
+ pageinfo["serverASNFilter"] = tonumber(server_asn)
+end
+
local flows_stats = interface.getFlowsInfo(host, pageinfo)
local total = flows_stats["numFlows"]
flows_stats = flows_stats["flows"]
diff --git a/scripts/lua/modules/http_lint.lua b/scripts/lua/modules/http_lint.lua
index 1a0828f887..ab60a3169c 100644
--- a/scripts/lua/modules/http_lint.lua
+++ b/scripts/lua/modules/http_lint.lua
@@ -770,6 +770,8 @@ local known_parameters = {
["alert_severity"] = validateNumber, -- An alert severity enum
["entity"] = validateNumber, -- An alert entity type
["asn"] = validateNumber, -- An ASN number
+ ["client_asn"] = validateNumber, -- A client ASN number
+ ["server_asn"] = validateNumber, -- A server ASN number
["module"] = validateTopModule, -- A top script module
["step"] = validateNumber, -- A step value
["cf"] = validateConsolidationFunction, -- An RRD consolidation function
diff --git a/scripts/lua/modules/lua_utils.lua b/scripts/lua/modules/lua_utils.lua
index 29439753a0..8758d18a98 100644
--- a/scripts/lua/modules/lua_utils.lua
+++ b/scripts/lua/modules/lua_utils.lua
@@ -402,6 +402,59 @@ end
-- ##############################################
+function printFlowASesFilterDropdown(base_url, page_params)
+ if(ntop.isEnterprise()) then
+ package.path = dirs.installdir .. "/pro/scripts/lua/modules/?.lua;" .. package.path
+ end
+
+ local ases = interface.getASesInfo({sortColumn = "column_asn", detailsLevel = "normal"})
+
+ if ases == nil then ases = {ASes = {}} end
+
+ for _, p in ipairs({
+ {side = "server_asn", title = i18n("flows_page.server_as")},
+ {side = "client_asn", title = i18n("flows_page.client_as")}}
+ ) do
+
+ local side = p["side"]
+ local title = p["title"]
+
+ local cur_as = _GET[side]
+ local cur_as_filter = ''
+ if not isEmptyString(cur_as) then
+ cur_as_filter = '
'
+ end
+
+ local as_params = table.clone(page_params)
+ as_params[side] = nil
+
+ print[[, '
\
+ ]] print(title) print[[]] print(cur_as_filter) print[[ \
+ \
+
']]
+
+ end
+
+end
+
+-- ##############################################
+
--
-- Returns indexes to be used for string shortening. The portion of to_shorten between
-- middle_start and middle_end will be inside the bounds.
diff --git a/src/AutonomousSystem.cpp b/src/AutonomousSystem.cpp
index 2bcb3eab84..28c232b103 100644
--- a/src/AutonomousSystem.cpp
+++ b/src/AutonomousSystem.cpp
@@ -76,16 +76,16 @@ void AutonomousSystem::lua(lua_State* vm, DetailsLevel details_level, bool asLis
if(details_level >= details_high) {
((GenericTrafficElement*)this)->lua(vm, true);
+ lua_push_int_table_entry(vm, "seen.first", first_seen);
+ lua_push_int_table_entry(vm, "seen.last", last_seen);
+ lua_push_int_table_entry(vm, "duration", get_duration());
+
+ lua_push_int_table_entry(vm, "num_hosts", getNumHosts());
+
if(details_level >= details_higher)
if(ndpiStats) ndpiStats->lua(iface, vm);
}
- lua_push_int_table_entry(vm, "seen.first", first_seen);
- lua_push_int_table_entry(vm, "seen.last", last_seen);
- lua_push_int_table_entry(vm, "duration", get_duration());
-
- lua_push_int_table_entry(vm, "num_hosts", getNumHosts());
-
if(asListElement) {
lua_pushnumber(vm, asn);
lua_insert(vm, -2);
diff --git a/src/Lua.cpp b/src/Lua.cpp
index 0cb8ed2b75..23f4a9d969 100644
--- a/src/Lua.cpp
+++ b/src/Lua.cpp
@@ -882,37 +882,25 @@ static int ntop_get_mac_device_types(lua_State* vm) {
static int ntop_get_interface_ases_info(lua_State* vm) {
NetworkInterface *ntop_interface = getCurrentInterface(vm);
- char *sortColumn = (char*)"column_asn";
- u_int32_t toSkip = 0, maxHits = CONST_MAX_NUM_HITS;
- bool a2zSortOrder = true;
- DetailsLevel details_level = details_higher;
- if(lua_type(vm, 1) == LUA_TSTRING) {
- sortColumn = (char*)lua_tostring(vm, 1);
+ Paginator *p = NULL;
- if(lua_type(vm, 2) == LUA_TNUMBER) {
- maxHits = (u_int16_t)lua_tonumber(vm, 2);
-
- if(lua_type(vm, 3) == LUA_TNUMBER) {
- toSkip = (u_int16_t)lua_tonumber(vm, 3);
-
- if(lua_type(vm, 4) == LUA_TBOOLEAN) {
- a2zSortOrder = lua_toboolean(vm, 4) ? true : false;
-
- if(lua_type(vm, 5) == LUA_TBOOLEAN) {
- details_level = lua_toboolean(vm, 4) ? details_higher : details_high;
- }
- }
- }
- }
- }
-
- if(!ntop_interface ||
- ntop_interface->getActiveASList(vm,
- sortColumn, maxHits,
- toSkip, a2zSortOrder, details_level) < 0)
+ if(!ntop_interface)
return(CONST_LUA_ERROR);
+ if((p = new(std::nothrow) Paginator()) == NULL)
+ return(CONST_LUA_ERROR);
+
+ if(lua_type(vm, 1) == LUA_TTABLE)
+ p->readOptions(vm, 1);
+
+ if(!ntop_interface ||
+ ntop_interface->getActiveASList(vm, p) < 0) {
+ if(p) delete(p);
+ return(CONST_LUA_ERROR);
+ }
+
+ if(p) delete(p);
return(CONST_LUA_OK);
}
diff --git a/src/NetworkInterface.cpp b/src/NetworkInterface.cpp
index 57a0d8aee7..3f5d670aa5 100644
--- a/src/NetworkInterface.cpp
+++ b/src/NetworkInterface.cpp
@@ -2930,6 +2930,7 @@ static bool flow_matches(Flow *f, struct flowHostRetriever *retriever) {
LocationPolicy client_policy;
LocationPolicy server_policy;
bool unicast, unidirectional, alerted_flows;
+ u_int32_t client_asn, server_asn;
u_int32_t deviceIP;
u_int16_t inIndex, outIndex;
#ifdef NTOPNG_PRO
@@ -2967,6 +2968,16 @@ static bool flow_matches(Flow *f, struct flowHostRetriever *retriever) {
return(false);
}
+ if(retriever->pag
+ && retriever->pag->clientASN(&client_asn)
+ && (!f->get_cli_host() || f->get_cli_host()->get_asn() != client_asn))
+ return(false);
+
+ if(retriever->pag
+ && retriever->pag->serverASN(&server_asn)
+ && (!f->get_srv_host() || f->get_srv_host()->get_asn() != server_asn))
+ return(false);
+
if(retriever->pag
&& retriever->pag->portFilter(&port)
&& f->get_cli_port() != port
@@ -5601,33 +5612,37 @@ int NetworkInterface::getActiveMacList(lua_State* vm,
/* **************************************** */
-int NetworkInterface::getActiveASList(lua_State* vm,
- char *sortColumn, u_int32_t maxHits,
- u_int32_t toSkip, bool a2zSortOrder,
- DetailsLevel details_level) {
+int NetworkInterface::getActiveASList(lua_State* vm, const Paginator *p) {
struct flowHostRetriever retriever;
+ DetailsLevel details_level;
+
+ if(!p)
+ return -1;
disablePurge(false);
- if(sortASes(&retriever, sortColumn) < 0) {
+ if(sortASes(&retriever, p->sortColumn()) < 0) {
enablePurge(false);
return -1;
}
+ if(!p->getDetailsLevel(&details_level))
+ details_level = details_normal;
+
lua_newtable(vm);
lua_push_int_table_entry(vm, "numASes", retriever.actNumEntries);
lua_newtable(vm);
- if(a2zSortOrder) {
- for(int i = toSkip, num=0; i<(int)retriever.actNumEntries && num < (int)maxHits; i++, num++) {
+ if(p->a2zSortOrder()) {
+ for(int i = p->toSkip(), num = 0; i < (int)retriever.actNumEntries && num < (int)p->maxHits(); i++, num++) {
AutonomousSystem *as = retriever.elems[i].asValue;
as->lua(vm, details_level, false);
lua_rawseti(vm, -2, num + 1); /* Must use integer keys to preserve and iterate inorder with ipairs */
}
} else {
- for(int i = (retriever.actNumEntries-1-toSkip), num=0; i >= 0 && num < (int)maxHits; i--, num++) {
+ for(int i = (retriever.actNumEntries - 1 - p->toSkip()), num = 0; i >= 0 && num < (int)p->maxHits(); i--, num++) {
AutonomousSystem *as = retriever.elems[i].asValue;
as->lua(vm, details_level, false);
diff --git a/src/Paginator.cpp b/src/Paginator.cpp
index 2685ec210c..4903b24cb4 100644
--- a/src/Paginator.cpp
+++ b/src/Paginator.cpp
@@ -51,6 +51,7 @@ Paginator::Paginator() {
mac_filter = NULL;
deviceIP = inIndex = outIndex = 0;
+ client_asn = server_asn = (u_int32_t)-1;
details_level = details_normal;
details_level_set = false;
@@ -164,6 +165,11 @@ void Paginator::readOptions(lua_State *L, int index) {
ip_version = lua_tointeger(L, -1);
else if(!strcmp(key, "poolFilter"))
pool_filter = lua_tointeger(L, -1);
+ else if(!strcmp(key, "clientASNFilter"))
+ client_asn = lua_tointeger(L, -1);
+ else if(!strcmp(key, "serverASNFilter"))
+ server_asn = lua_tointeger(L, -1);
+
//else
//ntop->getTrace()->traceEvent(TRACE_ERROR, "Invalid int type (%d) for option %s", lua_tointeger(L, -1), key);
break;