summaryrefslogtreecommitdiffstats
path: root/contrib/t2hproxy
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/t2hproxy')
-rw-r--r--contrib/t2hproxy/README95
-rw-r--r--contrib/t2hproxy/T2hproxy.java508
-rw-r--r--contrib/t2hproxy/build.xml19
-rwxr-xr-xcontrib/t2hproxy/runT2proxy.sh15
-rwxr-xr-xcontrib/t2hproxy/t2hproxy.pl174
-rw-r--r--contrib/t2hproxy/t2hproxy.xinetd29
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
-}