summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/jscanner/Scanner.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/it_jaros/jscanner/Scanner.java')
-rw-r--r--src/main/java/com/it_jaros/jscanner/Scanner.java72
1 files changed, 18 insertions, 54 deletions
diff --git a/src/main/java/com/it_jaros/jscanner/Scanner.java b/src/main/java/com/it_jaros/jscanner/Scanner.java
index 7aeee03..286afde 100644
--- a/src/main/java/com/it_jaros/jscanner/Scanner.java
+++ b/src/main/java/com/it_jaros/jscanner/Scanner.java
@@ -1,20 +1,14 @@
package com.it_jaros.jscanner;
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
-import java.util.stream.Stream;
public class Scanner implements AutoCloseable {
@@ -25,7 +19,6 @@ public class Scanner implements AutoCloseable {
private final Semaphore socketLimit;
private final boolean bannerRecognition;
private final boolean disableOnlineCheck;
- private final boolean quiet;
private final int maxHostsLimit;
private final int maxWorkersPerHost;
private final int timeoutInMillis;
@@ -38,7 +31,6 @@ public class Scanner implements AutoCloseable {
int maxWorkersPerHost,
int maxHostsLimit,
boolean disableOnlineCheck,
- boolean quiet,
boolean bannerRecognition
) {
this.delayInNanos = TimeUnit.MILLISECONDS.toNanos(Math.max(0, delayInMillis));
@@ -46,52 +38,24 @@ public class Scanner implements AutoCloseable {
this.disableOnlineCheck = disableOnlineCheck;
this.maxHostsLimit = maxHostsLimit;
this.maxWorkersPerHost = maxWorkersPerHost;
- this.quiet = quiet;
this.socketLimit = new Semaphore(socketLimit);
this.timeoutInMillis = timeoutInMillis;
}
public Scanner(ScanOptions options) {
- this(options.openSocketLimit(), options.timeoutInMillis(), options.delayInMillis(), options.maxWorkersPerHost(), options.maxHostsLimit(), options.disableHostCheck(), options.quiet(), options.bannerRecognition());
+ this(options.openSocketLimit(), options.timeoutInMillis(), options.delayInMillis(), options.maxWorkersPerHost(), options.maxHostsLimit(), options.disableHostCheck(), options.bannerRecognition());
}
- public Scan createScan(ScanOptions options) {
- if (options.hostsFile() != null) {
- return createScan(options.hostsFile(), options.ports());
- }
- return createScan(options.hostsArgv(), options.ports());
- }
-
- public Scan createScan(String sourceFile, String ports) {
- try (BufferedReader reader = Files.newBufferedReader(Path.of(sourceFile))) {
- return createScan(reader.lines(), ports);
- } catch (FileNotFoundException | NoSuchFileException e) {
- System.out.printf("Could not open file %s%n", sourceFile);
- } catch (IOException e) {
- System.out.printf("Error while trying to read hosts: %s -> %s %n", e.getClass().getSimpleName(), e.getMessage());
- }
-
- return null;
- }
-
- public Scan createScan(Stream<String> hosts, String ports) {
- return new Scan(hosts.toList(), ports, new ScanState(new Counter(), new ProgressBar(quiet)));
- }
-
- public Scan createScan(List<String> hostsArgv, String ports) {
- return new Scan(hostsArgv, ports, new ScanState(new Counter(), new ProgressBar(quiet)));
- }
public List<ScanResult> runScan(Scan scan) {
if (scan == null) {
throw new IllegalArgumentException("Scan argument cannot be null");
}
- ScanState scanState = scan.state();
- scanState.getProgressBar().start();
+ scan.start();
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
CompletionService<ScanResult> completionService = new ExecutorCompletionService<>(executor);
- Queue<String> hostsInQueue = new ArrayDeque<>(scan.hosts());
+ Queue<String> hostsInQueue = new ArrayDeque<>(scan.getHosts());
int hostsToProcess = hostsInQueue.size();
int activeHostWorkers = 0;
@@ -100,7 +64,7 @@ public class Scanner implements AutoCloseable {
while (!hostsInQueue.isEmpty() && activeHostWorkers < maxHostsLimit && !cancelled) {
activeHostWorkers++;
final String host = hostsInQueue.poll();
- completionService.submit(() -> scanHostPorts(host, scan.ports(), scanState));
+ completionService.submit(() -> scanHostPorts(host, scan.getPorts(), scan));
}
try {
@@ -110,7 +74,7 @@ public class Scanner implements AutoCloseable {
}
activeHostWorkers--;
hostsToProcess--;
- scanState.addScanResult(finishedHost.get());
+ scan.addScanResult(finishedHost.get());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
@@ -123,30 +87,30 @@ public class Scanner implements AutoCloseable {
}
}
- scanState.getProgressBar().stop();
- return scanState.getSnapshotOfScanResults();
+ scan.stop();
+ return scan.getResults();
}
- private ScanResult scanHostPorts(String host, String ports, ScanState scanState) {
+ private ScanResult scanHostPorts(String host, String ports, Scan scan) {
PortRange portRange = new PortRange(ports);
- AtomicLong portSlotFactory = new AtomicLong(System.nanoTime());
BitSet openPorts = new BitSet(PortRange.MAX_PORT);
BitSet filteredPorts = new BitSet(PortRange.MAX_PORT);
- HashMap<Integer, ServiceType> bannerRecognition = new HashMap<>();
+ HashMap<Integer, ServiceType> serviceTypes = new HashMap<>();
// Give progressbar the current progress object which is then updated in the sub virtual threads
Progress progress = new Progress(host, portRange.getTotal(), new AtomicInteger(), new AtomicInteger(), new AtomicInteger());
- scanState.getProgressBar().submit(progress);
+ scan.addHostProgress(progress);
if (!disableOnlineCheck && !checkHostOnline(host)) {
// Visually show that this host is basically done
progress.done().set(progress.total());
- return new ScanResult(host, openPorts, filteredPorts, bannerRecognition);
+ return new ScanResult(host, openPorts, filteredPorts, serviceTypes);
}
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
CompletionService<PortResult> completionService = new ExecutorCompletionService<>(executor);
List<Throwable> errors = new ArrayList<>();
+ AtomicLong portSlotFactory = new AtomicLong(System.nanoTime());
int activePerHostWorkers = 0;
int portsToProcess = portRange.getTotal();
while (portsToProcess > 0 && !cancelled) {
@@ -155,7 +119,7 @@ public class Scanner implements AutoCloseable {
final int currentPort = portRange.next();
completionService.submit(() -> {
waitForSlot(portSlotFactory);
- return checkPort(host, currentPort, scanState);
+ return checkPort(host, currentPort, scan);
});
}
@@ -174,7 +138,7 @@ public class Scanner implements AutoCloseable {
switch (portResult.getState()) {
case OPEN -> {
openPorts.set(portResult.getPort());
- bannerRecognition.put(portResult.getPort(), ServiceDetector.detect(portResult.getBanner()));
+ serviceTypes.put(portResult.getPort(), ServiceDetector.detect(portResult.getBanner()));
}
case FILTERED -> filteredPorts.set(portResult.getPort());
}
@@ -194,7 +158,7 @@ public class Scanner implements AutoCloseable {
}
}
- return new ScanResult(host, openPorts, filteredPorts, bannerRecognition);
+ return new ScanResult(host, openPorts, filteredPorts, serviceTypes);
}
private boolean checkHostOnline(String host) {
@@ -216,7 +180,7 @@ public class Scanner implements AutoCloseable {
}
}
- private PortResult checkPort(String host, int port, ScanState scanState) {
+ private PortResult checkPort(String host, int port, Scan scan) {
PortResult result = new PortResult();
result.setPort(port);
result.setState(PortState.UNKNOWN);
@@ -224,7 +188,7 @@ public class Scanner implements AutoCloseable {
// don't allow more sockets then specified
socketLimit.acquireUninterruptibly();
// count how many ports are concurrently checked
- scanState.getCounter().inc();
+ scan.incSocketCounter();
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), timeoutInMillis);
@@ -240,7 +204,7 @@ public class Scanner implements AutoCloseable {
// NoRouteToHostException: this can be safely ignored because the port is closed if a host is unreachable
// Will happen a lot when scanning for open ports, so not needed
} finally {
- scanState.getCounter().dec();
+ scan.decSocketCounter();
socketLimit.release();
}