summaryrefslogtreecommitdiff
path: root/com32/sysdump/be_tftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/sysdump/be_tftp.c')
-rw-r--r--com32/sysdump/be_tftp.c178
1 files changed, 0 insertions, 178 deletions
diff --git a/com32/sysdump/be_tftp.c b/com32/sysdump/be_tftp.c
deleted file mode 100644
index 36a91eb8..00000000
--- a/com32/sysdump/be_tftp.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * TFTP data output backend
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <syslinux/pxe.h>
-#include <syslinux/config.h>
-#include <netinet/in.h>
-#include <sys/times.h>
-
-#include "backend.h"
-
-enum tftp_opcode {
- TFTP_RRQ = 1,
- TFTP_WRQ = 2,
- TFTP_DATA = 3,
- TFTP_ACK = 4,
- TFTP_ERROR = 5,
-};
-
-struct tftp_state {
- uint32_t my_ip;
- uint32_t srv_ip;
- uint32_t srv_gw;
- uint16_t my_port;
- uint16_t srv_port;
- uint16_t seq;
-};
-
-#define RCV_BUF 2048
-
-static int send_ack_packet(struct tftp_state *tftp,
- const void *pkt, size_t len)
-{
- com32sys_t ireg, oreg;
- t_PXENV_UDP_WRITE *uw;
- t_PXENV_UDP_READ *ur;
- clock_t start;
- static const clock_t timeouts[] = {
- 2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 15, 18, 21, 26, 31,
- 37, 44, 53, 64, 77, 92, 110, 132, 159, 191, 229, 0
- };
- const clock_t *timeout;
- int err = -1;
-
- uw = lmalloc(sizeof *uw + len);
- ur = lmalloc(sizeof *ur + RCV_BUF);
-
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.w[0] = 0x0009;
-
- for (timeout = timeouts ; *timeout ; timeout++) {
- memset(uw, 0, sizeof uw);
- memcpy(uw+1, pkt, len);
- uw->ip = tftp->srv_ip;
- uw->gw = tftp->srv_gw;
- uw->src_port = tftp->my_port;
- uw->dst_port = tftp->srv_port ? tftp->srv_port : htons(69);
- uw->buffer_size = len;
- uw->buffer = FAR_PTR(uw+1);
-
- ireg.ebx.w[0] = PXENV_UDP_WRITE;
- ireg.es = SEG(uw);
- ireg.edi.w[0] = OFFS(uw);
-
- __intcall(0x22, &ireg, &oreg);
-
- start = times(NULL);
-
- do {
- memset(ur, 0, sizeof ur);
- ur->src_ip = tftp->srv_ip;
- ur->dest_ip = tftp->my_ip;
- ur->s_port = tftp->srv_port;
- ur->d_port = tftp->my_port;
- ur->buffer_size = RCV_BUF;
- ur->buffer = FAR_PTR(ur+1);
-
- ireg.ebx.w[0] = PXENV_UDP_READ;
- ireg.es = SEG(ur);
- ireg.edi.w[0] = OFFS(ur);
- __intcall(0x22, &ireg, &oreg);
-
- if (!(oreg.eflags.l & EFLAGS_CF) &&
- ur->status == PXENV_STATUS_SUCCESS &&
- tftp->srv_ip == ur->src_ip &&
- (tftp->srv_port == 0 ||
- tftp->srv_port == ur->s_port)) {
- uint16_t *xb = (uint16_t *)(ur+1);
- if (ntohs(xb[0]) == TFTP_ACK &&
- ntohs(xb[1]) == tftp->seq) {
- tftp->srv_port = ur->s_port;
- err = 0; /* All good! */
- goto done;
- } else if (ntohs(xb[1]) == TFTP_ERROR) {
- goto done;
- }
- }
- } while ((clock_t)(times(NULL) - start) < *timeout);
- }
-
-done:
- lfree(ur);
- lfree(uw);
-
- return err;
-}
-
-static int be_tftp_write(struct backend *be)
-{
- static uint16_t local_port = 0x4000;
- struct tftp_state tftp;
- char buffer[512+4+6];
- int nlen;
- const union syslinux_derivative_info *sdi =
- syslinux_derivative_info();
- const char *data = be->outbuf;
- size_t len = be->zbytes;
- size_t chunk;
-
- tftp.my_ip = sdi->pxe.myip;
- tftp.my_port = htons(local_port++);
- tftp.srv_gw = ((tftp.srv_ip ^ tftp.my_ip) & sdi->pxe.ipinfo->netmask)
- ? sdi->pxe.ipinfo->gateway : 0;
- tftp.srv_port = 0;
- tftp.seq = 0;
-
- if (be->argv[1]) {
- tftp.srv_ip = pxe_dns(be->argv[1]);
- if (!tftp.srv_ip) {
- printf("\nUnable to resolve hostname: %s\n", be->argv[1]);
- return -1;
- }
- } else {
- tftp.srv_ip = sdi->pxe.ipinfo->serverip;
- if (!tftp.srv_ip) {
- printf("\nNo server IP address\n");
- return -1;
- }
- }
-
- printf("server %u.%u.%u.%u... ",
- ((uint8_t *)&tftp.srv_ip)[0],
- ((uint8_t *)&tftp.srv_ip)[1],
- ((uint8_t *)&tftp.srv_ip)[2],
- ((uint8_t *)&tftp.srv_ip)[3]);
-
- buffer[0] = 0;
- buffer[1] = TFTP_WRQ;
- nlen = strlcpy(buffer+2, be->argv[0], 512);
- memcpy(buffer+3+nlen, "octet", 6);
-
- if (send_ack_packet(&tftp, buffer, 2+nlen+1+6))
- return -1;
-
- do {
- chunk = len >= 512 ? 512 : len;
-
- buffer[1] = TFTP_DATA;
- *((uint16_t *)(buffer+2)) = htons(++tftp.seq);
- memcpy(buffer+4, data, chunk);
- data += chunk;
- len -= chunk;
-
- if (send_ack_packet(&tftp, buffer, chunk+4))
- return -1;
- } while (chunk == 512);
-
- return 0;
-}
-
-struct backend be_tftp = {
- .name = "tftp",
- .helpmsg = "filename [tftp_server]",
- .minargs = 1,
- .write = be_tftp_write,
-};