/
PortTextFetcher.java
140 lines (120 loc) · 4.2 KB
/
PortTextFetcher.java
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
/*
This file is a part of Angry IP Scanner source code,
see http://www.angryip.org/ for more information.
Licensed under GPLv2.
*/
package net.azib.ipscan.fetchers;
import net.azib.ipscan.config.LoggerFactory;
import net.azib.ipscan.config.ScannerConfig;
import net.azib.ipscan.core.ScanningResult.ResultType;
import net.azib.ipscan.core.ScanningSubject;
import net.azib.ipscan.gui.fetchers.PortTextFetcherPrefs;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.Thread.currentThread;
import static java.util.Collections.singleton;
import static net.azib.ipscan.fetchers.PortsFetcher.PARAMETER_OPEN_PORTS;
/**
* PortTextFetcher - generic configurable fetcher to read some particular information from a port.
*
* @author Anton Keks
*/
public abstract class PortTextFetcher extends AbstractFetcher {
private static final Logger LOG = LoggerFactory.getLogger();
private ScannerConfig scannerConfig;
private int defaultPort;
protected boolean scanOpenPorts;
protected String textToSend;
protected Pattern matchingRegexp;
protected int extractGroup;
public PortTextFetcher(ScannerConfig scannerConfig, int defaultPort, String defaultTextToSend, String matchingRegexp) {
this.scannerConfig = scannerConfig;
this.defaultPort = defaultPort;
this.textToSend = getPreferences().get("textToSend", defaultTextToSend);
this.matchingRegexp = Pattern.compile(getPreferences().get("matchingRegexp", matchingRegexp));
this.extractGroup = getPreferences().getInt("extractGroup", 1);
}
public Object scan(ScanningSubject subject) {
Iterator<Integer> portIterator = getPortIterator(subject);
while (portIterator.hasNext() && !currentThread().isInterrupted()) {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(subject.getAddress(), portIterator.next()), subject.getAdaptedPortTimeout());
socket.setTcpNoDelay(true);
socket.setSoTimeout(scannerConfig.portTimeout * 2);
socket.setSoLinger(true, 0);
socket.getOutputStream().write(textToSend.getBytes());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
Matcher matcher = matchingRegexp.matcher(line);
if (matcher.find()) {
// mark that additional info is available
subject.setResultType(ResultType.WITH_PORTS);
// return the required contents
return getResult(matcher, socket.getPort());
}
}
}
catch (ConnectException e) {
// no connection
}
catch (SocketTimeoutException e) {
// no information
}
catch (SocketException e) {
// connection reset
}
catch (IOException e) {
LOG.log(Level.FINE, subject.getAddress().toString(), e);
}
}
return null;
}
protected String getResult(Matcher matcher, int port) {
String result = matcher.group(extractGroup);
return result.isEmpty() ? String.valueOf(port) : result;
}
private Iterator<Integer> getPortIterator(ScanningSubject subject) {
if (scanOpenPorts) {
@SuppressWarnings("unchecked")
SortedSet<Integer> openPorts = (SortedSet<Integer>) subject.getParameter(PARAMETER_OPEN_PORTS);
if (openPorts != null) {
SortedSet<Integer> ports = new TreeSet<>(openPorts);
ports.add(defaultPort);
return ports.iterator();
}
}
return subject.isAnyPortRequested() ? subject.requestedPortsIterator() : singleton(defaultPort).iterator();
}
@Override
public Class<? extends FetcherPrefs> getPreferencesClass() {
return PortTextFetcherPrefs.class;
}
public String getTextToSend() {
return textToSend;
}
public void setTextToSend(String textToSend) {
this.textToSend = textToSend;
}
public Pattern getMatchingRegexp() {
return matchingRegexp;
}
public void setMatchingRegexp(Pattern matchingRegexp) {
this.matchingRegexp = matchingRegexp;
}
public int getExtractGroup() {
return extractGroup;
}
public void setExtractGroup(int extractGroup) {
this.extractGroup = extractGroup;
}
}