diff --git a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua index b38d548..2cbd7db 100644 --- a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua +++ b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua @@ -26,49 +26,71 @@ function wifi.invert_rx_tx(interface) return interface end -function wifi.parse_hostapd_clients(clients) +function wifi.parse_hostapd_clients(clients,exclude_mac) local data = {} + if not exclude_mac then + exclude_mac = {} + end for mac, properties in pairs(clients) do - properties.mac = mac - table.insert(data, properties) + exclude_mac_b = false + for emac in pairs(exclude_mac) do + if string.find(mac,emac) == 1 then + exclude_mac_b = true + end + end + if not exclude_mac_b then + properties.mac = mac + table.insert(data, properties) + end end if #data > 0 then return data end end -function wifi.parse_iwinfo_clients(clients) +function wifi.parse_iwinfo_clients(clients,exclude_mac) local data = {} + if not exclude_mac then + exclude_mac = {} + end for _, p in pairs(clients) do - local client = {} - client.mac = p.mac - client.ht = p.rx.ht - client.vht = p.rx.vht - client.he = p.rx.he - client.auth = p.authenticated - client.authorized = p.authorized - client.wmm = p.wme - client.mfp = p.mfp - client.signal = p.signal - client.noise = p.noise - client.signal_avg = p.signal_avg - client.mesh_llid = p['mesh llid'] - client.mesh_plid = p['mesh plid'] - client.mesh_plink = p['mesh plink'] - client.mesh_local_ps = p['mesh local PS'] - client.mesh_peer_ps = p['mesh peer PS'] - client.mesh_non_peer_ps = p['mesh non-peer PS'] - if p.thr then - -- collect expected throughput in bytes - client.throughput = p.thr * 1000 + exclude_mac_b = false + for emac in pairs(exclude_mac) do + if string.find(p.mac,emac) == 1 then + exclude_mac_b = true + end + end + if not exclude_mac_b then + local client = {} + client.mac = p.mac + client.ht = p.rx.ht + client.vht = p.rx.vht + client.he = p.rx.he + client.auth = p.authenticated + client.authorized = p.authorized + client.wmm = p.wme + client.mfp = p.mfp + client.signal = p.signal + client.noise = p.noise + client.signal_avg = p.signal_avg + client.mesh_llid = p['mesh llid'] + client.mesh_plid = p['mesh plid'] + client.mesh_plink = p['mesh plink'] + client.mesh_local_ps = p['mesh local PS'] + client.mesh_peer_ps = p['mesh peer PS'] + client.mesh_non_peer_ps = p['mesh non-peer PS'] + if p.thr then + -- collect expected throughput in bytes + client.throughput = p.thr * 1000 + end + table.insert(data, client) end - table.insert(data, client) end if #data > 0 then return data end end -- takes ubus wireless.status clients output and converts it to NetJSON -function wifi.netjson_clients(clients, is_mesh) - return (is_mesh and wifi.parse_iwinfo_clients(clients) or - wifi.parse_hostapd_clients(clients)) -end +function wifi.netjson_clients(clients, is_mesh, exclude_mac) + return (is_mesh and wifi.parse_iwinfo_clients(clients, exclude_mac) or + wifi.parse_hostapd_clients(clients, exclude_mac)) +end return wifi diff --git a/openwisp-monitoring/files/monitoring.agent b/openwisp-monitoring/files/monitoring.agent index 78457a8..1c66d59 100755 --- a/openwisp-monitoring/files/monitoring.agent +++ b/openwisp-monitoring/files/monitoring.agent @@ -25,6 +25,8 @@ show_help() { printf " --verbose_mode <0, 1>\t\t\t: Run agent in verbose mode.\n" printf " --required_memory <0-1>\t\t: Fraction of total memory that should be available to collect data.\n" printf " --max_retries \t: No. of time agent should retry to send data.\n" + printf " --ignore_wifi \t: Interfaces that ignored for wifi clients.\n" + printf " --ignore_wifi_mac \t: Space seperated list off Client MAC addresses that will be ignored.\n" exit 0 } @@ -66,7 +68,7 @@ collect_data() { [ "$VERBOSE_MODE" -eq "1" ] && logger -s "Collecting NetJSON Monitoring data." \ -p daemon.info until [ "$n" -ge 5 ]; do - /usr/sbin/netjson-monitoring --dump "$MONITORED_INTERFACES" && break + /usr/sbin/netjson-monitoring --dump "$MONITORED_INTERFACES" "$IGNORE_WIFI" "$IGNORE_WIFI_MAC" && break if [ "$n" -eq 5 ]; then [ "$VERBOSE_MODE" -eq "1" ] && logger -s "Collecting data failed!" -p daemon.err @@ -328,6 +330,14 @@ main() { export BOOTUP_DELAY="$2" shift ;; + --ignore_wifi) + export IGNORE_WIFI="$2" + shift + ;; + --ignore_wifi_mac) + export IGNORE_WIFI_MAC="$2" + shift + ;; -*) echo "Invalid option: $1" exit 1 diff --git a/openwisp-monitoring/files/monitoring.config b/openwisp-monitoring/files/monitoring.config index 16501cd..7eb1c00 100644 --- a/openwisp-monitoring/files/monitoring.config +++ b/openwisp-monitoring/files/monitoring.config @@ -5,3 +5,7 @@ config monitoring 'monitoring' option required_memory '0.05' option max_retries '5' #option bootup_delay '10' + #option ignore_wifi 'phy0-mesh0' + #list ignore_wifi_mac '00:30:04' + #list ignore_wifi_mac 'aa:12:a4:1a:bc:02' + #list ignore_wifi_mac 'bb:34:c4:1B:7B:03' \ No newline at end of file diff --git a/openwisp-monitoring/files/monitoring.init b/openwisp-monitoring/files/monitoring.init index 2f4807b..8631a81 100755 --- a/openwisp-monitoring/files/monitoring.init +++ b/openwisp-monitoring/files/monitoring.init @@ -58,6 +58,8 @@ start_service() { config_get required_memory monitoring required_memory "0.05" config_get max_retries monitoring max_retries "5" config_get bootup_delay monitoring bootup_delay "10" + config_get ignore_wifi monitoring ignore_wifi + config_get ignore_wifi_mac monitoring ignore_wifi_mac interval="$(time_to_seconds "$interval")" if [ "$interval" -lt 1 ]; then @@ -74,7 +76,7 @@ start_service() { procd_open_instance "openwisp-monitoring_collect_data" # shellcheck disable=SC2086,SC2154 - procd_set_param command $PROG $interval $verbose $required_memory --mode collect --monitored_interfaces "$monitored_interfaces" + procd_set_param command $PROG $interval $verbose $required_memory --mode collect --monitored_interfaces "$monitored_interfaces" --ignore_wifi "$ignore_wifi" --ignore_wifi_mac "$ignore_wifi_mac" procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}" [ "$verbose_mode" -eq "1" ] && procd_set_param stdout 1 && procd_set_param stderr 1 procd_close_instance diff --git a/openwisp-monitoring/files/sbin/netjson-monitoring.lua b/openwisp-monitoring/files/sbin/netjson-monitoring.lua index 8f4200f..fa377ec 100755 --- a/openwisp-monitoring/files/sbin/netjson-monitoring.lua +++ b/openwisp-monitoring/files/sbin/netjson-monitoring.lua @@ -60,6 +60,18 @@ if traffic_monitored and traffic_monitored ~= '*' then traffic_monitored = monitoring.utils.split(traffic_monitored, ' ') for _, name in pairs(traffic_monitored) do include_stats[name] = true end end +local ignore_wifi = arg[2] +local exclude_wifi = {} +if ignore_wifi then + ignore_wifi = monitoring.utils.split(ignore_wifi, ' ') + for _, wifi_name in pairs(ignore_wifi) do exclude_wifi[wifi_name] = true end +end +local ignore_wifi_mac = arg[3] +local exclude_wifi_mac = {} +if ignore_wifi_mac then + ignore_wifi_mac = monitoring.utils.split(ignore_wifi_mac, ' ') + for _, wifi_mac in pairs(ignore_wifi_mac) do exclude_wifi_mac[wifi_mac] = true end +end -- collect device data local network_status = ubus:call('network.device', 'status', {}) @@ -70,7 +82,7 @@ local host_interfaces = {} local dns_servers = {} local dns_search = {} -local function get_wireless_netjson_interface(radio, name, iwinfo) +local function get_wireless_netjson_interface(radio, name, iwinfo, no_clients, exclude_mac) local clients = nil local is_mesh = false local htmode = radio.config.htmode @@ -99,17 +111,19 @@ local function get_wireless_netjson_interface(radio, name, iwinfo) bitrate = iwinfo.bitrate, htmode = htmode } - if iwinfo.mode == 'Ad-Hoc' or iwinfo.mode == 'Mesh Point' or iwinfo.mode == - 'Client' then - clients = ubus:call('iwinfo', 'assoclist', {device = name}).results - is_mesh = true - else - local hostapd_output = ubus:call('hostapd.' .. name, 'get_clients', {}) - if hostapd_output then clients = hostapd_output.clients end - end - if not monitoring.utils.is_table_empty(clients) then - netjson_interface.wireless.clients = monitoring.wifi.netjson_clients(clients, - is_mesh) + if no_clients == false then + if iwinfo.mode == 'Ad-Hoc' or iwinfo.mode == 'Mesh Point' or iwinfo.mode == + 'Client' then + clients = ubus:call('iwinfo', 'assoclist', {device = name}).results + is_mesh = true + else + local hostapd_output = ubus:call('hostapd.' .. name, 'get_clients', {}) + if hostapd_output then clients = hostapd_output.clients end + end + if not monitoring.utils.is_table_empty(clients) then + netjson_interface.wireless.clients = monitoring.wifi.netjson_clients(clients, + is_mesh, exclude_mac) + end end end return netjson_interface @@ -125,7 +139,7 @@ for _, radio in pairs(wireless_status) do if monitoring.iwinfo.enabled then iwinfo = ubus:call('iwinfo', 'info', {device = name}) end - wireless_interfaces[name] = get_wireless_netjson_interface(radio, name, iwinfo) + wireless_interfaces[name] = get_wireless_netjson_interface(radio, name, iwinfo, exclude_wifi[name] or false, exclude_wifi_mac) end end end diff --git a/openwisp-monitoring/tests/test_files/wireless_data.lua b/openwisp-monitoring/tests/test_files/wireless_data.lua index 57d8c8c..b990b09 100644 --- a/openwisp-monitoring/tests/test_files/wireless_data.lua +++ b/openwisp-monitoring/tests/test_files/wireless_data.lua @@ -192,6 +192,85 @@ test_data.wlan1_clients = { } } +test_data.exlude_wlan1_clients = { + ["98:3b:8f:98:b1:fb"] = { + aid = 1, + assoc = true, + auth = true, + authorized = true, + ht = true, + mfp = false, + preauth = false, + rrm = {0, 0, 0, 0, 0}, + vht = true, + wds = false, + wmm = true, + wps = false + }, + ["20:a6:0c:b2:da:10"] = { + aid = 2, + assoc = true, + auth = true, + authorized = true, + ht = true, + mfp = false, + preauth = false, + rrm = {0, 0, 0, 0, 0}, + vht = true, + wds = false, + wmm = true, + wps = false + }, + ["20:a6:0c:b2:da:11"] = { + aid = 3, + assoc = true, + auth = true, + authorized = true, + ht = true, + mfp = false, + preauth = false, + rrm = {0, 0, 0, 0, 0}, + vht = true, + wds = false, + wmm = true, + wps = false + }, + ["98:3b:8f:98:b1:fc"] = { + aid = 4, + assoc = true, + auth = true, + authorized = true, + ht = true, + mfp = false, + preauth = false, + rrm = {0, 0, 0, 0, 0}, + vht = true, + wds = false, + wmm = true, + wps = false + }, + ["00:30:04:1a:bf:44"] = { + aid = 5, + assoc = true, + auth = true, + authorized = true, + ht = true, + mfp = false, + preauth = false, + rrm = {0, 0, 0, 0, 0}, + vht = true, + wds = false, + wmm = true, + wps = false + } +} + +test_data.exclude_wifi_mac = { + ["98:3b:8f:98:b1:fc"] = true , + ["20:a6:0c:b2:da:11"] = true , + ["00:30:04"] = true +} + test_data.wlan2_clients = {} test_data.wlan0_iwinfo = { @@ -425,6 +504,38 @@ test_data.parsed_clients = { } } +test_data.exclude_parsed_clients = { + { + aid = 2, + assoc = true, + auth = true, + authorized = true, + ht = true, + mac = "20:a6:0c:b2:da:10", + mfp = false, + preauth = false, + rrm = {0, 0, 0, 0, 0}, + vht = true, + wds = false, + wmm = true, + wps = false + }, { + aid = 1, + assoc = true, + auth = true, + authorized = true, + ht = true, + mac = "98:3b:8f:98:b1:fb", + mfp = false, + preauth = false, + rrm = {0, 0, 0, 0, 0}, + vht = true, + wds = false, + wmm = true, + wps = false + } +} + test_data.mesh0_parsed_clients = { { auth = true, diff --git a/openwisp-monitoring/tests/test_wifi.lua b/openwisp-monitoring/tests/test_wifi.lua index 64311f3..b873190 100644 --- a/openwisp-monitoring/tests/test_wifi.lua +++ b/openwisp-monitoring/tests/test_wifi.lua @@ -87,6 +87,8 @@ function TestWifi.test_netjson_clients() luaunit.assertEquals( wifi_functions.netjson_clients(wifi_data.mesh1_clients.results, true), wifi_data.mesh1_parsed_clients) + luaunit.assertEquals(wifi_functions.netjson_clients(wifi_data.exlude_wlan1_clients, false, wifi_data.exclude_wifi_mac), + wifi_data.exclude_parsed_clients) end function TestWifi.test_needs_inversion()