From e242de0ddf63d875e871c6d2347e74ff572be853 Mon Sep 17 00:00:00 2001 From: jokob-sk Date: Sun, 5 Oct 2025 15:37:17 +1100 Subject: [PATCH] ARPSCAN DURATION #1172 Signed-off-by: jokob-sk --- front/plugins/arp_scan/config.json | 31 +++++++++++++++++++++++++++++- front/plugins/arp_scan/script.py | 29 ++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/front/plugins/arp_scan/config.json b/front/plugins/arp_scan/config.json index 11542ee9..8e13029c 100755 --- a/front/plugins/arp_scan/config.json +++ b/front/plugins/arp_scan/config.json @@ -64,7 +64,8 @@ "name": "subnets", "type": "setting", "value": "SCAN_SUBNETS", - "base64": true + "base64": true, + "timeoutMultiplier": true } ], "settings": [ @@ -387,6 +388,34 @@ "string": "Arguments to run arps-scan with. Recommended and tested only with the setting:
sudo arp-scan --ignoredups --retry=6." } ] + }, + { + "function": "DURATION", + "type": { + "dataType": "integer", + "elements": [ + { + "elementType": "input", + "elementOptions": [{ "type": "number" }], + "transformers": [] + } + ] + }, + "default_value": 0, + "options": [], + "localized": ["name", "description"], + "name": [ + { + "language_code": "en_us", + "string": "Discovery duration" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "If DURATION is not 0, the scan runs repeatedly per interface for that many seconds. Important: RUN_TIMEOUT must be greater than DURATION, otherwise the scan will fail." + } + ] } ], "database_column_definitions": [ diff --git a/front/plugins/arp_scan/script.py b/front/plugins/arp_scan/script.py index 7d83b8b1..eff7c87d 100755 --- a/front/plugins/arp_scan/script.py +++ b/front/plugins/arp_scan/script.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import os +import time import pathlib import argparse import sys @@ -150,16 +151,28 @@ def execute_arpscan_on_interface(interface): # Prepare command arguments arpscan_args = get_setting_value('ARPSCAN_ARGS').split() + interface.split() - # Execute command + # Optional duration in seconds (0 = run once) try: - # try running a subprocess safely - result = subprocess.check_output(arpscan_args, universal_newlines=True) - except subprocess.CalledProcessError as e: - # An error occurred, handle it - error_type = type(e).__name__ # Capture the error type - result = "" + scan_duration = int(get_setting_value('ARPSCAN_DURATION')) + except Exception: + scan_duration = 0 # default: single run - return result + results = [] + start_time = time.time() + + while True: + try: + result = subprocess.check_output(arpscan_args, universal_newlines=True) + results.append(result) + except subprocess.CalledProcessError as e: + result = "" + # stop looping if duration not set or expired + if scan_duration == 0 or (time.time() - start_time) > scan_duration: + break + time.sleep(2) # short delay between scans + + # concatenate all outputs (for regex parsing) + return "\n".join(results)