1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.tftp;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Random;
25
26 import org.apache.commons.io.FileUtils;
27
28
29
30
31
32
33 public class TFTPServerMain {
34
35 private static final String USAGE = "Usage: TFTPServerMain [options] [port]\n\n" + "port - the port to use (default 6901)\n"
36 + "\t-p path to server directory (default java.io.tempdir)\n" + "\t-r randomly introduce errors\n" + "\t-v verbose (trace packets)\n";
37
38 public static void main(final String[] args) throws Exception {
39 int port = 6901;
40 int argc;
41 final Map<String, String> opts = new HashMap<>();
42 opts.put("-p", FileUtils.getTempDirectoryPath());
43
44 for (argc = 0; argc < args.length; argc++) {
45 final String arg = args[argc];
46 if (!arg.startsWith("-")) {
47 break;
48 }
49 if (arg.equals("-v") || arg.equals("-r")) {
50 opts.put(arg, arg);
51 } else if (arg.equals("-p")) {
52 opts.put(arg, args[++argc]);
53 } else {
54 System.err.println("Error: unrecognized option.");
55 System.err.print(USAGE);
56 System.exit(1);
57 }
58 }
59
60 if (argc < args.length) {
61 port = Integer.parseInt(args[argc]);
62 argc++;
63 }
64 final boolean verbose = opts.containsKey("-v");
65 final boolean randomErrors = opts.containsKey("-r");
66 final Random rand = randomErrors ? new Random() : null;
67
68 final File serverDirectory = new File(opts.get("-p"));
69 System.out.println("Server directory: " + serverDirectory);
70 final TFTPServer tftpS = new TFTPServer(serverDirectory, serverDirectory, port, TFTPServer.ServerMode.GET_AND_PUT, null, null) {
71 @Override
72 TFTP newTFTP() {
73 if (verbose) {
74 return new TFTP() {
75 @Override
76 protected void trace(final String direction, final TFTPPacket packet) {
77 System.out.println(direction + " " + packet.toString());
78 }
79 };
80 }
81 return new TFTP();
82 }
83
84 @Override
85 void sendData(final TFTP tftp, final TFTPPacket packet) throws IOException {
86 if (rand == null) {
87 super.sendData(tftp, packet);
88 return;
89 }
90 final int rint = rand.nextInt(10);
91 switch (rint) {
92 case 0:
93 System.out.println("Bump port " + packet);
94 final int port = packet.getPort();
95 packet.setPort(port + 5);
96 super.sendData(tftp, packet);
97 packet.setPort(port);
98 break;
99 case 1:
100 if (packet instanceof TFTPDataPacket) {
101 final TFTPDataPacket data = (TFTPDataPacket) packet;
102 System.out.println("Change data block num");
103 data.blockNumber--;
104 super.sendData(tftp, packet);
105 data.blockNumber++;
106 }
107 if (packet instanceof TFTPAckPacket) {
108 final TFTPAckPacket ack = (TFTPAckPacket) packet;
109 System.out.println("Change ack block num");
110 ack.blockNumber--;
111 super.sendData(tftp, packet);
112 ack.blockNumber++;
113 }
114 break;
115 case 2:
116 System.out.println("Drop packet: " + packet);
117 break;
118 case 3:
119 System.out.println("Dupe packet: " + packet);
120 super.sendData(tftp, packet);
121 super.sendData(tftp, packet);
122 break;
123 default:
124 super.sendData(tftp, packet);
125 break;
126 }
127 }
128 };
129
130 Runtime.getRuntime().addShutdownHook(new Thread() {
131 @Override
132 public void run() {
133 System.out.println("Server shutting down");
134 tftpS.close();
135 System.out.println("Server exit");
136 }
137 });
138 System.out.println("Started the server on " + port);
139 Thread.sleep(99999999L);
140 }
141
142 }