1 | static class ProgramScan {
|
2 | static int threads = isWindows() ? 500 : 10;
|
3 | static int timeout = 5000; // hmm...
|
4 | static String ip = "127.0.0.1";
|
5 |
|
6 | // This range is not used anymore anyway
|
7 | static int quickScanFrom = 10000, quickScanTo = 10999;
|
8 |
|
9 | static int maxNumberOfVMs_android = 4; // Android will always only have one if we don't screw up
|
10 | static int maxNumberOfVMs_nonAndroid = 50; // 100;
|
11 | static int maxNumberOfVMs;
|
12 |
|
13 | static boolean verbose;
|
14 |
|
15 | static class Program {
|
16 | int port;
|
17 | String helloString;
|
18 |
|
19 | *(int *port, String *helloString) {}
|
20 | }
|
21 |
|
22 | static List<Program> scan() ctex {
|
23 | return scan(1, 65535);
|
24 | }
|
25 |
|
26 | static List<Program> scan(int fromPort, int toPort) {
|
27 | return scan(fromPort, toPort, new int[0]);
|
28 | }
|
29 |
|
30 | static List<Program> scan(int fromPort, int toPort, int[] preferredPorts) ctex {
|
31 | Set<int> preferredPortsSet = new HashSet<int>(asList(preferredPorts));
|
32 | int scanSize = toPort-fromPort+1;
|
33 | S name = toPort < 10000 ? "bot" : "program";
|
34 | int threads = isWindows() ? min(500, scanSize) : min(scanSize, 10);
|
35 | final ExecutorService es = Executors.newFixedThreadPool(threads);
|
36 | if (verbose) print(firstToUpper(name) + "-scanning " + ip + " with timeout " + timeout + " ms in " + threads + " threads.");
|
37 | startTiming();
|
38 | new List<Future<Program>> futures;
|
39 | new L<Int> ports;
|
40 | for (int port : preferredPorts) {
|
41 | futures.add(checkPort(es, ip, port, timeout));
|
42 | ports.add(port);
|
43 | }
|
44 | for (int port = fromPort; port <= toPort; port++)
|
45 | if (!preferredPortsSet.contains(port) && !forbiddenPort(port)) {
|
46 | futures.add(checkPort(es, ip, port, timeout));
|
47 | ports.add(port);
|
48 | }
|
49 | es.shutdown();
|
50 | new List<Program> programs;
|
51 | long time = now();
|
52 | int i = 0;
|
53 | for (final Future<Program> f : futures) {
|
54 | if (verbose) print("Waiting for port " + get(ports, i++) + " at time " + (now()-time));
|
55 | Program p = f.get();
|
56 | if (p != null)
|
57 | programs.add(p);
|
58 | }
|
59 | //stopTiming("Port Scan " + scanSize + ", " + n(threads, "threads") + ": ", 250);
|
60 | if (verbose) print("Found " + programs.size() + " " + name + "(s) on " + ip);
|
61 | return programs;
|
62 | }
|
63 |
|
64 | static Future<Program> checkPort(final ExecutorService es, final String ip, final int port, final int timeout) {
|
65 | return es.submit(new Callable<Program>() {
|
66 | @Override public Program call() {
|
67 | try {
|
68 | Socket socket = new Socket();
|
69 | try {
|
70 | socket.setSoTimeout(timeout);
|
71 | socket.connect(new InetSocketAddress(ip, port), timeout);
|
72 | //if (verbose) print("Connected to " + ip + ":" + port);
|
73 | BufferedReader in = new BufferedReader(
|
74 | new InputStreamReader(socket.getInputStream(), "UTF-8"));
|
75 | S hello = or(in.readLine(), "?");
|
76 | return new Program(port, hello);
|
77 | } finally {
|
78 | socket.close();
|
79 | }
|
80 | } catch (Exception ex) {
|
81 | return null;
|
82 | }
|
83 | }
|
84 | });
|
85 | }
|
86 |
|
87 | static List<Program> quickScan() {
|
88 | return scan(quickScanFrom, quickScanTo);
|
89 | }
|
90 |
|
91 | static List<Program> quickBotScan() {
|
92 | return quickBotScan(new int[0]);
|
93 | }
|
94 |
|
95 | static List<Program> quickBotScan(int[] preferredPorts) {
|
96 | if (maxNumberOfVMs == 0)
|
97 | maxNumberOfVMs = isAndroid() ? maxNumberOfVMs_android : maxNumberOfVMs_nonAndroid;
|
98 | return scan(4999, 5000+maxNumberOfVMs-1, preferredPorts);
|
99 | }
|
100 | } |