summaryrefslogtreecommitdiff
path: root/src/main/java/com/it_jaros/jscanner/CliParser.java
blob: d7f51431b83cec2cf4137fe421a4690cb8732552 (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
package com.it_jaros.jscanner;

import java.util.HashSet;
import java.util.Set;

public class CliParser {

    public ScanOptions parseArgs(String[] args) {
        if (args.length < 1 || args[0].trim().isEmpty()) {
            throw new IllegalArgumentException("No argument given");
        }

        Set<String> hostsArgv = new HashSet<>();
        String hostsFile = null;
        String ports = CliDefaults.PORTS;
        boolean bannerRecognition = CliDefaults.BANNER_RECOGNITION;
        boolean disableOnlineCheck = CliDefaults.DISABLE_HOST_CHECK;
        boolean quiet = CliDefaults.QUIET;
        boolean showFilteredPorts = CliDefaults.SHOW_FILTERED_PORTS;
        int delayInMillis = CliDefaults.DELAY_IN_MILLIS;
        int hostsLimit = CliDefaults.MAX_HOSTS_LIMIT;
        int workersPerHostLimit = 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];
            if (!currentArg.startsWith("-")) {
                hostsArgv.add(currentArg);
                continue;
            }

            switch (currentArg) {
                case "--bannerRecognition", "-b":
                    bannerRecognition = true;
                    break;
                case "--delay", "-d":
                    delayInMillis = parseIntOption(args, ++i, currentArg);
                    break;
                case "--disableOnlineCheck", "-do":
                    disableOnlineCheck = true;
                    break;
                case "--help", "-h":
                    printUsageHelp();
                    throw new HelpRequested();
                case "--input", "-i":
                    hostsFile = getArgument(args, ++i, currentArg);
                    break;
                case "--hostsLimit", "-hl":
                    hostsLimit = parseIntOption(args, ++i, currentArg);
                    break;
                case "--workersPerHostLimit", "-whl":
                    workersPerHostLimit = parseIntOption(args, ++i, currentArg);
                    break;
                case "--ports", "-p":
                    ports = getArgument(args, ++i, currentArg);
                    break;
                case "--quiet", "-q":
                    quiet = true;
                    break;
                case "--showFilteredPorts", "-sf":
                    showFilteredPorts = true;
                    break;
                case "--socketLimit", "-sl":
                    socketLimit = parseIntOption(args, ++i, currentArg);
                    break;
                case "--timeout", "-t":
                    timeoutInMillis = parseIntOption(args, ++i, currentArg);
                    break;
                default:
                    throw new IllegalArgumentException("No such param " + currentArg);
            }
        }

        if (hostsArgv.isEmpty() && hostsFile == null) {
           throw new IllegalArgumentException("No input provided. Check with --help for available options.");
        }

        return new ScanOptions(
                hostsArgv.stream().toList(),
                hostsFile,
                ports,
                bannerRecognition,
                disableOnlineCheck,
                quiet,
                showFilteredPorts,
                delayInMillis,
                hostsLimit,
                workersPerHostLimit,
                socketLimit,
                timeoutInMillis
        );
    }

    private String getArgument(String[] args, int index, String option) {
        if (index >= args.length) {
            throw new IllegalArgumentException(String.format("Missing argument for option %s", option));
        }
        return args[index];
    }

    private int parseIntOption(String[] args, int index, String option) {
        String value = getArgument(args, index, option);
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(String.format("Invalid argument %s for option %s", value, option));
        }
    }

    public void printUsageHelp() {
        StringBuilder usage = new StringBuilder();
        usage.append("""
                Usage:
                    java -jar jscanner.jar [OPTIONS] [<host>,...]

                Options:
                """);
        usage.append("""
                    --bannerRecognition, -b:\t\tEnable banner recognition to find out which service is running behind port (Default: %b)
                    --delay, -d:\t\t\tWaiting period in millis for connection attempts for a host (Default: %d)
                    --disableOnlineCheck, -do:\t\tDon't check if Host is reachable (Default: %b)
                    --input, -i:\t\t\tRead file to get host targets to scan. If set to "-" than Stdin is read (Default: null)
                    --hostsLimit, -hl:\t\t\tMax number of hosts that are scanned in parallel (Default: %d)
                    --workersPerHostLimit, -whl:\tMax workers per host. (Default: %d)
                    --ports, -p:\t\t\tDefine ports to be scanned (Default: %s)
                    --quiet, -q:\t\t\tDo not output progress bar (Default: %b)
                    --showFilteredPorts, -sf:\t\tShow also filtered ports (Default: %b)
                    --socketLimit, -sl:\t\t\tSocket limit in total. You can not scan more ports than allowed here (Default: %d)
                    --timeout, -t:\t\t\tTimeout in millis per connection attempt, 0 means infinite (Default: %d)
                """.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("""
                
                Examples:
                    java -jar jscanner.jar localhost
                    java -jar jscanner.jar fd00::1
                """);
        System.err.println(usage);
    }
}