jscanner

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit cedba0f485d95cca854ab1b3b83d020a4aa10181
parent a17a156f18e86a79572fee147f2237f6ef8202b2
Author: Matthias Jaros <jaros@mailbox.org>
Date:   Thu,  2 Jul 2026 11:49:42 +0200

Added banner recognition parameter to enable it depending on use case

Diffstat:
Msrc/main/java/com/it_jaros/jscanner/CliDefaults.java | 1+
Msrc/main/java/com/it_jaros/jscanner/CliParser.java | 61+++++++++++++++++++++++++++++++------------------------------
Msrc/main/java/com/it_jaros/jscanner/ScanOptions.java | 2+-
Msrc/main/java/com/it_jaros/jscanner/Scanner.java | 12+++++++++---
4 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/src/main/java/com/it_jaros/jscanner/CliDefaults.java b/src/main/java/com/it_jaros/jscanner/CliDefaults.java @@ -2,6 +2,7 @@ package com.it_jaros.jscanner; public class CliDefaults { public static final String PORTS = "1-1024"; + public static final boolean BANNER_RECOGNITION = false; public static final boolean DISABLE_HOST_CHECK = false; public static final boolean QUIET = false; public static final boolean SHOW_FILTERED_PORTS = false; diff --git a/src/main/java/com/it_jaros/jscanner/CliParser.java b/src/main/java/com/it_jaros/jscanner/CliParser.java @@ -6,21 +6,22 @@ import java.util.Set; public class CliParser { public ScanOptions parseArgs(String[] args) { - if (args.length < 1 || args[0].trim().equals("")) { + if (args.length < 1 || args[0].trim().isEmpty()) { throw new IllegalArgumentException("No argument given"); } Set<String> hostsArgv = new HashSet<>(); - int socketLimit = CliDefaults.SOCKET_LIMIT; - int delayInMillis = CliDefaults.DELAY_IN_MILLIS; - int timeoutInMillis = CliDefaults.TIMEOUT_IN_MILLIS; - int maxWorkersPerHost = CliDefaults.MAX_WORKERS_PER_HOST; - int maxHostsLimit = CliDefaults.MAX_HOSTS_LIMIT; + String hostsFile = null; String ports = CliDefaults.PORTS; - boolean showFilteredPorts = CliDefaults.SHOW_FILTERED_PORTS; + boolean bannerRecognition = CliDefaults.BANNER_RECOGNITION; boolean disableOnlineCheck = CliDefaults.DISABLE_HOST_CHECK; boolean quiet = CliDefaults.QUIET; - String hostsFile = null; + boolean showFilteredPorts = CliDefaults.SHOW_FILTERED_PORTS; + int delayInMillis = CliDefaults.DELAY_IN_MILLIS; + int maxHostsLimit = CliDefaults.MAX_HOSTS_LIMIT; + int maxWorkersPerHost = CliDefaults.MAX_WORKERS_PER_HOST; + int socketLimit = CliDefaults.SOCKET_LIMIT; + int timeoutInMillis = CliDefaults.TIMEOUT_IN_MILLIS; for (int i = 0; i < args.length; i++) { final String currentArg = args[i]; @@ -30,49 +31,48 @@ public class CliParser { } switch (currentArg) { - case "--help", "-h": - usageAndExit(); - break; - case "--socketLimit", "-sl": - socketLimit = parseIntOption(args, ++i, currentArg); + case "--bannerRecognition", "-b": + bannerRecognition = true; break; case "--delay", "-d": delayInMillis = parseIntOption(args, ++i, currentArg); break; - case "--timeout", "-t": - timeoutInMillis = parseIntOption(args, ++i, currentArg); + case "--disableOnlineCheck", "-do": + disableOnlineCheck = true; break; - case "--maxWorkersPerHost", "-mh": - maxWorkersPerHost = parseIntOption(args, ++i, currentArg); + case "--help", "-h": + usageAndExit(); + break; + case "--input", "-i": + hostsFile = requireValue(args, ++i, currentArg); break; case "--maxHostsLimit", "-m": maxHostsLimit = parseIntOption(args, ++i, currentArg); break; + case "--maxWorkersPerHost", "-mh": + maxWorkersPerHost = parseIntOption(args, ++i, currentArg); + break; case "--ports", "-p": ports = requireValue(args, ++i, currentArg); break; + case "--quiet", "-q": + quiet = true; + break; case "--showFilteredPorts", "-sf": showFilteredPorts = true; break; - case "--disableOnlineCheck", "-do": - disableOnlineCheck = true; - break; - case "--input", "-i": - hostsFile = requireValue(args, ++i, currentArg); + case "--socketLimit", "-sl": + socketLimit = parseIntOption(args, ++i, currentArg); break; - case "--quiet", "-q": - quiet = true; + case "--timeout", "-t": + timeoutInMillis = parseIntOption(args, ++i, currentArg); break; default: throw new IllegalArgumentException("No such param " + currentArg); } } - System.out.printf( - "Parsed arguments: hostsArgv('%s'), ports(%s), socketLimit(%s), delayInMillis(%s), timeoutInMillis(%s), maxWorkersPerHost(%s), maxHostsLimit(%s), showFilteredPorts(%s), disableOnlineCheck(%s), file(%s), quiet(%b) %n", - hostsArgv, ports, socketLimit, delayInMillis, timeoutInMillis, maxWorkersPerHost, maxHostsLimit, showFilteredPorts, disableOnlineCheck, hostsFile, quiet); - - return new ScanOptions(hostsArgv.stream().toList(), socketLimit, delayInMillis, timeoutInMillis, maxWorkersPerHost, maxHostsLimit, ports, showFilteredPorts, disableOnlineCheck, hostsFile, quiet); + return new ScanOptions(hostsArgv.stream().toList(), socketLimit, delayInMillis, timeoutInMillis, maxWorkersPerHost, maxHostsLimit, ports, showFilteredPorts, disableOnlineCheck, hostsFile, quiet, bannerRecognition); } private String requireValue(String[] args, int index, String option) { @@ -100,6 +100,7 @@ public class CliParser { Options: """); usage.append(""" + --bannerRecognition, -b:\tEnable banner recognition to find out which service is running behind port (Default :%b) --delay, -d:\t\tWaiting period in millis for connection attempts for a host (Default: %d) --disableOnlineCheck, -do:\tDon't check if Host is reachable (Default: %b) --input, -i:\t\tRead file to get host targets to scan (Default: null) @@ -110,7 +111,7 @@ public class CliParser { --showFilteredPorts, -sf:\tShow also filtered ports (Default: %b) --socketLimit, -sl:\t\tSocket limit in total. You can not scan more ports than allowed here (Default: %d) --timeout, -t:\t\tTimeout in millis per connection attempt, 0 means infinite (Default: %d) - """.formatted(CliDefaults.DELAY_IN_MILLIS, CliDefaults.DISABLE_HOST_CHECK, CliDefaults.MAX_HOSTS_LIMIT, CliDefaults.MAX_WORKERS_PER_HOST, CliDefaults.PORTS, CliDefaults.QUIET, CliDefaults.SHOW_FILTERED_PORTS, CliDefaults.SOCKET_LIMIT, CliDefaults.TIMEOUT_IN_MILLIS) + """.formatted(CliDefaults.BANNER_RECOGNITION, CliDefaults.DELAY_IN_MILLIS, CliDefaults.DISABLE_HOST_CHECK, CliDefaults.MAX_HOSTS_LIMIT, CliDefaults.MAX_WORKERS_PER_HOST, CliDefaults.PORTS, CliDefaults.QUIET, CliDefaults.SHOW_FILTERED_PORTS, CliDefaults.SOCKET_LIMIT, CliDefaults.TIMEOUT_IN_MILLIS) ); usage.append(""" diff --git a/src/main/java/com/it_jaros/jscanner/ScanOptions.java b/src/main/java/com/it_jaros/jscanner/ScanOptions.java @@ -2,4 +2,4 @@ package com.it_jaros.jscanner; import java.util.List; -public record ScanOptions(List<String> hostsArgv, int openSocketLimit, int delayInMillis, int timeoutInMillis, int maxWorkersPerHost, int maxHostsLimit, String ports, boolean showFilteredPorts, boolean disableHostCheck, String hostsFile, boolean quiet) {} +public record ScanOptions(List<String> hostsArgv, int openSocketLimit, int delayInMillis, int timeoutInMillis, int maxWorkersPerHost, int maxHostsLimit, String ports, boolean showFilteredPorts, boolean disableHostCheck, String hostsFile, boolean quiet, boolean bannerRecognition) {} diff --git a/src/main/java/com/it_jaros/jscanner/Scanner.java b/src/main/java/com/it_jaros/jscanner/Scanner.java @@ -24,6 +24,7 @@ public class Scanner implements AutoCloseable { private volatile boolean cancelled = false; private final Semaphore socketLimit; + private final boolean bannerRecognition; private final boolean disableOnlineCheck; private final boolean quiet; private final int maxHostsLimit; @@ -38,9 +39,11 @@ public class Scanner implements AutoCloseable { int maxWorkersPerHost, int maxHostsLimit, boolean disableOnlineCheck, - boolean quiet + boolean quiet, + boolean bannerRecognition ) { this.delayInNanos = TimeUnit.MILLISECONDS.toNanos(Math.max(0, delayInMillis)); + this.bannerRecognition = bannerRecognition; this.disableOnlineCheck = disableOnlineCheck; this.maxHostsLimit = maxHostsLimit; this.maxWorkersPerHost = maxWorkersPerHost; @@ -50,7 +53,7 @@ public class Scanner implements AutoCloseable { } public Scanner(ScanOptions options) { - this(options.openSocketLimit(), options.timeoutInMillis(), options.delayInMillis(), options.maxWorkersPerHost(), options.maxHostsLimit(), options.disableHostCheck(), options.quiet()); + this(options.openSocketLimit(), options.timeoutInMillis(), options.delayInMillis(), options.maxWorkersPerHost(), options.maxHostsLimit(), options.disableHostCheck(), options.quiet(), options.bannerRecognition()); } public List<ScanResult> scan(ScanOptions options) { @@ -228,7 +231,10 @@ public class Scanner implements AutoCloseable { scanState.counter().inc(); try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), timeoutInMillis); - result.setBanner(getBanner(socket)); + + if (bannerRecognition) { + result.setBanner(getBanner(socket)); + } result.setState(PortState.OPEN); } catch (SocketTimeoutException ignored) { result.setState(PortState.FILTERED);