/*
 * tftp.c - a simple, read-only tftp server for qemu
 *
 * Copyright (c) 2004 Magnus Damm <damm@opensource.se>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <slirp.h>
#include "qemu-common.h" // for pstrcpy

struct tftp_session {
    int in_use;
    unsigned char filename[TFTP_FILENAME_MAX];

    uint32_t client_ip;
    uint16_t client_port;

    int timestamp;
};

static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];

const char *tftp_prefix;

static void tftp_session_update(struct tftp_session *spt)
{
    spt->timestamp = curtime;
    spt->in_use = 1;
}

static void tftp_session_terminate(struct tftp_session *spt)
{
  spt->in_use = 0;
}

static int tftp_session_allocate(struct tftp_t *tp)
{
  struct tftp_session *spt;
  int k;

  for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
    spt = &tftp_sessions[k];

    if (!spt->in_use)
        goto found;

    /* sessions time out after 5 inactive seconds */
    if ((int)(curtime - spt->timestamp) > 5000)
        goto found;
  }

  return -1;

 found:
  memset(spt, 0, sizeof(*spt));
  spt->client_ip   = ip_geth(tp->ip.ip_src);
  spt->client_port = port_geth(tp->udp.uh_sport);

  tftp_session_update(spt);

  return k;
}

static int tftp_session_find(struct tftp_t *tp)
{
  struct tftp_session *spt;
  int k;

  for (k = 0; k < TFTP_SESSIONS_MAX; k++) {
    spt = &tftp_sessions[k];

    if (spt->in_use) {
      if (spt->client_ip == ip_geth(tp->ip.ip_src)) {
		if (spt->client_port == port_geth(tp->udp.uh_sport)) {
		  return k;
		}
      }
    }
  }

  return -1;
}

static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr,
			  u_int8_t *buf, int len)
{
  int fd;
  int bytes_read = 0;
  char buffer[1024];
  int n;

  n = snprintf(buffer, sizeof(buffer), "%s/%s",
	       tftp_prefix, spt->filename);
  if (n >= sizeof(buffer))
    return -1;

  fd = open(buffer, O_RDONLY | O_BINARY);

  if (fd < 0) {
    return -1;
  }

  if (len) {
    lseek(fd, block_nr * 512, SEEK_SET);

    bytes_read = read(fd, buf, len);
  }

  close(fd);

  return bytes_read;
}

static int tftp_send_oack(struct tftp_session *spt,
                          const char *key, uint32_t value,
                          struct tftp_t *recv_tp)
{
    SockAddress  saddr, daddr;
    struct mbuf *m;
    struct tftp_t *tp;
    int n = 0;

    m = m_get();

    if (!m)
	return -1;

    memset(m->m_data, 0, m->m_size);

    m->m_data += IF_MAXLINKHDR;
    tp = (void *)m->m_data;
    m->m_data += sizeof(struct udpiphdr);

    tp->tp_op = htons(TFTP_OACK);
    n += snprintf((char *)tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s",
                  key) + 1;
    n += snprintf((char *)tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u",
                  value) + 1;

    sock_address_init_inet( &saddr,
                            ip_geth(recv_tp->ip.ip_dst),
                            port_geth(recv_tp->udp.uh_dport) );

    sock_address_init_inet( &daddr,
                            spt->client_ip,
                            spt->client_port );

    m->m_len = sizeof(struct tftp_t) - 514 + n -
        sizeof(struct ip) - sizeof(struct udphdr);
    udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);

    return 0;
}



static int tftp_send_error(struct tftp_session *spt,
			   u_int16_t errorcode, const char *msg,
			   struct tftp_t *recv_tp)
{
  SockAddress saddr, daddr;
  struct mbuf *m;
  struct tftp_t *tp;
  int nobytes;

  m = m_get();

  if (!m) {
    return -1;
  }

  memset(m->m_data, 0, m->m_size);

  m->m_data += IF_MAXLINKHDR;
  tp = (void *)m->m_data;
  m->m_data += sizeof(struct udpiphdr);

  tp->tp_op = htons(TFTP_ERROR);
  tp->x.tp_error.tp_error_code = htons(errorcode);
  pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);

  sock_address_init_inet( &saddr,
                          ip_geth(recv_tp->ip.ip_dst),
                          port_geth(recv_tp->udp.uh_dport) );

  sock_address_init_inet( &daddr,
                          spt->client_ip,
                          spt->client_port );

  nobytes = 2;

  m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
        sizeof(struct ip) - sizeof(struct udphdr);

  udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);

  tftp_session_terminate(spt);

  return 0;
}

