Skip to content

Commit a6c5063

Browse files
tzaeschkeTilmann Zäschke
andauthored
CLI help (#20)
* CLI help --------- Co-authored-by: Tilmann Zäschke <[email protected]>
1 parent 02d7c0b commit a6c5063

File tree

4 files changed

+157
-12
lines changed

4 files changed

+157
-12
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
-- Nothing yet
1111

12+
### Added
13+
14+
- Added command line `--help` and several options to multi-ping.
15+
[#20](https://github.com/netsec-ethz/scion-java-multiping/pull/20)
16+
1217
## [0.5.0] - 2025-09-09
1318

1419
### Added

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ java -jar scion-multiping-0.5.0-executable.jar [tool-command]
2323
Some tools require configuration files, see below in the tool description sections.
2424
See also the troubleshooting section below in case of issues.
2525

26+
# Help
27+
28+
To get command line help, the tool can be executed with:
29+
30+
```
31+
java -jar scion-multiping-0.5.0-executable.jar --help
32+
```
33+
34+
2635
# Download Assignments
2736

2837
The tool
@@ -34,7 +43,9 @@ Note: the `isd-as-assignments.csv` output file can be directly used as input fil
3443

3544
The tool
3645
parses [Anapayas ISD/AS assignment website](https://docs.anapaya.net/en/latest/resources/isd-as-assignments/),
37-
identifies the shortest path to each AS and sends a traceroute to each AS.
46+
identifies the shortest or fastest path to each AS and sends a traceroute to each AS.
47+
By default is will use the fastest path (determined by a traceroute over all paths), but it can be
48+
configured to use the shortest path (`--shortest`).
3849
It reports the number of paths to each AS as well as the shortest path with latency, remote IP, hop
3950
count and remote IP.
4051

src/main/java/org/scion/multiping/Main.java

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,35 @@
2222
public class Main {
2323

2424
public static void main(String[] args) throws IOException {
25-
if (args.length != 1) {
26-
printUsage();
27-
System.exit(1);
28-
}
25+
checkArgs(args, 1, Integer.MAX_VALUE);
2926
String mode = args[0].toLowerCase(Locale.ROOT);
3027
String[] newArgs = Arrays.copyOfRange(args, 1, args.length);
3128
switch (mode) {
3229
case "download-assignments":
3330
{
31+
checkArgs(args, 1, 1);
3432
DownloadAssignments.main(newArgs);
3533
return;
3634
}
35+
case "help":
36+
{
37+
printHelp(args.length == 1 ? "" : args[1]);
38+
return;
39+
}
3740
case "ping-all":
3841
{
3942
PingAll.main(newArgs);
4043
return;
4144
}
4245
case "ping-repeat":
4346
{
47+
checkArgs(args, 1, 1);
4448
PingRepeat.main(newArgs);
4549
return;
4650
}
4751
case "ping-responder":
4852
{
53+
checkArgs(args, 1, 1);
4954
PingResponder.main(newArgs);
5055
return;
5156
}
@@ -55,6 +60,33 @@ public static void main(String[] args) throws IOException {
5560
}
5661
}
5762

63+
private static void checkArgs(String[] args, int minArgs, int maxArgs) {
64+
if (args.length < minArgs || args.length > maxArgs) {
65+
Util.println("Invalid number of arguments.");
66+
printUsage();
67+
System.exit(1);
68+
}
69+
}
70+
71+
private static void printHelp(String mode) {
72+
switch (mode) {
73+
case "download-assignments":
74+
printUsageDownloadAssignments();
75+
return;
76+
case "ping-all":
77+
printUsagePingAll();
78+
return;
79+
case "ping-repeat":
80+
printUsagePingRepeat();
81+
return;
82+
case "ping-responder":
83+
printUsagePingResponder();
84+
return;
85+
default:
86+
printUsage();
87+
}
88+
}
89+
5890
private static void printUsage() {
5991
Util.println("Usage: scion-multiping [MODE]");
6092
Util.println("where MODE is one of: ");
@@ -65,6 +97,53 @@ private static void printUsage() {
6597
" - `ping-repeat` for repeatedly probing (traceroute) multiple paths to multiple ASes.");
6698
Util.println(
6799
" - `ping-responder` for starting a server that responds to incoming echo requests.");
100+
Util.println(" - `help [MODE]` for getting more help for a given mode.");
101+
Util.println("");
102+
}
103+
104+
private static void printUsageDownloadAssignments() {
105+
Util.println("Usage: scion-multiping download-assignments");
106+
Util.println();
107+
Util.println(
108+
" This tool downloads a list of known ISD/AS assignments and saves it to a file.");
109+
Util.println(" The output file is called `isd-as-assignments.csv`.");
110+
Util.println("");
111+
}
112+
113+
static void printUsagePingAll() {
114+
Util.println(
115+
"Usage: ping-all [--help] [--fastest|--shortest|--shortest_echo|--fastest_sync] [--port <port>] [--shim]");
116+
Util.println(" --help Show this help message.");
117+
Util.println(" --fastest Use fastest path with SCMP traceroute (default).");
118+
Util.println(
119+
" The fastest path is determined by running a single traceroute on all path.");
120+
// Util.println(" --fastest_sync Use fastest path with SCMP traceroute (synchronous)");
121+
Util.println(" --shortest Use shortest path (fewest hops) with SCMP traceroute.");
122+
// Util.println(" --shortest_echo Use shortest path with SCMP echo");
123+
Util.println(
124+
" --port <port> Use specified local port (default " + PingAll.localPort + ").");
125+
Util.println(" --shim Start with SHIM enabled (default disabled).");
126+
Util.println("");
127+
}
128+
129+
private static void printUsagePingRepeat() {
130+
Util.println("Usage: scion-multiping ping-repeat");
131+
Util.println();
132+
Util.println(
133+
" This tool is used for repeatedly probing (traceroute) multiple paths to multiple ASes.");
134+
Util.println(" The destination ASes are read from a file `isd-as-assignments.csv`.");
135+
Util.println(" Other configuration options can be defined in `ping-repeat-config.json`.");
136+
Util.println(" Results are written to a CSV file `ping-results.csv`.");
137+
Util.println(" See README.md for more information.");
138+
Util.println("");
139+
}
140+
141+
private static void printUsagePingResponder() {
142+
Util.println("Usage: scion-multiping ping-responder");
143+
Util.println();
144+
Util.println(" This command starts a server that responds to incoming echo requests.");
145+
Util.println(" It takes a configuration file `ping-responder-config.json` as input.");
146+
Util.println(" See README.md for more information.");
68147
Util.println("");
69148
}
70149
}

src/main/java/org/scion/multiping/PingAll.java

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public class PingAll {
5252
private static final boolean SHOW_ONLY_ICMP = false;
5353
private static final Config config = new Config();
5454

55-
private static final int LOCAL_PORT = 30041;
56-
private static final boolean STOP_SHIM = true;
55+
static int localPort = 30041;
56+
private static boolean startShim = false;
5757

5858
static {
5959
config.tryICMP = false;
@@ -88,21 +88,71 @@ enum Policy {
8888
this.service = service;
8989
}
9090

91-
public static void main(String[] args) throws IOException {
91+
public static void main(String[] argsArray) throws IOException {
9292
PRINT = true;
93-
// System.setProperty(Constants.PROPERTY_DNS_SEARCH_DOMAINS, "ethz.ch.");
94-
System.setProperty(Constants.PROPERTY_SHIM, STOP_SHIM ? "false" : "true"); // disable SHIM
93+
94+
Policy policy = parseArgs(argsArray);
95+
96+
System.setProperty(Constants.PROPERTY_SHIM, startShim ? "true" : "false"); // disable SHIM
9597

9698
println("Settings:");
97-
println(" Path policy = " + DEFAULT_POLICY);
99+
println(" Path policy = " + policy);
98100
println(" ICMP=" + config.tryICMP);
99101
println(" printOnlyICMP=" + SHOW_ONLY_ICMP);
100102

101-
PingAll pingAll = new PingAll(DEFAULT_POLICY, ScionProvider.defaultProvider(LOCAL_PORT));
103+
PingAll pingAll = new PingAll(policy, ScionProvider.defaultProvider(localPort));
102104
pingAll.run();
103105
pingAll.summary.prettyPrint();
104106
}
105107

108+
private static Policy parseArgs(String[] argsArray) {
109+
List<String> args = new ArrayList<>(Arrays.asList(argsArray));
110+
Policy policy = DEFAULT_POLICY;
111+
while (!args.isEmpty()) {
112+
switch (args.get(0)) {
113+
case "--fastest":
114+
policy = Policy.FASTEST_TR_ASYNC;
115+
break;
116+
case "--shortest":
117+
policy = Policy.SHORTEST_TR;
118+
break;
119+
case "--shortest_echo":
120+
policy = Policy.SHORTEST_ECHO;
121+
break;
122+
case "--fastest_sync":
123+
policy = Policy.FASTEST_TR;
124+
break;
125+
case "--help":
126+
Main.printUsagePingAll();
127+
System.exit(0);
128+
case "--shim":
129+
startShim = true;
130+
break;
131+
case "--port":
132+
if (args.size() < 2) {
133+
Util.println("Error: --port requires a port number");
134+
Main.printUsagePingAll();
135+
System.exit(1);
136+
}
137+
try {
138+
localPort = Integer.parseInt(args.get(1));
139+
} catch (NumberFormatException e) {
140+
Util.println("Error: Invalid port number: " + args.get(1));
141+
Main.printUsagePingAll();
142+
System.exit(1);
143+
}
144+
args.remove(1);
145+
break;
146+
default:
147+
Util.println("Unknown option: " + args.get(0));
148+
Main.printUsagePingAll();
149+
System.exit(1);
150+
}
151+
args.remove(0);
152+
}
153+
return policy;
154+
}
155+
106156
ResultSummary run() throws IOException {
107157
List<ParseAssignments.HostEntry> allASes = service.getIsdAsEntries();
108158
// remove entry for local AS

0 commit comments

Comments
 (0)