diff --git a/httpdocs/templates/pages/alerts/datatable.js.template b/httpdocs/templates/pages/alerts/datatable.js.template index 10f8fd02f0..61a5bed2e6 100644 --- a/httpdocs/templates/pages/alerts/datatable.js.template +++ b/httpdocs/templates/pages/alerts/datatable.js.template @@ -209,14 +209,21 @@ const $disableAlert = $('#alerts_filter_dialog form').modalHandler({ $(`#cli_radio`).parent().hide(); } else if (FAMILY === "flow") { + let cliValue = alert.flow.cli_ip.value + let srvValue = alert.flow.srv_ip.value - const cliLabel = (alert.flow.cli_ip.label) ? `${alert.flow.cli_ip.label} (${alert.flow.cli_ip.value})` : alert.flow.cli_ip.value; - const srvLabel = (alert.flow.srv_ip.label) ? `${alert.flow.srv_ip.label} (${alert.flow.srv_ip.value})` : alert.flow.srv_ip.value; + if((alert.flow.vlan != undefined) && (alert.flow.vlan.value != 0)) { + cliValue = cliValue + '@' + alert.flow.vlan.value + srvValue = srvValue + '@' + alert.flow.vlan.value + } + const cliLabel = (alert.flow.cli_ip.label) ? `${alert.flow.cli_ip.label} (${cliValue})` : cliValue; + const srvLabel = (alert.flow.srv_ip.label) ? `${alert.flow.srv_ip.label} (${srvValue})` : srvValue; + $(`#cli_addr`).text(cliLabel); - $(`#cli_radio`).val(alert.flow.cli_ip.value); + $(`#cli_radio`).val(cliValue); $(`#srv_addr`).text(srvLabel); - $(`#srv_radio`).val(alert.flow.srv_ip.value); + $(`#srv_radio`).val(srvValue); } else { $(`.alert_entity_val`).text("Unexpected alert family") diff --git a/include/Utils.h b/include/Utils.h index 9ab3df694a..d34a81f639 100755 --- a/include/Utils.h +++ b/include/Utils.h @@ -50,6 +50,7 @@ public: static u_int8_t l4name2proto(const char *name); static u_int8_t queryname2type(const char *name); static bool isIPAddress(const char *ip); + static void splitAddressAndVlan(char *addr, VLANid *vlan_id); static const bool isIpEmpty(ipAddress addr); #ifdef __linux__ static int setAffinityMask(char *cores_list, cpu_set_t *mask); diff --git a/include/VLANAddressTree.h b/include/VLANAddressTree.h index e003e2aba1..c9eed054ac 100644 --- a/include/VLANAddressTree.h +++ b/include/VLANAddressTree.h @@ -52,6 +52,8 @@ class VLANAddressTree { int16_t findAddress(VLANid vlan_id, int family, void *addr, u_int8_t *network_mask_bits = NULL); int16_t findMac(VLANid vlan_id, const u_int8_t addr[]); + void *findAndGetData(VLANid vlan_id, const IpAddress * const ipa) const; + bool addVLANAddressAndData(VLANid vlan_id, const char *_what, void *user_data); inline AddressTree *getAddressTree(VLANid vlan_id) { return tree[vlan_id]; }; }; diff --git a/scripts/lua/alert_stats.lua b/scripts/lua/alert_stats.lua index 68f7c99b0b..b04b1ba322 100644 --- a/scripts/lua/alert_stats.lua +++ b/scripts/lua/alert_stats.lua @@ -293,6 +293,7 @@ end local prefs = ntop.getPrefs() local download_endpoint_list = endpoint_list +local download_file_name = 'alerts-' .. os.time() page_utils.set_active_menu_entry(page_utils.menu_entries.detected_alerts) @@ -637,8 +638,8 @@ local datatable = { modals = modals, download = { endpoint = download_endpoint_list, - filename = "alerts.txt", - format = "txt", + filename = "download_file_name.csv", + format = "csv", i18n = i18n('show_alerts.download_alerts'), }, endpoint_delete = endpoint_delete, diff --git a/scripts/lua/modules/alert_exclusions.lua b/scripts/lua/modules/alert_exclusions.lua index 6805acc521..3d53e2cb66 100644 --- a/scripts/lua/modules/alert_exclusions.lua +++ b/scripts/lua/modules/alert_exclusions.lua @@ -8,7 +8,6 @@ package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path require "lua_utils" local alert_consts = require "alert_consts" -local alert_entities = require "alert_entities" local json = require "dkjson" -- ############################################## @@ -59,28 +58,33 @@ end -- ############################################## -local function _check_host_ip_alert_key(host_ip, alert_key) - if not isIPv4(host_ip) and not isIPv6(host_ip) and not isIPv4Network(host_ip) then - -- Invalid host submitted - return false - end +local function _check_host_ip_vlan_id_alert_key(host_ip, vlan_id, alert_key) + if not isIPv4(host_ip) and not isIPv6(host_ip) and not isIPv4Network(host_ip) then + -- Invalid host submitted + return false + end - if not alert_consts.getAlertType(tonumber(alert_key)) then - -- Invalid alert key submitted - return false - end + if not alert_consts.getAlertType(tonumber(alert_key)) then + -- Invalid alert key submitted + return false + end - return true + if (vlan_id) and (not tonumber(vlan_id)) then + -- Invalid vlan_id + return false + end + + return true end -- ############################################## local function _get_configured_alert_exclusions() - local excl_key = _get_alert_exclusions_prefix_key() - local configured_excl_str = ntop.getPref(excl_key) - local configured_excl = json.decode(configured_excl_str) or {} + local excl_key = _get_alert_exclusions_prefix_key() + local configured_excl_str = ntop.getPref(excl_key) + local configured_excl = json.decode(configured_excl_str) or {} - return configured_excl + return configured_excl end -- ############################################## @@ -95,176 +99,186 @@ end -- ############################################## ---@brief Enables or disables an alert for an `host_ip` -local function _toggle_alert(is_flow_exclusion, host_ip, alert_key, enable_exclusion) - local ret = false - - if not _check_host_ip_alert_key(host_ip, alert_key) then - -- Invalid params submitted - return false - end +--@brief Enables or disables an alert for an `host`, supports VLANs +local function _toggle_alert(is_flow_exclusion, host_ip, vlan_id, alert_key, enable_exclusion) + local ret = false + + if not _check_host_ip_vlan_id_alert_key(host_ip, vlan_id, alert_key) then + -- Invalid params submitted + return false + end + + local host = host_ip - local locked = _lock() + -- Adding vlan_id to the host + if (vlan_id) and (tonumber(vlan_id) ~= 0) then + host = format_ip_vlan(host_ip, vlan_id) + end - if locked then - local id = tonumber(alert_key) - local exclusions = _get_configured_alert_exclusions() + local locked = _lock() - if(not enable_exclusion) then - -- disable alert - if exclusions[host_ip] then - local r = {} + if locked then + local id = tonumber(alert_key) + local exclusions = _get_configured_alert_exclusions() + + if(not enable_exclusion) then + -- disable alert -- + -- ip@vlan + if exclusions[host] then + local r = {} + local t = {} + + if(is_flow_exclusion) then + t = exclusions[host].flow_alerts + else + t = exclusions[host].host_alerts + end + + for i=0,table.len(t) do + if(t[i] ~= id) then + table.insert(r, t[i]) + end + end - if(is_flow_exclusion) then - t = exclusions[host_ip].flow_alerts - else - t = exclusions[host_ip].host_alerts + if(is_flow_exclusion) then + exclusions[host].flow_alerts = r + else + exclusions[host].host_alerts = r + end end - - for i=0,table.len(t) do - if(t[i] ~= id) then - table.insert(r, t[i]) - end - end - - if(is_flow_exclusion) then - exclusions[host_ip].flow_alerts = r - else - exclusions[host_ip].host_alerts = r - end - end - else - -- enable alert - - -- Add an entry for the current alert entity, if currently exising exclusions don't already have it - if(exclusions[host_ip] == nil) then - exclusions[host_ip] = { flow_alerts = {}, host_alerts = {} } - end - - if(is_flow_exclusion) then - table.insert(exclusions[host_ip].flow_alerts, id) - else - table.insert(exclusions[host_ip].host_alerts, id) - end + else + -- enable alert -- + -- Add an entry for the current alert entity, if currently exising exclusions don't already have it + if(exclusions[host] == nil) then + exclusions[host] = { flow_alerts = {}, host_alerts = {} } end + + if(is_flow_exclusion) then + table.insert(exclusions[host].flow_alerts, id) + else + table.insert(exclusions[host].host_alerts, id) + end + end - _set_configured_alert_exclusions(exclusions) + _set_configured_alert_exclusions(exclusions) + + ret = true + _unlock() + end - ret = true - _unlock() - end - - return ret + return ret end -- ############################################## --@brief Removes all exclusions for a given entity -local function _enable_all_alerts(is_flow_exclusion, host_ip) - local ret = false - - local locked = _lock() +local function _enable_all_alerts(host_ip, vlan_id) + local ret = false + + local locked = _lock() - if locked then - local exclusions - - if(host_ip == nil) then - exclusions = {} - else - exclusions = _get_configured_alert_exclusions() - exclusions[host_ip] = nil - end + if locked then + local exclusions + + if(host_ip == nil) then + exclusions = {} + else + local host = format_ip_vlan(host_ip, vlan_id) + exclusions = _get_configured_alert_exclusions() + exclusions[host] = nil + end - _set_configured_alert_exclusions(exclusions) + _set_configured_alert_exclusions(exclusions) - ret = true - _unlock() - end + ret = true + _unlock() + end - return ret + return ret end -- ############################################## -- @brief Returns true if `host_ip` has the alert identified with `alert_key` disabled -function _has_disabled_alert(is_flow_exclusion, host_ip, alert_key) - local exclusions = _get_configured_alert_exclusions() - local id = tonumber(alert_key) +local function _has_disabled_alert(is_flow_exclusion, host_ip, vlan_id, alert_key) + local exclusions = _get_configured_alert_exclusions() + local id = tonumber(alert_key) + local host = format_ip_vlan(host_ip, vlan_id) - if(is_flow_exclusion) then - if((exclusions[host_ip] == nil) or (exclusions[host_ip].flow_alerts[id] == nil)) then - return false - else - return true - end - else - if((exclusions[host_ip] == nil) or (exclusions[host_ip].host_alerts[id] == nil)) then - return false - else - return true - end - end + if(is_flow_exclusion) then + if((exclusions[host] == nil) or (exclusions[host].flow_alerts[id] == nil)) then + return false + else + return true + end + else + if((exclusions[host] == nil) or (exclusions[host].host_alerts[id] == nil)) then + return false + else + return true + end + end end -- ############################################## -- @brief Returns true if `is_flow_exclusion` has one or more disabled alerts function alert_exclusions.has_disabled_alerts() - local exclusions = _get_configured_alert_exclusions() + local exclusions = _get_configured_alert_exclusions() - if(table.len(exclusions) > 0) then - return true - else - return false - end + if(table.len(exclusions) > 0) then + return true + else + return false + end end -- ############################################## -- @brief Returns all excluded hosts for the given `alert_key` or nil if no excluded host exists -function _get_excluded_hosts(is_flow_exclusion, alert_key) - local exclusions = _get_configured_alert_exclusions() - local id = tonumber(alert_key) - local ret = {} +local function _get_excluded_hosts(is_flow_exclusion, alert_key) + local exclusions = _get_configured_alert_exclusions() + local id = tonumber(alert_key) + local ret = {} - for host,v in pairs(exclusions) do - local t + for host,v in pairs(exclusions) do + local t - if(is_flow_exclusion) then - t = v.flow_alerts - else - t = v.host_alerts - end + if(is_flow_exclusion) then + t = v.flow_alerts + else + t = v.host_alerts + end - if not t then - traceError(TRACE_INFO,TRACE_CONSOLE, "Failure checking exclusions for host") - else - for i=0,table.len(t) do - if(t[i] == id) then - ret[host] = true - break - end - end - end - end - - return ret + if not t then + traceError(TRACE_INFO,TRACE_CONSOLE, "Failure checking exclusions for host") + else + for i=0,table.len(t) do + if(t[i] == id) then + ret[host] = true + break + end + end + end + end + + return ret end -- ############################################## --@brief Marks a flow alert as disabled for a given `host_ip`, considered either as client or server --@return True, if alert is disabled with success, false otherwise -function alert_exclusions.disable_flow_alert(host_ip, alert_key) - return _toggle_alert(true --[[ flow --]], host_ip, alert_key, true --[[ disable --]]) +function alert_exclusions.disable_flow_alert(host_ip, vlan_id, alert_key) + return _toggle_alert(true --[[ flow --]], host_ip, vlan_id, alert_key, true --[[ disable --]]) end -- ############################################## --@brief Marks a flow alert as enabled for a given `host_ip`, considered either as client or server --@return True, if alert is enabled with success, false otherwise -function alert_exclusions.enable_flow_alert(host_ip, alert_key) - return _toggle_alert(true --[[ flow --]], host_ip, alert_key, false --[[ enable --]]) +function alert_exclusions.enable_flow_alert(host_ip, vlan_id, alert_key) + return _toggle_alert(true --[[ flow --]], host_ip, vlan_id, alert_key, false --[[ enable --]]) end -- ############################################## @@ -272,31 +286,31 @@ end --@brief Enables all flow alerts possibly disabled --@param host If a valid ip address is specified, then all alerts will be enabled only for `host`, otherwise all alerts will be enabled --@return True, if enabled with success, false otherwise -function alert_exclusions.enable_all_flow_alerts(host) - return _enable_all_alerts(true --[[ flow --]], host) +function alert_exclusions.enable_all_flow_alerts(host_ip, vlan_id) + return _enable_all_alerts(host_ip, vlan_id) end -- ############################################## -- @brief Returns true if `host_ip` has the flow alert identified with `alert_key` disabled function alert_exclusions.has_disabled_flow_alert(host_ip, alert_key) - return _has_disabled_alert(true --[[ flow --]], host_ip, alert_key) + return _has_disabled_alert(true --[[ flow --]], host_ip, 0, alert_key) end - + -- ############################################## --@brief Marks a host alert as disabled for a given `host_ip` --@return True, if alert is disabled with success, false otherwise -function alert_exclusions.disable_host_alert(host_ip, alert_key) - return _toggle_alert(false --[[ host --]], host_ip, alert_key, true --[[ disable --]]) +function alert_exclusions.disable_host_alert(host_ip, vlan_id, alert_key) + return _toggle_alert(false --[[ host --]], host_ip, vlan_id, alert_key, true --[[ disable --]]) end -- ############################################## --@brief Marks a host alert as enabled for a given `host_ip` --@return True, if alert is enabled with success, false otherwise -function alert_exclusions.enable_host_alert(host_ip, alert_key) - return _toggle_alert(false --[[ host --]], host_ip, alert_key, false --[[ enable --]]) +function alert_exclusions.enable_host_alert(host_ip, vlan_id, alert_key) + return _toggle_alert(false --[[ host --]], host_ip, vlan_id, alert_key, false --[[ enable --]]) end -- ############################################## @@ -304,15 +318,8 @@ end --@brief Enables all host alerts possibly disabled --@param host If a valid ip address is specified, then all alerts will be enabled only for `host`, otherwise all alerts will be enabled --@return True, if enabled with success, false otherwise -function alert_exclusions.enable_all_host_alerts(host) - return _enable_all_alerts(false --[[ host --]], host) -end - --- ############################################## - --- @brief Returns true if `host_ip` has the host alert identified with `alert_key` disabled -function alert_exclusions.has_disabled_host_alert(host_ip, alert_key) - return _has_disabled_alert(false --[[ host --]], host_ip, alert_key) +function alert_exclusions.enable_all_host_alerts(host_ip, vlan_id) + return _enable_all_alerts(host_ip, vlan_id) end -- ############################################## @@ -331,16 +338,9 @@ end -- ############################################## --- @brief Returns all the excluded hosts for the flowt alert identified with `alert_key` ---function alert_exclusions.domain_alerts_get_excluded_hosts(alert_key) --- return _get_excluded_hosts(alert_entities.domain, alert_key) or {} ---end - --- ############################################## - -- @brief Returns true if `host_ip` has the host alert identified with `alert_key` disabled function alert_exclusions.has_disabled_host_alert(host_ip, alert_key) - return _has_disabled_alert(false --[[ host --]], host_ip, alert_key) + return _has_disabled_alert(false --[[ host --]], host_ip, 0, alert_key) end -- ############################################## diff --git a/scripts/lua/modules/alert_store/flow_alert_store.lua b/scripts/lua/modules/alert_store/flow_alert_store.lua index 026f2d789f..cd476ef540 100644 --- a/scripts/lua/modules/alert_store/flow_alert_store.lua +++ b/scripts/lua/modules/alert_store/flow_alert_store.lua @@ -344,7 +344,14 @@ end --@brief Add ip filter function flow_alert_store:add_ip_filter(ip) - self:add_filter_condition('ip', 'eq', ip); + self:add_filter_condition('ip', 'eq', ip); +end + +-- ############################################## + +--@brief Add ip filter +function flow_alert_store:add_vlan_filter(vlan_id) + self:add_filter_condition('vlan_id', 'eq', vlan_id); end -- ############################################## diff --git a/scripts/lua/modules/alert_store/host_alert_store.lua b/scripts/lua/modules/alert_store/host_alert_store.lua index d7c611528a..bb3630565b 100644 --- a/scripts/lua/modules/alert_store/host_alert_store.lua +++ b/scripts/lua/modules/alert_store/host_alert_store.lua @@ -135,6 +135,13 @@ end -- ############################################## +--@brief Add vlan filter +function host_alert_store:add_vlan_filter(vlan_id) + self:add_filter_condition('vlan_id', 'eq', vlan_id); +end + +-- ############################################## + --@brief Add filters according to what is specified inside the REST API function host_alert_store:_add_additional_request_filters() local vlan_id = _GET["vlan_id"] diff --git a/scripts/lua/modules/alert_utils.lua b/scripts/lua/modules/alert_utils.lua index 188de26ced..e8bd86ad60 100644 --- a/scripts/lua/modules/alert_utils.lua +++ b/scripts/lua/modules/alert_utils.lua @@ -58,32 +58,42 @@ end --@brief Deletes all stored alerts matching an host and an IP -- @return nil -function alert_utils.deleteFlowAlertsMatching(host_ip, alert_id) - local flow_alert_store = require("flow_alert_store").new() +function alert_utils.deleteFlowAlertsMatching(host_ip, vlan_id, alert_id) + local flow_alert_store = require("flow_alert_store").new() - if not isEmptyString(host_ip) then - flow_alert_store:add_ip_filter(hostkey2hostinfo(host_ip)["host"]) - end - flow_alert_store:add_alert_id_filter(alert_id) + if not isEmptyString(host_ip) then + flow_alert_store:add_ip_filter(hostkey2hostinfo(host_ip)["host"]) + end - -- Perform the actual deletion - flow_alert_store:delete() + if (vlan_id) and (tonumber(vlan_id) ~= 0) then + flow_alert_store:add_vlan_filter(vlan_id) + end + + flow_alert_store:add_alert_id_filter(alert_id) + + -- Perform the actual deletion + flow_alert_store:delete() end -- ################################# --@brief Deletes all stored alerts matching an host and an IP -- @return nil -function alert_utils.deleteHostAlertsMatching(host_ip, alert_id) - local host_alert_store = require("host_alert_store").new() +function alert_utils.deleteHostAlertsMatching(host_ip, vlan_id, alert_id) + local host_alert_store = require("host_alert_store").new() - if not isEmptyString(host_ip) then - host_alert_store:add_ip_filter(hostkey2hostinfo(host_ip)["host"]) - end - host_alert_store:add_alert_id_filter(alert_id) + if not isEmptyString(host_ip) then + host_alert_store:add_ip_filter(hostkey2hostinfo(host_ip)["host"]) + end - -- Perform the actual deletion - host_alert_store:delete() + if (vlan_id) and (tonumber(vlan_id) ~= 0) then + host_alert_store:add_vlan_filter(vlan_id) + end + + host_alert_store:add_alert_id_filter(alert_id) + + -- Perform the actual deletion + host_alert_store:delete() end -- ################################# diff --git a/scripts/lua/modules/checks.lua b/scripts/lua/modules/checks.lua index 8ab184801e..63b1a5ed2b 100644 --- a/scripts/lua/modules/checks.lua +++ b/scripts/lua/modules/checks.lua @@ -1199,7 +1199,7 @@ function checks.updateScriptConfig(script_key, subdir, new_config, additional_fi if not current_filters[new_ip] then -- Not an already-added filter - alert_exclusions.disable_host_alert(new_ip, script.alert_id) + alert_exclusions.disable_host_alert(new_ip, 0, script.alert_id) else -- Filter was already added, nothing to do current_filters[new_ip] = nil @@ -1209,7 +1209,7 @@ function checks.updateScriptConfig(script_key, subdir, new_config, additional_fi -- Here we have leftovers, that is, previously added filters that should -- be removed as they don't appear in the new filters for current_ip, _ in pairs(current_filters or {}) do - alert_exclusions.enable_host_alert(current_ip, script.alert_id) + alert_exclusions.enable_host_alert(current_ip, 0, script.alert_id) end elseif subdir == "flow" then local current_filters = alert_exclusions.flow_alerts_get_excluded_hosts(script.alert_id) @@ -1220,7 +1220,7 @@ function checks.updateScriptConfig(script_key, subdir, new_config, additional_fi if not current_filters[new_ip] then -- Not an already-added filter - alert_exclusions.disable_flow_alert(new_ip, script.alert_id) + alert_exclusions.disable_flow_alert(new_ip, 0, script.alert_id) else -- Filter was already added, nothing to do current_filters[new_ip] = nil @@ -1229,7 +1229,7 @@ function checks.updateScriptConfig(script_key, subdir, new_config, additional_fi -- See above for flows for current_ip, _ in pairs(current_filters or {}) do - alert_exclusions.enable_flow_alert(current_ip, script.alert_id) + alert_exclusions.enable_flow_alert(current_ip, 0, script.alert_id) end end elseif additional_filters then diff --git a/scripts/lua/modules/historical_flow_utils.lua b/scripts/lua/modules/historical_flow_utils.lua index 3420c02472..685d7043c1 100644 --- a/scripts/lua/modules/historical_flow_utils.lua +++ b/scripts/lua/modules/historical_flow_utils.lua @@ -1206,7 +1206,6 @@ function historical_flow_utils.format_record(record, csv_format, formatted_recor ---------------------------------- -- Need to do this in order to remove unnecessary frontend data - if csv_format == true then processed_record = "" diff --git a/scripts/lua/modules/lua_utils.lua b/scripts/lua/modules/lua_utils.lua index 2fc472f3cc..1cb4b66754 100644 --- a/scripts/lua/modules/lua_utils.lua +++ b/scripts/lua/modules/lua_utils.lua @@ -1903,12 +1903,12 @@ function hostinfo2label(host_info, show_vlan, shorten_len) res = getHostAltName(ip) if isEmptyString(res) then - -- Read what is found inside host `name`, e.g., name as found by dissected traffic such as DHCP - res = host_info["name"] + -- Read what is found inside host `name`, e.g., name as found by dissected traffic such as DHCP + res = host_info["name"] - if isEmptyString(res) then - return hostinfo2label_resolved(host_info, show_vlan, shorten_len) - end + if isEmptyString(res) then + return hostinfo2label_resolved(host_info, show_vlan, shorten_len) + end end end diff --git a/src/Utils.cpp b/src/Utils.cpp index 0e9745baae..808352cba8 100755 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -5149,3 +5149,17 @@ const char* Utils::get_state_label(ThreadedActivityState ta_state) { break; } } + +/* ******************************************* */ + +void Utils::splitAddressAndVlan(char *addr, VLANid *vlan_id) { + char *at = NULL; + + if((at = strchr(addr, '@'))) { + *vlan_id = atoi(at + 1); + *at = '\0'; + } else + vlan_id = 0; +} + +/* ******************************************* */ diff --git a/src/VLANAddressTree.cpp b/src/VLANAddressTree.cpp index 27c24df40c..f7b141a681 100644 --- a/src/VLANAddressTree.cpp +++ b/src/VLANAddressTree.cpp @@ -49,6 +49,15 @@ bool VLANAddressTree::addAddress(VLANid vlan_id, char *_net, const int16_t user_ /* **************************************** */ +bool VLANAddressTree::addVLANAddressAndData(VLANid vlan_id, const char *_what, void *user_data) { + if(tree[vlan_id] || (tree[vlan_id] = new (std::nothrow) AddressTree())) + return tree[vlan_id]->addAddressAndData(_what, user_data); + + return false; +} + +/* **************************************** */ + bool VLANAddressTree::addAddresses(VLANid vlan_id, char *net, const int16_t user_data) { if(tree[vlan_id] || (tree[vlan_id] = new (std::nothrow) AddressTree())) return tree[vlan_id]->addAddresses(net, user_data); @@ -69,3 +78,12 @@ int16_t VLANAddressTree::findMac(VLANid vlan_id, const u_int8_t addr[]) { if(! tree[vlan_id]) return -1; return tree[vlan_id]->findMac(addr); } + +/* **************************************** */ + +void *VLANAddressTree::findAndGetData(VLANid vlan_id, const IpAddress * const ipa) const { + if(! tree[vlan_id]) return NULL; + return tree[vlan_id]->matchAndGetData(ipa); +} + +/* **************************************** */