From ce590b6b4157661096c910883e11d40cb202398f Mon Sep 17 00:00:00 2001 From: Patrick Grimm Date: Sun, 2 Feb 2025 16:24:16 +0100 Subject: [PATCH 1/5] add option for exclude reporting wifi client mac --ignore-wifi : Interfaces that ignored for wifi clients." --ignore-wifi-mac : Space seperated list off Client MAC addresses that will be ignored. --- .../files/lib/openwisp-monitoring/wifi.lua | 64 ++++++++++--------- openwisp-monitoring/files/monitoring.agent | 13 +++- openwisp-monitoring/files/monitoring.config | 4 ++ openwisp-monitoring/files/monitoring.init | 4 +- .../files/sbin/netjson-monitoring.lua | 40 ++++++++---- 5 files changed, 80 insertions(+), 45 deletions(-) diff --git a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua index a3dbfc7..53e8e18 100644 --- a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua +++ b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua @@ -26,49 +26,53 @@ 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 = {} for mac, properties in pairs(clients) do - properties.mac = mac - table.insert(data, properties) + if not exclude_mac[mac] then + properties.mac = mac + table.insert(data, properties) + end end return data end -function wifi.parse_iwinfo_clients(clients) +function wifi.parse_iwinfo_clients(clients,exclude_mac) local data = {} 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 + if not exclude_mac[p.mac] 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 return data 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 8731d34..7335499 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 @@ -103,6 +105,7 @@ save_data() { filename="$(date -u +'%d-%m-%Y_%H:%M:%S')" # save data with file_name echo "$data" >"$TMP_DIR/$filename" + cp "$TMP_DIR/$filename" "/tmp/$filename.json" # compress data gzip "$TMP_DIR/$filename" [ "$VERBOSE_MODE" -eq "1" ] && logger -s "Data saved temporarily." \ @@ -321,6 +324,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..6a75c64 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:1b:79:01' + #list ignore_wifi_mac '00:30:04:1a:bc:02' + #list ignore_wifi_mac '00:30:04: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 From 0fe5decbb1cb850e5401cba2c27f37142cfbd4b6 Mon Sep 17 00:00:00 2001 From: Patrick Grimm Date: Sun, 2 Feb 2025 17:03:29 +0100 Subject: [PATCH 2/5] remove debug output --- openwisp-monitoring/files/monitoring.agent | 1 - 1 file changed, 1 deletion(-) diff --git a/openwisp-monitoring/files/monitoring.agent b/openwisp-monitoring/files/monitoring.agent index 7335499..c711b4d 100755 --- a/openwisp-monitoring/files/monitoring.agent +++ b/openwisp-monitoring/files/monitoring.agent @@ -105,7 +105,6 @@ save_data() { filename="$(date -u +'%d-%m-%Y_%H:%M:%S')" # save data with file_name echo "$data" >"$TMP_DIR/$filename" - cp "$TMP_DIR/$filename" "/tmp/$filename.json" # compress data gzip "$TMP_DIR/$filename" [ "$VERBOSE_MODE" -eq "1" ] && logger -s "Data saved temporarily." \ From acc4a6abeb425b9a564b881ab410f1b0dcfb38f1 Mon Sep 17 00:00:00 2001 From: Patrick Grimm Date: Sat, 8 Feb 2025 23:16:28 +0100 Subject: [PATCH 3/5] add new test cases for clients exclude --- .../files/lib/openwisp-monitoring/wifi.lua | 6 ++ .../tests/test_files/wireless_data.lua | 96 +++++++++++++++++++ openwisp-monitoring/tests/test_wifi.lua | 2 + 3 files changed, 104 insertions(+) diff --git a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua index 53e8e18..787ac83 100644 --- a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua +++ b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua @@ -28,6 +28,9 @@ end 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 if not exclude_mac[mac] then properties.mac = mac @@ -39,6 +42,9 @@ end function wifi.parse_iwinfo_clients(clients,exclude_mac) local data = {} + if not exclude_mac then + exclude_mac = {} + end for _, p in pairs(clients) do if not exclude_mac[p.mac] then local client = {} diff --git a/openwisp-monitoring/tests/test_files/wireless_data.lua b/openwisp-monitoring/tests/test_files/wireless_data.lua index 57d8c8c..a017ac4 100644 --- a/openwisp-monitoring/tests/test_files/wireless_data.lua +++ b/openwisp-monitoring/tests/test_files/wireless_data.lua @@ -192,6 +192,70 @@ 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 + }, +} + +test_data.exclude_wifi_mac = { + ["98:3b:8f:98:b1:fc"] = true , + ["20:a6:0c:b2:da:11"] = true +} + test_data.wlan2_clients = {} test_data.wlan0_iwinfo = { @@ -425,6 +489,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 9489ec4..607ffb5 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() From 2dc5e245fd7774e06aaca5e57ef5536c895fa9fb Mon Sep 17 00:00:00 2001 From: Patrick Grimm Date: Thu, 24 Jul 2025 18:23:51 +0200 Subject: [PATCH 4/5] modify the option for exclude reporting wifi client mac --ignore-wifi : Interfaces that ignored for wifi clients." --ignore-wifi-mac : Space seperated list off Client MAC addresses that will be ignored. An incomplete address is compared from left to right. --- .../files/lib/openwisp-monitoring/wifi.lua | 16 ++++++++++++++-- openwisp-monitoring/files/monitoring.config | 6 +++--- .../tests/test_files/wireless_data.lua | 17 ++++++++++++++++- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua index 787ac83..8f0f1b7 100644 --- a/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua +++ b/openwisp-monitoring/files/lib/openwisp-monitoring/wifi.lua @@ -32,7 +32,13 @@ function wifi.parse_hostapd_clients(clients,exclude_mac) exclude_mac = {} end for mac, properties in pairs(clients) do - if not exclude_mac[mac] then + 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 @@ -46,7 +52,13 @@ function wifi.parse_iwinfo_clients(clients,exclude_mac) exclude_mac = {} end for _, p in pairs(clients) do - if not exclude_mac[p.mac] then + 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 diff --git a/openwisp-monitoring/files/monitoring.config b/openwisp-monitoring/files/monitoring.config index 6a75c64..7eb1c00 100644 --- a/openwisp-monitoring/files/monitoring.config +++ b/openwisp-monitoring/files/monitoring.config @@ -6,6 +6,6 @@ config monitoring 'monitoring' option max_retries '5' #option bootup_delay '10' #option ignore_wifi 'phy0-mesh0' - #list ignore_wifi_mac '00:30:04:1b:79:01' - #list ignore_wifi_mac '00:30:04:1a:bc:02' - #list ignore_wifi_mac '00:30:04:1B:7B:03' \ No newline at end of file + #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/tests/test_files/wireless_data.lua b/openwisp-monitoring/tests/test_files/wireless_data.lua index a017ac4..b990b09 100644 --- a/openwisp-monitoring/tests/test_files/wireless_data.lua +++ b/openwisp-monitoring/tests/test_files/wireless_data.lua @@ -249,11 +249,26 @@ test_data.exlude_wlan1_clients = { 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 + ["20:a6:0c:b2:da:11"] = true , + ["00:30:04"] = true } test_data.wlan2_clients = {} From 8df699f90a59aa215cae540a4d32315ed38b2948 Mon Sep 17 00:00:00 2001 From: Patrick Grimm Date: Sat, 1 Nov 2025 11:14:29 +0100 Subject: [PATCH 5/5] [chores] Fixed monitoring.agent help --- openwisp-monitoring/files/monitoring.agent | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openwisp-monitoring/files/monitoring.agent b/openwisp-monitoring/files/monitoring.agent index d9602f7..1c66d59 100755 --- a/openwisp-monitoring/files/monitoring.agent +++ b/openwisp-monitoring/files/monitoring.agent @@ -25,8 +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" + 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 }