diff options
Diffstat (limited to 'contrib/t2hproxy')
-rw-r--r-- | contrib/t2hproxy/README | 95 | ||||
-rw-r--r-- | contrib/t2hproxy/T2hproxy.java | 508 | ||||
-rw-r--r-- | contrib/t2hproxy/build.xml | 19 | ||||
-rwxr-xr-x | contrib/t2hproxy/runT2proxy.sh | 15 | ||||
-rwxr-xr-x | contrib/t2hproxy/t2hproxy.pl | 174 | ||||
-rw-r--r-- | contrib/t2hproxy/t2hproxy.xinetd | 29 |
6 files changed, 0 insertions, 840 deletions
diff --git a/contrib/t2hproxy/README b/contrib/t2hproxy/README deleted file mode 100644 index ce5e1e9b..00000000 --- a/contrib/t2hproxy/README +++ /dev/null @@ -1,95 +0,0 @@ -T2hproxy - -This is a TFTP to HTTP proxy. To the TFTP client it looks like a TFTP -server. To the HTTP server it looks like a HTTP client. So you can store -your boot files on the HTTP server. Or even create them with a CGI -program. E.g. if you can get dhcpd to send a filename which has strings -representing attributes of the client, as determined from the DHCP -request, then you can get the CGI program to parse this and send the -appropriate image, which might even be synthesised. - -There are two versions of the proxy, in Perl and in Java. - -1. The Perl version. - -This is the original quick Perl hack conceived in a moment of madness. -:-) Perl is great for prototyping. - -To run it, you need Perl 5.8.0 or later and all the Perl modules listed -at the top of the program installed. Edit and install the xinetd config -file as /etc/xinetd.d/t2hproxy and restart xinetd. The prefix is the -string that is prepended to all filenames to form the URL requested from -the HTTP server. Remember you need the trailing / if the filenames don't -start with /. - -This is only a proof-of concept. It has these drawbacks at the moment: - -+ (I don't consider this a draback, but some may.) It's started from -xinetd because xinetd handles all the socket listening, IP address -checking, rate limiting, etc. - -+ It has no cache. Use a proxy to do the caching (there's a --proxy -option). This also takes care of fetching from outside a firewall. - -+ It reads the entire HTTP content into memory before serving. Ideally -it should stream it from the HTTP server to minimise memory usage. This -is a serious drawback for booting lots of clients. Each instance of the -server will consume an amount of memory equal to the size of image -loaded. - -+ If the HTTP server is at the end of a slow link there is a delay -before the first data block is sent. The client may timeout before -then. Another reason for streaming, as this allows the first block to -be sent sooner. A local cache primed with the images in advance may -help. Using the blocksize option helps here because this causes the -server to send the OACK to the client immediately before the data is -fetched and this prevents it from starting up another connection. - -+ The transfer size may not be obtainable from the HTTP headers in all -cases, e.g. a CGI constructed image. This matters for clients that need -the tsize extension, which is not supported at the moment. - -If I'm feeling masochistic I may write a Java version, which should take -care of the multi-threading and streaming. - -2. The Java version - -The main problem with the Perl version is that it does not stream the -HTTP input but sucks it all in at once. As mentioned, this causes a -delay as well as requiring memory to hold the image. I could fix this by -doing the polling on the HTTP socket myself instead of letting LWP do -it, but that's for later. Java has streaming facilities as well as -threading and is also somewhat portable. So I decided to be masochistic -and give it a go. But boy is Java bureaucratic. - -You will need a Java 1.4 JRE, because I use the java.nio classes; and -the commons-httpclient and commons-logging jars from the -jakarta.apache.org project. As I understand it, there are several ways -to get those jars on your classpath. One is to put it in the directory -where your java extensions jars are kept, normally -$JAVA_HOME/jre/lib/ext. But it may not be writable to you. Another is to -set your $CLASSPATH variable to have those jars in the path. A third is -to use the -cp option of the java interpreter, see the shell script -runT2hproxy for details. - -All the source is in one Java file. build.xml is a "Makefile" for ant to -compile and jar it. You should then edit runT2proxy.sh as required, then -start it. As with the Perl version, the prefix is what's prepended to -the filenames requested by the TFTP client, and the proxy is the -host:port string for the proxy if you are using one. On *ix you will -need root permission to listen on ports below 1024 (TFTP is at 69 UDP by -default). - -Currently it logs to stderr, but you can change this by downloading and -installing the log4j jar from jakarta.apache.org and instructing -commons-logging to use that, with a command line property setting and a -property file. Destinations could be syslog, or a file, or an event -logger, or...; it's supposedly very flexible. - -3. Licensing - -All this code is GPLed. For details read the file COPYING found in the -Etherboot top directory since it currently bundled with Etherboot. I -don't see the point of including COPYING in every directory. - -Ken Yap, October 2003 diff --git a/contrib/t2hproxy/T2hproxy.java b/contrib/t2hproxy/T2hproxy.java deleted file mode 100644 index cfe1d1a7..00000000 --- a/contrib/t2hproxy/T2hproxy.java +++ /dev/null @@ -1,508 +0,0 @@ -/* - * 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); - } - } - } -} diff --git a/contrib/t2hproxy/build.xml b/contrib/t2hproxy/build.xml deleted file mode 100644 index 5494ab96..00000000 --- a/contrib/t2hproxy/build.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<!-- - Build file for T2hproxy ---> -<project name="T2hproxy" default="jar" basedir="."> - <target name="compile"> - <javac fork="true" srcdir="." destdir="." /> - </target> - - <target name="jar" depends="compile"> - <jar jarfile="T2hproxy.jar" basedir="." - includes="T2hproxy.class"> - <manifest> - <attribute name="Main-Class" value="T2hproxy" /> - </manifest> - </jar> - </target> -</project> - diff --git a/contrib/t2hproxy/runT2proxy.sh b/contrib/t2hproxy/runT2proxy.sh deleted file mode 100755 index d7fc0d2d..00000000 --- a/contrib/t2hproxy/runT2proxy.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# If the httpclient and logging jars are not in the standard directories -# edit and uncomment -# CP='-cp /usr/local/lib/commons-httpclient-2.0-rc1.jar:/usr/local/lib/commons-logging-api.jar:/usr/local/lib/commons-logging.jar' - -# Edit and uncomment to use an alternate port -# PORT='-DT2hproxy.port=1069' -PREFIX='-DT2hproxy.prefix=http://localhost/' -# Edit and uncomment to use a proxy -# PROXY='-DT2hproxy.proxy=localhost:3128' -# These T2hproxy properties can be put in a file and read in all at once -# PROPERTIES='-DT2hproxy.properties=t2hproxy.prop - -exec java -jar $CP $PORT $PREFIX $PROXY $PROPERTIES T2hproxy.jar diff --git a/contrib/t2hproxy/t2hproxy.pl b/contrib/t2hproxy/t2hproxy.pl deleted file mode 100755 index 4fc01781..00000000 --- a/contrib/t2hproxy/t2hproxy.pl +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl -w -# -# tftp to http proxy -# Copyright 2003 Ken Yap -# Released under GPL2 -# - -require 5.8.0; # needs constant and the pack Z format behaviour - -use bytes; # to forestall Unicode interpretation of strings -use strict; - -use Getopt::Long; -use Socket; -use Sys::Hostname; -use Sys::Syslog; -use LWP; -use POSIX 'setsid'; - -use constant PROGNAME => 't2hproxy'; -use constant VERSION => '0.1'; - -use constant ETH_DATA_LEN => 1500; -use constant { - TFTP_RRQ => 1, TFTP_WRQ => 2, TFTP_DATA => 3, TFTP_ACK => 4, - TFTP_ERROR => 5, TFTP_OACK => 6 -}; -use constant { - E_UNDEF => 0, E_FNF => 1, E_ACC => 2, E_DISK => 3, E_ILLOP => 4, - E_UTID => 5, E_FEXIST => 6, E_NOUSER => 7 -}; - -use vars qw($prefix $proxy $sockh $timeout %options $tsize $bsize); - -# We can't use die because xinetd will think something's wrong -sub log_and_exit ($) { - syslog('info', $_[0]); - exit; -} - -sub what_source ($) { - my ($port, $saddr) = sockaddr_in($_[0]); - my $host = gethostbyaddr($saddr, AF_INET); - return ($host, $port); -} - -sub send_error ($$$) { - my ($iaddr, $error, $message) = @_; - # error packets don't get acked - send(STDOUT, pack('nna*', TFTP_ERROR, $error, $message), 0, $iaddr); -} - -sub send_ack_retry ($$$$$) { - my ($iaddr, $udptimeout, $maxretries, $blockno, $sendfunc) = @_; -RETRY: - while ($maxretries-- > 0) { - &$sendfunc; - my $rin = ''; - my $rout = ''; - vec($rin, fileno($sockh), 1) = 1; - do { - my ($fds, $timeleft) = select($rout = $rin, undef, undef, $udptimeout); - last if ($fds <= 0); - my $ack; - my $theiripaddr = recv($sockh, $ack, 256, 0); - # check it's for us - if ($theiripaddr eq $iaddr) { - my ($opcode, $ackblock) = unpack('nn', $ack); - return (0) if ($opcode == TFTP_ERROR); - # check that the right block was acked - if ($ackblock == $blockno) { - return (1); - } else { - syslog('info', "Resending block $blockno"); - next RETRY; - } - } - # stray packet for some other server instance - send_error($theiripaddr, E_UTID, 'Wrong TID'); - } while (1); - } - return (0); -} - -sub handle_options ($$) { - my ($iaddr, $operand) = @_; - while ($operand ne '') { - my ($key, $value) = unpack('Z*Z*', $operand); - $options{$key} = $value; - syslog('info', "$key=$value"); - $operand = substr($operand, length($key) + length($value) + 2); - } - my $optstr = ''; - if (exists($options{blksize})) { - $bsize = $options{blksize}; - $bsize = 512 if ($bsize < 512); - $bsize = 1432 if ($bsize > 1432); - $optstr .= pack('Z*Z*', 'blksize', $bsize . ''); - } - # OACK expects an ack for block 0 - log_and_exit('Abort received or retransmit limit reached, exiting') - unless send_ack_retry($iaddr, 2, 5, 0, - sub { send($sockh, pack('na*', TFTP_OACK, $optstr), 0, $iaddr); }); -} - -sub http_get ($) { - my ($url) = @_; - syslog('info', "GET $url"); - my $ua = LWP::UserAgent->new; - $ua->timeout($timeout); - $ua->proxy(['http', 'ftp'], $proxy) if (defined($proxy) and $proxy); - my $req = HTTP::Request->new(GET => $url); - my $res = $ua->request($req); - return ($res->is_success, $res->status_line, $res->content_ref); -} - -sub send_file ($$) { - my ($iaddr, $contentref) = @_; - my $blockno = 1; - my $data; - do { - $blockno &= 0xffff; - $data = substr($$contentref, ($blockno - 1) * $bsize, $bsize); - # syslog('info', "Block $blockno length " . length($data)); - log_and_exit('Abort received or retransmit limit reached, exiting') - unless send_ack_retry($iaddr, 2, 5, $blockno, - sub { send($sockh, pack('nna*', TFTP_DATA, $blockno, $data), 0, $iaddr); }); - $blockno++; - } while (length($data) >= $bsize); -} - -sub do_rrq ($$) { - my ($iaddr, $packetref) = @_; - # fork and handle request in child so that *inetd can continue - # to serve incoming requests - defined(my $pid = fork) or log_and_exit("Can't fork: $!"); - exit if $pid; # parent exits - setsid or log_and_exit("Can't start a new session: $!"); - socket(SOCK, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or log_and_exit('Cannot create UDP socket'); - $sockh = *SOCK{IO}; - my ($opcode, $operand) = unpack('na*', $$packetref); - my ($filename, $mode) = unpack('Z*Z*', $operand); - syslog('info', "RRQ $filename $mode"); - my $length = length($filename) + length($mode) + 2; - $operand = substr($operand, $length); - handle_options($iaddr, $operand) if ($operand ne ''); - my ($success, $status_line, $result) = http_get($prefix . $filename); - syslog('info', $status_line); - if ($success) { - send_file($iaddr, $result); - } else { - send_error($iaddr, E_FNF, $status_line); - } -} - -$prefix = 'http://localhost/'; -$timeout = 60; -GetOptions('prefix=s' => \$prefix, - 'proxy=s' => \$proxy, - 'timeout=i' => \$timeout); -$bsize = 512; -openlog(PROGNAME, 'cons,pid', 'user'); -syslog('info', PROGNAME . ' version ' . VERSION); -my $packet; -my $theiriaddr = recv(STDIN, $packet, ETH_DATA_LEN, 0); -my ($host, $port) = what_source($theiriaddr); -syslog('info', "Connection from $host:$port"); -my $opcode = unpack('n', $packet); -if ($opcode == TFTP_RRQ) { - do_rrq($theiriaddr, \$packet); -} else { # anything else is an error - send_error($theiriaddr, E_ILLOP, 'Illegal operation'); -} -exit 0; diff --git a/contrib/t2hproxy/t2hproxy.xinetd b/contrib/t2hproxy/t2hproxy.xinetd deleted file mode 100644 index ea6a03f1..00000000 --- a/contrib/t2hproxy/t2hproxy.xinetd +++ /dev/null @@ -1,29 +0,0 @@ -# Description: tftp to http proxy -# A sample config file for xinetd, edit and put in /etc/xinetd.d -# then killall -HUP xinetd, or restart xinetd - -service t2hproxy -{ - type = UNLISTED - id = t2hproxy - socket_type = dgram - protocol = udp -# -# The pathname to where you have installed it -# - server = /usr/local/sbin/t2hproxy.pl -# -# If your filenames don't start with /, then the trailing -# slash is needed -# - server_args = --prefix http://localhost/ -# -# --proxy http://proxyhost:3128/ can also be appended -# - log_type = FILE /var/log/t2hproxy.log - user = nobody - wait = yes - instances = 10 - disable = no - port = 69 -} |