⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t2hproxy.java

📁 linux下从网卡远程启动
💻 JAVA
字号:
/* *  TFTP to HTTP proxy in Java * *  Copyright Ken Yap 2003 *  Released under GPL2 */import java.io.IOException;import java.io.InputStream;import java.io.FileInputStream;import java.io.BufferedInputStream;import java.io.UnsupportedEncodingException;import java.lang.String;import java.lang.StringBuffer;import java.lang.Thread;import java.lang.NumberFormatException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;import java.net.SocketTimeoutException;import java.nio.Buffer;import java.nio.ByteBuffer;import java.nio.BufferUnderflowException;import java.util.HashMap;import java.util.Properties;import org.apache.commons.httpclient.Credentials;import org.apache.commons.httpclient.Header;import org.apache.commons.httpclient.HostConfiguration;import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpException;import org.apache.commons.httpclient.HttpMethod;import org.apache.commons.httpclient.UsernamePasswordCredentials;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** *  Description of the Class * *@author     ken *@created    24 September 2003 */public class T2hproxy implements Runnable {	/**	 *  Description of the Field	 */	public final static String NAME = T2hproxy.class.getName();	/**	 *  Description of the Field	 */	public final static String VERSION = "0.1";	/**	 *  Description of the Field	 */	public final static int MTU = 1500;	/**	 *  Description of the Field	 */	public final static short TFTP_RRQ = 1;	/**	 *  Description of the Field	 */	public final static short TFTP_DATA = 3;	/**	 *  Description of the Field	 */	public final static short TFTP_ACK = 4;	/**	 *  Description of the Field	 */	public final static short TFTP_ERROR = 5;	/**	 *  Description of the Field	 */	public final static short TFTP_OACK = 6;	/**	 *  Description of the Field	 */	public final static short ERR_NOFILE = 1;	/**	 *  Description of the Field	 */	public final static short ERR_ILLOP = 4;	/**	 *  Description of the Field	 */	public final static int MAX_RETRIES = 5;	/**	 *  TFTP timeout in milliseconds	 */	public final static int TFTP_ACK_TIMEOUT = 2000;	/**	 *  Description of the Field	 */	public final static int DEFAULT_PROXY_PORT = 3128;	private static Log log = LogFactory.getLog(T2hproxy.class);	/**	 *  The members below must be per thread and must not share any storage with	 *  the main thread	 */	private DatagramSocket responsesocket;	private DatagramPacket response;	private InetAddress iaddr;	private int port;	private byte[] req;	private String prefix;	private String proxy = null;	private int timeout;	private HashMap options = new HashMap();	private int blocksize = 512;	private HttpClient client = new HttpClient();	private HttpMethod method;	private BufferedInputStream bstream = null;	private String message;	/**	 *  Constructor for the T2hproxy object	 *	 *@param  i   Description of the Parameter	 *@param  p   Description of the Parameter	 *@param  b   Description of the Parameter	 *@param  pf  Description of the Parameter	 *@param  pr  Description of the Parameter	 *@param  t   Timeout for HTTP GET	 */	public T2hproxy(InetAddress i, int p, byte[] b, String pf, String pr, int t) {		iaddr = i;		port = p;		// make a copy of the request buffer		req = new byte[b.length];		System.arraycopy(b, 0, req, 0, b.length);		prefix = pf;		// proxy can be null		proxy = pr;		timeout = t;	}	/**	 *  Extract an asciz string from bufer	 *	 *@param  buffer  Description of the Parameter	 *@return         The asciz value	 */	private String getAsciz(ByteBuffer buffer) {		StringBuffer s = new StringBuffer();		try {			byte b;			while ((b = buffer.get()) != 0) {				s.append((char) b);			}		} catch (BufferUnderflowException e) {		} finally {			return (s.toString());		}	}	/**	 *  Convert a string of digits to a number, invalid => 0	 *	 *@param  s  Description of the Parameter	 *@return    Description of the Return Value	 */	private int atoi(String s) {		if (s == null) {			return (0);		}		int value = 0;		try {			value = (new Integer(s)).intValue();		} catch (NumberFormatException e) {		}		return (value);	}	/**	 *  Wait for ack packet with timeout	 *	 *@return    Return block number acked	 */	private int waitForAck() {		DatagramPacket ack = new DatagramPacket(new byte[MTU], MTU);		try {			do {				responsesocket.setSoTimeout(TFTP_ACK_TIMEOUT);				responsesocket.receive(ack);			} while (!ack.getAddress().equals(iaddr) || ack.getPort() != port);		} catch (SocketTimeoutException e) {			return (-1);		} catch (Exception e) {			log.info(e.toString(), e);		}		ByteBuffer buffer = ByteBuffer.wrap(ack.getData(), ack.getOffset(), ack.getLength() - ack.getOffset());		short op;		if ((op = buffer.getShort()) == TFTP_ACK) {			return ((int) buffer.getShort());		} else if (op == TFTP_ERROR) {			return (-2);		}		return (-3);	}	/**	 *  Description of the Method	 *	 *@param  error    Description of the Parameter	 *@param  message  Description of the Parameter	 */	private void sendError(short error, String message) {		ByteBuffer buffer = ByteBuffer.wrap(response.getData());		buffer.putShort(TFTP_ERROR).putShort(error).put(message.getBytes());		response.setLength(buffer.position());		try {			responsesocket.send(response);		} catch (Exception e) {			log.info(e.toString(), e);		}	}	/**	 *  Description of the Method	 *	 *@return    Description of the Return Value	 */	private boolean sendOackRecvAck() {		ByteBuffer buffer = ByteBuffer.wrap(response.getData());		buffer.putShort(TFTP_OACK).put("blksize".getBytes()).put((byte) 0).put(String.valueOf(blocksize).getBytes()).put((byte) 0);		response.setLength(buffer.position());		int retry;		for (retry = 0; retry < MAX_RETRIES; retry++) {			try {				responsesocket.send(response);			} catch (Exception e) {				log.info(e.toString(), e);			}			if (waitForAck() == 0) {				log.debug("Ack received");				break;			}		}		return (retry < MAX_RETRIES);	}	/**	 *  Description of the Method	 *	 *@param  block      Description of the Parameter	 *@return            Description of the Return Value	 */	private boolean sendDataBlock(int block) {		int retry;		for (retry = 0; retry < MAX_RETRIES; retry++) {			try {				responsesocket.send(response);			} catch (Exception e) {				log.info(e.toString(), e);			}			int ablock;			if ((ablock = waitForAck()) == block) {				log.debug("Ack received for " + ablock);				break;			} else if (ablock == -1) {				log.info("Timeout waiting for ack");			} else if (ablock == -2) {				return (false);			} else {				log.info("Unknown opcode from ack");			}		}		return (retry < MAX_RETRIES);	}	/**	 *  Description of the Method	 *	 *@param  buffer  Description of the Parameter	 *@return         Description of the Return Value	 */	private boolean handleOptions(ByteBuffer buffer) {		for (; ; ) {			String option = getAsciz(buffer);			String value = getAsciz(buffer);			if (option.equals("") || value.equals("")) {				break;			}			log.info(option + " " + value);			options.put(option, value);		}		blocksize = atoi((String) options.get("blksize"));		if (blocksize < 512) {			blocksize = 512;		}		if (blocksize > 1432) {			blocksize = 1432;		}		return (sendOackRecvAck());	}	/**	 *  Description of the Method	 *	 *@param  url  Description of the Parameter	 */	private void makeStream(String url) {		// establish a connection within timeout milliseconds		client.setConnectionTimeout(timeout);		if (proxy != null) {			String[] hostport = proxy.split(":");			int port = DEFAULT_PROXY_PORT;			if (hostport.length > 1) {				port = atoi(hostport[1]);				if (port == 0) {					port = DEFAULT_PROXY_PORT;				}			}			log.info("Proxy is " + hostport[0] + ":" + port);			client.getHostConfiguration().setProxy(hostport[0], port);		}		// create a method object		method = new GetMethod(url);		method.setFollowRedirects(true);		method.setStrictMode(false);		try {			int status;			if ((status = client.executeMethod(method)) != 200) {				log.info(message = method.getStatusText());				return;			}			bstream = new BufferedInputStream(method.getResponseBodyAsStream());		} catch (HttpException he) {			message = he.getMessage();		} catch (IOException ioe) {			message = "Unable to get " + url;		}	}	/**	 *  Reads a block of data from URL stream	 *	 *@param  stream     Description of the Parameter	 *@param  data       Description of the Parameter	 *@param  blocksize  Description of the Parameter	 *@param  offset     Description of the Parameter	 *@return            Number of bytes read	 */	private int readBlock(BufferedInputStream stream, byte[] data, int offset, int blocksize) {		int status;		int nread = 0;		while (nread < blocksize) {			try {				status = stream.read(data, offset + nread, blocksize - nread);			} catch (Exception e) {				return (-1);			}			if (status < 0) {				return (nread);			}			nread += status;		}		return (nread);	}	/**	 *  Description of the Method	 *	 *@param  filename  Description of the Parameter	 */	private void doRrq(String filename) {		String url = prefix + filename;		log.info("GET " + url);		makeStream(url);		if (bstream == null) {			log.info(message);			sendError(ERR_NOFILE, message);			return;		}		// read directly into send buffer to avoid buffer copying		byte[] data;		ByteBuffer buffer = ByteBuffer.wrap(data = response.getData());		// dummy puts to get start position of data		buffer.putShort(TFTP_DATA).putShort((short) 0);		int start = buffer.position();		int length;		int block = 1;		do {			length = readBlock(bstream, data, start, blocksize);			block &= 0xffff;			log.debug("Block " + block + " " + length);			// fill in the block number			buffer.position(0);			buffer.putShort(TFTP_DATA).putShort((short) block);			response.setLength(start + length);			if (!sendDataBlock(block)) {				break;			}			buffer.position(start);			block++;		} while (length >= blocksize);		log.info("Closing TFTP session");		// clean up the connection resources		method.releaseConnection();		method.recycle();	}	/**	 *  Main processing method for the T2hproxy object	 */	public void run() {		ByteBuffer buffer = ByteBuffer.wrap(req);		buffer.getShort();		String filename = getAsciz(buffer);		String mode = getAsciz(buffer);		log.info(filename + " " + mode);		response = new DatagramPacket(new byte[MTU], MTU, iaddr, port);		try {			responsesocket = new DatagramSocket();		} catch (SocketException e) {			log.info(e.toString(), e);			return;		}		if (!handleOptions(buffer)) {			return;		}		doRrq(filename);	}	/**	 *  Description of the Method	 *	 *@param  s        Description of the Parameter	 *@param  r        Description of the Parameter	 *@param  prefix   Description of the Parameter	 *@param  proxy    Description of the Parameter	 *@param  timeout  Description of the Parameter	 */	public static void handleRequest(DatagramSocket s, DatagramPacket r, String prefix, String proxy, int timeout) {		log.info("Connection from " + r.getAddress().getCanonicalHostName() + ":" + r.getPort());		ByteBuffer buffer = ByteBuffer.wrap(r.getData(), r.getOffset(), r.getLength() - r.getOffset());		if (buffer.getShort() != TFTP_RRQ) {			DatagramPacket error = new DatagramPacket(new byte[MTU], MTU);			ByteBuffer rbuf = ByteBuffer.wrap(error.getData());			rbuf.putShort(TFTP_ERROR).putShort(ERR_ILLOP).put("Illegal operation".getBytes());			error.setLength(rbuf.position());			try {				s.send(error);			} catch (Exception e) {				log.info(e.toString(), e);			}			return;		}		// fork thread		new Thread(new T2hproxy(r.getAddress(), r.getPort(), r.getData(), prefix, proxy, timeout)).start();	}	/**	 *  The main program for the T2hproxy class	 *	 *@param  argv             The command line arguments	 *@exception  IOException  Description of the Exception	 */	public static void main(String[] argv) throws IOException {		log.info(T2hproxy.NAME + "." + T2hproxy.VERSION);		int port = Integer.getInteger(T2hproxy.NAME + ".port", 69).intValue();		String prefix = System.getProperty(T2hproxy.NAME + ".prefix", "http://localhost/");		String proxy = System.getProperty(T2hproxy.NAME + ".proxy");		int timeout = Integer.getInteger(T2hproxy.NAME + ".timeout", 5000).intValue();		String propfile = System.getProperty(T2hproxy.NAME + ".properties");		if (propfile != null) {			FileInputStream pf = new FileInputStream(propfile);			Properties p = new Properties(System.getProperties());			p.load(pf);			// set the system properties			System.setProperties(p);		}		DatagramSocket requestsocket;		try {			requestsocket = new DatagramSocket(port);		} catch (SocketException e) {			log.info(e.toString(), e);			return;		}		DatagramPacket request = new DatagramPacket(new byte[MTU], MTU);		for (; ; ) {			try {				requestsocket.receive(request);				handleRequest(requestsocket, request, prefix, proxy, timeout);			} catch (Exception e) {				log.info(e.toString(), e);			}		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -