summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/jscanner/Scan.java
blob: dc109c6dd1e1a70dc0d88ff827ef4171b995e5c8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package com.it_jaros.jscanner;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;

/**
 * Object holder for stateful volatile data during scan
 */
public class Scan {
    private final Stream<String> hosts;
    private final String ports;
    private final Runnable onDone;
    private final Counter hostCounter;
    private final Counter hostTotalCounter;
    private final Counter portTotalCounter;
    private final Counter socketCounter;
    private final Counter threadCounter;
    private long start = 0;
    private long stop = 0;

    private Scan(Stream<String> hosts, String ports) {
        this(hosts, ports, () -> {});
    }

    private Scan(Stream<String> hosts, String ports, Runnable onDone) {
        this.hosts = hosts;
        this.ports = ports;
        this.onDone = onDone;
        this.hostCounter = new Counter();
        this.hostTotalCounter = new Counter();
        this.portTotalCounter = new Counter();
        this.socketCounter = new Counter();
        this.threadCounter = new Counter();
    }

    public static Scan create(ScanOptions options) throws IOException {
        if (options.hostsFile() != null) {
            return create(options.hostsFile(), options.ports());
        }
        return create(options.hostsArgv(), options.ports());
    }

    /**
     * Create Scan based on either a source file or stdin
     *
     * @param sourceFile
     * @param ports
     * @return
     * @throws IOException
     */
    public static Scan create(String sourceFile, String ports) {
        Stream<String> hosts;
        if (sourceFile == null || sourceFile.isEmpty()) {
            throw new IllegalArgumentException("Source file is null or empty");
        }

        if ("-".equals(sourceFile)) {
            BufferedReader stdinReader = new BufferedReader(new InputStreamReader(System.in));
            hosts = stdinReader.lines();
            return new Scan(hosts, ports);
        }

        try {
            BufferedReader reader = Files.newBufferedReader(Path.of(sourceFile));
            return new Scan(reader.lines(), ports, () -> {
                try {
                    reader.close();
                } catch (IOException ignore) {
                    // we ignore it because at this moment the program is shutting down anyway
                }
            });
        } catch (IOException e) {
            throw new ScanException("Error while trying to open source File", e);
        }
    }

    public static Scan create(List<String> hostsArgv, String ports) {
        return new Scan(hostsArgv.stream(), ports);
    }

    public Stream<String> getHosts() {
        return hosts;
    }

    public String getPorts() {
        return ports;
    }

    public void stop() {
        stop = System.currentTimeMillis();
        onDone.run();
    }

    public Counter getThreadCounter() {
        return threadCounter;
    }

    public Counter getHostCounter() {
        return hostCounter;
    }

    public Counter getSocketCounter() {
        return socketCounter;
    }

    public Counter getHostTotalCounter() {
        return hostTotalCounter;
    }

    public void start() {
        start = System.currentTimeMillis();
    }

    public long getDurationMillis() {
        if (stop == 0) {
            if (start == 0) {
                return 0;
            }
            return System.currentTimeMillis() - start;
        }
        return stop - start;
    }

    public void portStart() {
        this.portTotalCounter.inc();
        this.threadCounter.inc();
    }

    public void portFinish() {
        this.threadCounter.dec();
    }

    public void hostStart() {
        this.hostCounter.inc();
        this.hostTotalCounter.inc();
        this.threadCounter.inc();
    }

    public void hostFinish() {
        this.threadCounter.dec();
        this.hostCounter.dec();
    }

    public void socketStart() {
        this.socketCounter.inc();
    }

    public void socketFinish() {
        this.socketCounter.dec();
    }

    public void producerStart() {
        this.threadCounter.inc();
    }

    public void producerStop() {
        this.threadCounter.dec();
    }

    public int portTotal() {
        return this.portTotalCounter.current();
    }
}