static int tftp_send_data(struct tftp_session *spt,
			  u_int16_t block_nr,
			  struct tftp_t *recv_tp)
{
  SockAddress saddr, daddr;
  struct mbuf *m;
  struct tftp_t *tp;
  int nobytes;

  if (block_nr < 1) {
    return -1;
  }

  m = m_get();

  if (!m) {
    return -1;
  }

  memset(m->m_data, 0, m->m_size);

  m->m_data += IF_MAXLINKHDR;
  tp = (void *)m->m_data;
  m->m_data += sizeof(struct udpiphdr);

  tp->tp_op = htons(TFTP_DATA);
  tp->x.tp_data.tp_block_nr = htons(block_nr);

  sock_address_init_inet( &saddr,
                          ip_geth(recv_tp->ip.ip_dst),
                          port_geth(recv_tp->udp.uh_dport) );

  sock_address_init_inet( &daddr,
                          spt->client_ip,
                          spt->client_port );

  nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512);

  if (nobytes < 0) {
    m_free(m);

    /* send "file not found" error back */

    tftp_send_error(spt, 1, "File not found", tp);

    return -1;
  }

  m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
        sizeof(struct ip) - sizeof(struct udphdr);

  udp_output2_(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);

  if (nobytes == 512) {
    tftp_session_update(spt);
  }
  else {
    tftp_session_terminate(spt);
  }

  return 0;
}

static void tftp_handle_rrq(struct tftp_t *tp, int pktlen)
{
  struct tftp_session *spt;
  int s, k, n;
  u_int8_t *src, *dst;

  s = tftp_session_allocate(tp);

  if (s < 0) {
    return;
  }

  spt = &tftp_sessions[s];

  src = tp->x.tp_buf;
  dst = spt->filename;
  n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp);

  /* get name */

  for (k = 0; k < n; k++) {
    if (k < TFTP_FILENAME_MAX) {
      dst[k] = src[k];
    }
    else {
      return;
    }

    if (src[k] == '\0') {
      break;
    }
  }

  if (k >= n) {
    return;
  }

  k++;

  /* check mode */
  if ((n - k) < 6) {
    return;
  }

  if (memcmp(&src[k], "octet\0", 6) != 0) {
      tftp_send_error(spt, 4, "Unsupported transfer mode", tp);
      return;
  }

  k += 6; /* skipping octet */

  /* do sanity checks on the filename */

  if ((spt->filename[0] != '/')
      || (spt->filename[strlen((char *)spt->filename) - 1] == '/')
      ||  strstr((char *)spt->filename, "/../")) {
      tftp_send_error(spt, 2, "Access violation", tp);
      return;
  }

  /* only allow exported prefixes */

  if (!tftp_prefix) {
      tftp_send_error(spt, 2, "Access violation", tp);
      return;
  }

  /* check if the file exists */

  if (tftp_read_data(spt, 0, spt->filename, 0) < 0) {
      tftp_send_error(spt, 1, "File not found", tp);
      return;
  }

  if (src[n - 1] != 0) {
      tftp_send_error(spt, 2, "Access violation", tp);
      return;
  }

  while (k < n) {
      const char *key, *value;

      key = (char *)src + k;
      k += strlen(key) + 1;

      if (k >= n) {
	  tftp_send_error(spt, 2, "Access violation", tp);
	  return;
      }

      value = (char *)src + k;
      k += strlen(value) + 1;

      if (strcmp(key, "tsize") == 0) {
	  int tsize = atoi(value);
	  struct stat stat_p;

	  if (tsize == 0 && tftp_prefix) {
	      char buffer[1024];
	      int len;

	      len = snprintf(buffer, sizeof(buffer), "%s/%s",
			     tftp_prefix, spt->filename);

	      if (stat(buffer, &stat_p) == 0)
		  tsize = stat_p.st_size;
	      else {
		  tftp_send_error(spt, 1, "File not found", tp);
		  return;
	      }
	  }

	  tftp_send_oack(spt, "tsize", tsize, tp);
      }
  }

  tftp_send_data(spt, 1, tp);
}

static void tftp_handle_ack(struct tftp_t *tp, int pktlen)
{
  int s;

  s = tftp_session_find(tp);

  if (s < 0) {
    return;
  }

  if (tftp_send_data(&tftp_sessions[s],
		     ntohs(tp->x.tp_data.tp_block_nr) + 1,
		     tp) < 0) {
    return;
  }
}

void tftp_input(struct mbuf *m)
{
  struct tftp_t *tp = (struct tftp_t *)m->m_data;

  switch(ntohs(tp->tp_op)) {
  case TFTP_RRQ:
    tftp_handle_rrq(tp, m->m_len);
    break;

  case TFTP_ACK:
    tftp_handle_ack(tp, m->m_len);
    break;
  }
}
