diff --git a/src/main/java/ru/redguy/tftpserver/CheckSum.java b/src/main/java/ru/redguy/tftpserver/CheckSum.java index 5f7dd3d..9870905 100644 --- a/src/main/java/ru/redguy/tftpserver/CheckSum.java +++ b/src/main/java/ru/redguy/tftpserver/CheckSum.java @@ -5,31 +5,33 @@ import java.security.MessageDigest; public class CheckSum { - static String getChecksum(String fileName) { - StringBuffer sb = new StringBuffer(""); - try { - String datafile = fileName; - //use SHA1 to calculate checksum - MessageDigest md = MessageDigest.getInstance("SHA1"); - FileInputStream fis = new FileInputStream(datafile); - byte[] dataBytes = new byte[1024]; + static String getChecksum(String fileName) { + StringBuffer sb = new StringBuffer(""); + try { + String datafile = fileName; + //use SHA1 to calculate checksum + MessageDigest md = MessageDigest.getInstance("SHA1"); + FileInputStream fis = new FileInputStream(datafile); + byte[] dataBytes = new byte[1024]; - int nread = 0; + int nread = 0; - while ((nread = fis.read(dataBytes)) != -1) { - md.update(dataBytes, 0, nread); - } - fis.close(); + while ((nread = fis.read(dataBytes)) != -1) { + md.update(dataBytes, 0, nread); + } + fis.close(); - byte[] mdbytes = md.digest(); + byte[] mdbytes = md.digest(); - // convert the byte to hex format - for (int i = 0; i < mdbytes.length; i++) { - sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); - } + // convert the byte to hex format + for (int i = 0; i < mdbytes.length; i++) { + sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); + } - } catch (Exception e){System.out.println("Generate Checksum Failed: "+e.getMessage());} - - return sb.toString(); - } - } + } catch (Exception e) { + System.out.println("Generate Checksum Failed: " + e.getMessage()); + } + + return sb.toString(); + } +} diff --git a/src/main/java/ru/redguy/tftpserver/ErrorEvent.java b/src/main/java/ru/redguy/tftpserver/ErrorEvent.java index 2db6152..9bc27b1 100644 --- a/src/main/java/ru/redguy/tftpserver/ErrorEvent.java +++ b/src/main/java/ru/redguy/tftpserver/ErrorEvent.java @@ -2,8 +2,12 @@ package ru.redguy.tftpserver; public interface ErrorEvent { public void onPacketReceiveException(Exception exception); + public void onPacketReadException(Exception exception); + public void onPacketWriteException(Exception exception); + public void onClientReadException(Exception exception, TFTPread tftPread); + public void onClientWriteException(Exception exception, TFTPwrite tftPwrite); } diff --git a/src/main/java/ru/redguy/tftpserver/TFTPServer.java b/src/main/java/ru/redguy/tftpserver/TFTPServer.java index 4ea6a2e..9330e02 100644 --- a/src/main/java/ru/redguy/tftpserver/TFTPServer.java +++ b/src/main/java/ru/redguy/tftpserver/TFTPServer.java @@ -1,87 +1,88 @@ package ru.redguy.tftpserver; -import java.net.*; -import java.io.*; +import java.io.IOException; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; public class TFTPServer { - private DatagramSocket socket; - private Runner runner; - private Thread thread; - private ErrorEvent errorEvent; + private DatagramSocket socket; + private Runner runner; + private Thread thread; + private ErrorEvent errorEvent; - public void start() throws SocketException { - start(69); - } + public void start() throws SocketException { + start(69); + } - public void start(int port) throws SocketException { - socket = new DatagramSocket(port); - runner = new Runner(socket,this); - thread = new Thread(runner); - thread.setDaemon(true); - thread.start(); - } + public void start(int port) throws SocketException { + socket = new DatagramSocket(port); + runner = new Runner(socket, this); + thread = new Thread(runner); + thread.setDaemon(true); + thread.start(); + } - public void start(String host, int port) throws UnknownHostException, SocketException { - socket = new DatagramSocket(port,InetAddress.getByName(host)); - runner = new Runner(socket,this); - thread.setDaemon(true); - thread.start(); - } + public void start(String host, int port) throws UnknownHostException, SocketException { + socket = new DatagramSocket(port, InetAddress.getByName(host)); + runner = new Runner(socket, this); + thread.setDaemon(true); + thread.start(); + } - public int getPort() { - return socket.getLocalPort(); - } + public int getPort() { + return socket.getLocalPort(); + } - public void stop() { - thread.interrupt(); - } + public void stop() { + thread.interrupt(); + } - public void onError(ErrorEvent event) { - this.errorEvent = event; - } + public void onError(ErrorEvent event) { + this.errorEvent = event; + } - static class Runner implements Runnable { + static class Runner implements Runnable { - DatagramSocket datagramSocket; - TFTPServer server; - boolean run = true; + DatagramSocket datagramSocket; + TFTPServer server; + boolean run = true; - public Runner(DatagramSocket socket,TFTPServer server) { - this.datagramSocket = socket; - this.server = server; - } + public Runner(DatagramSocket socket, TFTPServer server) { + this.datagramSocket = socket; + this.server = server; + } - public void stop() { - run = false; - } + public void stop() { + run = false; + } - @Override - public void run() { - while (run) { - TFTPpacket in = null; - try { - in = TFTPpacket.receive(datagramSocket); - } catch (IOException e) { - server.errorEvent.onPacketReceiveException(e); - } + @Override + public void run() { + while (run) { + TFTPpacket in = null; + try { + in = TFTPpacket.receive(datagramSocket); + } catch (IOException e) { + server.errorEvent.onPacketReceiveException(e); + } - if (in instanceof TFTPread) { - try { - TFTPserverRRQ r = new TFTPserverRRQ((TFTPread) in, server.errorEvent); - } catch (TftpException e) { - server.errorEvent.onPacketReadException(e); - } - } - - else if (in instanceof TFTPwrite) { - try { - TFTPserverWRQ w = new TFTPserverWRQ((TFTPwrite) in, server.errorEvent); - } catch (TftpException e) { - server.errorEvent.onPacketWriteException(e); - } - } - } - } - } + if (in instanceof TFTPread) { + try { + TFTPserverRRQ r = new TFTPserverRRQ((TFTPread) in, server.errorEvent); + } catch (TftpException e) { + server.errorEvent.onPacketReadException(e); + } + } else if (in instanceof TFTPwrite) { + try { + TFTPserverWRQ w = new TFTPserverWRQ((TFTPwrite) in, server.errorEvent); + } catch (TftpException e) { + server.errorEvent.onPacketWriteException(e); + } + } + } + } + } } \ No newline at end of file diff --git a/src/main/java/ru/redguy/tftpserver/TFTPpacket.java b/src/main/java/ru/redguy/tftpserver/TFTPpacket.java index facd393..54836ad 100644 --- a/src/main/java/ru/redguy/tftpserver/TFTPpacket.java +++ b/src/main/java/ru/redguy/tftpserver/TFTPpacket.java @@ -1,132 +1,138 @@ package ru.redguy.tftpserver; -import java.net.*; -import java.io.*; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; class TftpException extends Exception { - public TftpException() { - super(); - } - public TftpException(String s) { - super(s); - } + public TftpException() { + super(); + } + + public TftpException(String s) { + super(s); + } } + ////////////////////////////////////////////////////////////////////////////// //GENERAL packet: define the packet structure, necessary members and methods// //of TFTP packet. To be extended by other specific packet(read, write, etc) // ////////////////////////////////////////////////////////////////////////////// public class TFTPpacket { - // TFTP constants - public static int tftpPort = 69; - public static int maxTftpPakLen=516; - public static int maxTftpData=512; + // TFTP constants + public static int tftpPort = 69; + public static int maxTftpPakLen = 516; + public static int maxTftpData = 512; - // Tftp opcodes - protected static final short tftpRRQ=1; - protected static final short tftpWRQ=2; - protected static final short tftpDATA=3; - protected static final short tftpACK=4; - protected static final short tftpERROR=5; + // Tftp opcodes + protected static final short tftpRRQ = 1; + protected static final short tftpWRQ = 2; + protected static final short tftpDATA = 3; + protected static final short tftpACK = 4; + protected static final short tftpERROR = 5; - // Packet Offsets - protected static final int opOffset=0; + // Packet Offsets + protected static final int opOffset = 0; - protected static final int fileOffset=2; + protected static final int fileOffset = 2; - protected static final int blkOffset=2; - protected static final int dataOffset=4; + protected static final int blkOffset = 2; + protected static final int dataOffset = 4; - protected static final int numOffset=2; - protected static final int msgOffset=4; + protected static final int numOffset = 2; + protected static final int msgOffset = 4; - // The actual packet for UDP transfer - protected byte [] message; - protected int length; + // The actual packet for UDP transfer + protected byte[] message; + protected int length; - // Address info (required for replies) - protected InetAddress host; - protected int port; + // Address info (required for replies) + protected InetAddress host; + protected int port; - // Constructor - public TFTPpacket() { - message=new byte[maxTftpPakLen]; - length=maxTftpPakLen; - } - - // Methods to receive packet and convert it to yhe right type(data/ack/read/...) - public static TFTPpacket receive(DatagramSocket sock) throws IOException { - TFTPpacket in=new TFTPpacket(), retPak=new TFTPpacket(); - //receive data and put them into in.message - DatagramPacket inPak = new DatagramPacket(in.message,in.length); - sock.receive(inPak); - - //Check the opcode in message, then cast the message into the corresponding type - switch (in.get(0)) { - case tftpRRQ: - retPak=new TFTPread(); - break; - case tftpWRQ: - retPak=new TFTPwrite(); - break; - case tftpDATA: - retPak=new TFTPdata(); - break; - case tftpACK: - retPak=new TFTPack(); - break; - case tftpERROR: - retPak=new TFTPerror(); - break; + // Constructor + public TFTPpacket() { + message = new byte[maxTftpPakLen]; + length = maxTftpPakLen; } - retPak.message=in.message; - retPak.length=inPak.getLength(); - retPak.host=inPak.getAddress(); - retPak.port=inPak.getPort(); - return retPak; - } - - //Method to send packet - public void send(InetAddress ip, int port, DatagramSocket s) throws IOException { - s.send(new DatagramPacket(message,length,ip,port)); - } + // Methods to receive packet and convert it to yhe right type(data/ack/read/...) + public static TFTPpacket receive(DatagramSocket sock) throws IOException { + TFTPpacket in = new TFTPpacket(), retPak = new TFTPpacket(); + //receive data and put them into in.message + DatagramPacket inPak = new DatagramPacket(in.message, in.length); + sock.receive(inPak); - // DatagramPacket like methods - public InetAddress getAddress() { - return host; - } + //Check the opcode in message, then cast the message into the corresponding type + switch (in.get(0)) { + case tftpRRQ: + retPak = new TFTPread(); + break; + case tftpWRQ: + retPak = new TFTPwrite(); + break; + case tftpDATA: + retPak = new TFTPdata(); + break; + case tftpACK: + retPak = new TFTPack(); + break; + case tftpERROR: + retPak = new TFTPerror(); + break; + } + retPak.message = in.message; + retPak.length = inPak.getLength(); + retPak.host = inPak.getAddress(); + retPak.port = inPak.getPort(); - public int getPort() { - return port; - } + return retPak; + } - public int getLength() { - return length; - } + //Method to send packet + public void send(InetAddress ip, int port, DatagramSocket s) throws IOException { + s.send(new DatagramPacket(message, length, ip, port)); + } - // Methods to put opcode, blkNum, error code into the byte array 'message'. - protected void put(int at, short value) { - message[at++] = (byte)(value >>> 8); // first byte - message[at] = (byte)(value % 256); // last byte - } + // DatagramPacket like methods + public InetAddress getAddress() { + return host; + } - @SuppressWarnings("deprecation") - //Put the filename and mode into the 'message' at 'at' follow by byte "del" - protected void put(int at, String value, byte del) { - value.getBytes(0, value.length(), message, at); - message[at + value.length()] = del; - } + public int getPort() { + return port; + } - protected int get(int at) { - return (message[at] & 0xff) << 8 | message[at+1] & 0xff; - } + public int getLength() { + return length; + } - protected String get (int at, byte del) { - StringBuffer result = new StringBuffer(); - while (message[at] != del) result.append((char)message[at++]); - return result.toString(); - } + // Methods to put opcode, blkNum, error code into the byte array 'message'. + protected void put(int at, short value) { + message[at++] = (byte) (value >>> 8); // first byte + message[at] = (byte) (value % 256); // last byte + } + + @SuppressWarnings("deprecation") + //Put the filename and mode into the 'message' at 'at' follow by byte "del" + protected void put(int at, String value, byte del) { + value.getBytes(0, value.length(), message, at); + message[at + value.length()] = del; + } + + protected int get(int at) { + return (message[at] & 0xff) << 8 | message[at + 1] & 0xff; + } + + protected String get(int at, byte del) { + StringBuffer result = new StringBuffer(); + while (message[at] != del) result.append((char) message[at++]); + return result.toString(); + } } //////////////////////////////////////////////////////// @@ -135,35 +141,37 @@ public class TFTPpacket { //////////////////////////////////////////////////////// final class TFTPdata extends TFTPpacket { - // Constructors - protected TFTPdata() {} - public TFTPdata(int blockNumber, FileInputStream in) throws IOException { - this.message = new byte[maxTftpPakLen]; - // manipulate message - this.put(opOffset, tftpDATA); - this.put(blkOffset, (short) blockNumber); - // read the file into packet and calculate the entire length - length = in.read(message, dataOffset, maxTftpData) + 4; - } + // Constructors + protected TFTPdata() { + } - // Accessors + public TFTPdata(int blockNumber, FileInputStream in) throws IOException { + this.message = new byte[maxTftpPakLen]; + // manipulate message + this.put(opOffset, tftpDATA); + this.put(blkOffset, (short) blockNumber); + // read the file into packet and calculate the entire length + length = in.read(message, dataOffset, maxTftpData) + 4; + } - public int blockNumber() { - return this.get(blkOffset); - } + // Accessors - /* - * public void data(byte[] buffer) { buffer = new byte[length-4]; - * - * for (int i=0; i