/* tftp.c - TFTP client.
 *
 * Copyright 2012 Madhur Verma <mad.flexi@gmail.com>
 * Copyright 2015 Sameer Prakash Pradhan <sameer.p.pradhan@gmail.com>
 *
 * No Standard.

USE_TFTP(NEWTOY(tftp, "<1b#<8>65464r:l:g|p|[!gp]", TOYFLAG_USR|TOYFLAG_BIN))

config TFTP
  bool "tftp"
  default n
  help
    usage: tftp [OPTIONS] HOST [PORT]

    Transfer file from/to tftp server.

    -l FILE Local FILE
    -r FILE Remote FILE
    -g    Get file
    -p    Put file
    -b SIZE Transfer blocks of SIZE octets(8 <= SIZE <= 65464)
*/
#define FOR_tftp
#include "toys.h"

GLOBALS(
  char *local_file;
  char *remote_file;
  long block_size;

  struct sockaddr_storage inaddr;
  int af;
)

#define TFTP_BLKSIZE    512
#define TFTP_RETRIES    3
#define TFTP_DATAHEADERSIZE 4
#define TFTP_MAXPACKETSIZE  (TFTP_DATAHEADERSIZE + TFTP_BLKSIZE)
#define TFTP_PACKETSIZE    TFTP_MAXPACKETSIZE
#define TFTP_DATASIZE    (TFTP_PACKETSIZE-TFTP_DATAHEADERSIZE)
#define TFTP_IOBUFSIZE    (TFTP_PACKETSIZE+8)

#define TFTP_OP_RRQ      1  /* Read Request      RFC 1350, RFC 2090 */
#define TFTP_OP_WRQ      2  /* Write Request     RFC 1350 */
#define TFTP_OP_DATA    3  /* Data chunk      RFC 1350 */
#define TFTP_OP_ACK      4  /* Acknowledgement     RFC 1350 */
#define TFTP_OP_ERR      5  /* Error Message     RFC 1350 */
#define TFTP_OP_OACK    6  /* Option acknowledgment RFC 2347 */

#define TFTP_ER_ILLEGALOP  4  /* Illegal TFTP operation */
#define TFTP_ER_UNKID    5  /* Unknown transfer ID */

#define TFTP_ES_NOSUCHFILE  "File not found"
#define TFTP_ES_ACCESS    "Access violation"
#define TFTP_ES_FULL    "Disk full or allocation exceeded"
#define TFTP_ES_ILLEGALOP  "Illegal TFTP operation"
#define TFTP_ES_UNKID    "Unknown transfer ID"
#define TFTP_ES_EXISTS    "File already exists"
#define TFTP_ES_UNKUSER    "No such user"
#define TFTP_ES_NEGOTIATE  "Terminate transfer due to option negotiation"

// Initializes SERVER with ADDR and returns socket.
static int init_tftp(struct sockaddr_storage *server)
{
  struct timeval to = { .tv_sec = 10, //Time out
                        .tv_usec = 0 };
  const int set = 1;
  int port = 69, sd = xsocket(TT.af, SOCK_DGRAM, IPPROTO_UDP);

  xsetsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (void *)&to, sizeof(struct timeval));
  xsetsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (void *)&set, sizeof(set));

  if(toys.optc == 2) port = atolx_range(toys.optargs[1], 1, 65535);
  memset(server, 0, sizeof(struct sockaddr_storage));
  if (TT.af == AF_INET6) {
      ((struct sockaddr_in6 *)server)->sin6_family = AF_INET6;
      ((struct sockaddr_in6 *)server)->sin6_addr =
        ((struct sockaddr_in6 *)&TT.inaddr)->sin6_addr;
      ((struct sockaddr_in6 *)server)->sin6_port = htons(port);
  }
  else {
      ((struct sockaddr_in *)server)->sin_family = AF_INET;
      ((struct sockaddr_in *)server)->sin_addr.s_addr =
        ((struct sockaddr_in *)&TT.inaddr)->sin_addr.s_addr;
      ((struct sockaddr_in *)server)->sin_port = htons(port);
  }
  return sd;
}

/*
 * Makes a request packet in BUFFER with OPCODE and file PATH of MODE
 * and returns length of packet.
 */
static int mkpkt_request(uint8_t *buffer, int opcode, char *path, int mode)
{
  buffer[0] = opcode >> 8;
  buffer[1] = opcode & 0xff;
  if(strlen(path) > TFTP_BLKSIZE) error_exit("path too long");
  return sprintf((char*) &buffer[2], "%s%c%s", path, 0, 
    (mode ? "octet" : "netascii")) + 3;
}

/*
 * Makes an acknowledgement packet in BUFFER of BLOCNO
 * and returns packet length.
 */
static int mkpkt_ack(uint8_t *buffer, uint16_t blockno)
{
  buffer[0] = TFTP_OP_ACK >> 8;
  buffer[1] = TFTP_OP_ACK & 0xff;
  buffer[2] = blockno >> 8;
  buffer[3] = blockno & 0xff;
  return 4;
}

/*
 * Makes an error packet in BUFFER with ERRORCODE and ERRORMSG.
 * and returns packet length.
 */
static int mkpkt_err(uint8_t *buffer, uint16_t errorcode, char *errormsg)
{
  buffer[0] = TFTP_OP_ERR >> 8;
  buffer[1] = TFTP_OP_ERR & 0xff;
  buffer[2] = errorcode >> 8;
  buffer[3] = errorcode & 0xff;
  strcpy((char*) &buffer[4], errormsg);
  return strlen(errormsg) + 5;
}

/*
 * Recieves data from server in BUFF with socket SD and updates FROM
 * and returns read length.
 */
static ssize_t read_server(int sd, void *buf, size_t len,
  struct sockaddr_storage *from)
{
  socklen_t alen;
  ssize_t nb;
  
  for (;;) {
    memset(buf, 0, len);
    alen = sizeof(struct sockaddr_storage);
    nb = recvfrom(sd, buf, len, 0, (struct sockaddr *) from, &alen);
    if (nb < 0) {
      if (errno == EAGAIN) {
        perror_msg("server read timed out");
        return nb;
      }else if (errno != EINTR) {
        perror_msg("server read failed");
        return nb;
      }
    }else return nb;
  }
  return nb;
}

/*
 * sends data to server TO from BUFF of length LEN through socket SD
 * and returns successfully send bytes number.
 */
static ssize_t write_server(int sd, void *buf, size_t len,
  struct sockaddr_storage *to)
{
  ssize_t nb;
  
  for (;;) {
    nb = sendto(sd, buf, len, 0, (struct sockaddr *)to,
            sizeof(struct sockaddr_storage));
    if (nb < 0) {
      if (errno != EINTR) {
        perror_msg("server write failed");
        return nb;
      }
    } else return nb;
  }
  return nb;
}

// checks packet for data and updates block no
static inline int check_data( uint8_t *packet, uint16_t *opcode, 
  uint16_t *blockno)
{
  *opcode = (uint16_t) packet[0] << 8 | (uint16_t) packet[1];
  if (*opcode == TFTP_OP_DATA) {
    *blockno = (uint16_t) packet[2] << 8 | (uint16_t) packet[3];
    return 0;
  }
  return -1;
}

// Makes data packet through FD from file OFFSET in buffer PACKET of BLOCKNO
static int mkpkt_data(int fd, off_t offset, uint8_t *packet, uint16_t blockno)
{
  off_t tmp;
  int nbytesread;

  packet[0] = TFTP_OP_DATA >> 8;
  packet[1] = TFTP_OP_DATA & 0xff;
  packet[2] = blockno >> 8;
  packet[3] = blockno & 0xff;
  tmp = lseek(fd, offset, SEEK_SET);
  if (tmp == (off_t) -1) {
    perror_msg("lseek failed");
    return -1;
  }
  nbytesread = readall(fd, &packet[TFTP_DATAHEADERSIZE], TFTP_DATASIZE);
  if (nbytesread < 0) return -1;
  return nbytesread + TFTP_DATAHEADERSIZE;
}

// Receives ACK responses from server and updates blockno
static int read_ack(int sd, uint8_t *packet, struct sockaddr_storage *server,
  uint16_t *port, uint16_t *blockno)
{
  struct sockaddr_storage from;
  ssize_t nbytes;
  uint16_t opcode, rblockno;
  int packetlen, retry;

  for (retry = 0; retry < TFTP_RETRIES; retry++) {
    for (;;) {
      nbytes = read_server(sd, packet, TFTP_IOBUFSIZE, &from);
      if (nbytes < 4) { // Ack headersize = 4
        if (nbytes == 0) error_msg("Connection lost.");
        else if (nbytes > 0) error_msg("Short packet: %d bytes", nbytes);
        else error_msg("Server read ACK failure.");
        break;
      } else {
        if (!*port) {
          *port = ((struct sockaddr_in *)&from)->sin_port;
          ((struct sockaddr_in *)server)->sin_port =
                  ((struct sockaddr_in *)&from)->sin_port;
        }
        if (((struct sockaddr_in *)server)->sin_addr.s_addr !=
                ((struct sockaddr_in *)&from)->sin_addr.s_addr) {
          error_msg("Invalid address in DATA.");
          continue;
        }
        if (*port != ((struct sockaddr_in *)server)->sin_port) {
          error_msg("Invalid port in DATA.");
          packetlen = mkpkt_err(packet, TFTP_ER_UNKID, TFTP_ES_UNKID);
          (void) write_server(sd, packet, packetlen, server);
          continue;
        }
        opcode = (uint16_t) packet[0] << 8 | (uint16_t) packet[1];
        rblockno = (uint16_t) packet[2] << 8 | (uint16_t) packet[3];

        if (opcode != TFTP_OP_ACK) {
          error_msg("Bad opcode.");
          if (opcode > 5) {
            packetlen = mkpkt_err(packet, TFTP_ER_ILLEGALOP, TFTP_ES_ILLEGALOP);
            (void) write_server(sd, packet, packetlen, server);
          }
          break;
        }
        if (blockno) *blockno = rblockno;
        return 0;
      }
    }
  }
  error_msg("Timeout, Waiting for ACK.");
  return -1;
}

// receives file from server.
static int file_get(void)
{
  struct sockaddr_storage server, from;
  uint8_t *packet;
  uint16_t blockno = 0, opcode, rblockno = 0;
  int len, sd, fd, retry, nbytesrecvd = 0, ndatabytes, ret, result = -1;

  sd = init_tftp(&server);

  packet = (uint8_t*) xzalloc(TFTP_IOBUFSIZE);
  fd = xcreate(TT.local_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);

  len = mkpkt_request(packet, TFTP_OP_RRQ, TT.remote_file, 1);
  ret = write_server(sd, packet, len, &server);
  if (ret != len){
    unlink(TT.local_file);
    goto errout_with_sd;
  }
  if (TT.af == AF_INET6) ((struct sockaddr_in6 *)&server)->sin6_port = 0;
  else ((struct sockaddr_in *)&server)->sin_port = 0;

  do {
    blockno++;
    for (retry = 0 ; retry < TFTP_RETRIES; retry++) {
      nbytesrecvd = read_server(sd, packet, TFTP_IOBUFSIZE, &from);
      if (nbytesrecvd > 0) {
        if ( ((TT.af == AF_INET) &&
                memcmp(&((struct sockaddr_in *)&server)->sin_addr,
                &((struct sockaddr_in *)&from)->sin_addr,
                sizeof(struct in_addr))) ||
             ((TT.af == AF_INET6) &&
                memcmp(&((struct sockaddr_in6 *)&server)->sin6_addr,
                &((struct sockaddr_in6 *)&from)->sin6_addr,
                sizeof(struct in6_addr)))) {
          error_msg("Invalid address in DATA.");
          retry--;
          continue;
        }
        if ( ((TT.af == AF_INET) && ((struct sockaddr_in *)&server)->sin_port
                && (((struct sockaddr_in *)&server)->sin_port !=
                ((struct sockaddr_in *)&from)->sin_port)) ||
             ((TT.af == AF_INET6) && ((struct sockaddr_in6 *)&server)->sin6_port
                && (((struct sockaddr_in6 *)&server)->sin6_port !=
                ((struct sockaddr_in6 *)&from)->sin6_port))) {
          error_msg("Invalid port in DATA.");
          len = mkpkt_err(packet, TFTP_ER_UNKID, TFTP_ES_UNKID);
          ret = write_server(sd, packet, len, &from);
          retry--;
          continue;
        }
        if (nbytesrecvd < TFTP_DATAHEADERSIZE) {
          error_msg("Tiny data packet ignored.");
          continue;
        }
        if (check_data(packet, &opcode, &rblockno) != 0
            || blockno != rblockno) {

        if (opcode == TFTP_OP_ERR) {
          char *message = "DATA Check failure.";
            char *arr[] = {TFTP_ES_NOSUCHFILE, TFTP_ES_ACCESS,
              TFTP_ES_FULL, TFTP_ES_ILLEGALOP,
              TFTP_ES_UNKID, TFTP_ES_EXISTS,
              TFTP_ES_UNKUSER, TFTP_ES_NEGOTIATE};
            if (rblockno && (rblockno < 9)) message = arr[rblockno - 1];
            error_msg(message);
        }
        if (opcode > 5) {
          len = mkpkt_err(packet, TFTP_ER_ILLEGALOP, TFTP_ES_ILLEGALOP);
          ret = write_server(sd, packet, len, &from);
        }
        continue;
        }
        if ((TT.af == AF_INET6) && !((struct sockaddr_in6 *)&server)->sin6_port)
          ((struct sockaddr_in6 *)&server)->sin6_port =
            ((struct sockaddr_in6 *)&from)->sin6_port;
        else if ((TT.af == AF_INET) && !((struct sockaddr_in *)&server)->sin_port)
          ((struct sockaddr_in *)&server)->sin_port =
            ((struct sockaddr_in *)&from)->sin_port;
        break;
      }
    }
    if (retry == TFTP_RETRIES) {
      error_msg("Retry limit exceeded.");
      unlink(TT.local_file);
      goto errout_with_sd;
    }
    ndatabytes = nbytesrecvd - TFTP_DATAHEADERSIZE;
    if (writeall(fd, packet + TFTP_DATAHEADERSIZE, ndatabytes) < 0){
      unlink(TT.local_file);
      goto errout_with_sd;
    }
    len = mkpkt_ack(packet, blockno);
    ret = write_server(sd, packet, len, &server);
    if (ret != len){
      unlink(TT.local_file);
      goto errout_with_sd;
    }
  } while (ndatabytes >= TFTP_DATASIZE);

  result = 0;

errout_with_sd: xclose(sd);
  free(packet);
  return result;
}

// Sends file to server.
int file_put(void)
{
  struct sockaddr_storage server;
  uint8_t *packet;
  off_t offset = 0;
  uint16_t blockno = 1, rblockno, port = 0;
  int packetlen, sd, fd, retry = 0, ret, result = -1;

  sd = init_tftp(&server);
  packet = (uint8_t*)xzalloc(TFTP_IOBUFSIZE);
  fd = xopenro(TT.local_file);

  for (;;) {  //first loop for request send and confirmation from server.
    packetlen = mkpkt_request(packet, TFTP_OP_WRQ, TT.remote_file, 1);
    ret = write_server(sd, packet, packetlen, &server);
    if (ret != packetlen) goto errout_with_sd;
    if (read_ack(sd, packet, &server, &port, NULL) == 0) break;
    if (++retry > TFTP_RETRIES) {
      error_msg("Retry count exceeded.");
      goto errout_with_sd;
    }
  }
  for (;;) {  // loop for data sending and receving ack from server.
    packetlen = mkpkt_data(fd, offset, packet, blockno);
    if (packetlen < 0) goto errout_with_sd;

    ret = write_server(sd, packet, packetlen, &server);
    if (ret != packetlen) goto errout_with_sd;

    if (read_ack(sd, packet, &server, &port, &rblockno) == 0) {
      if (rblockno == blockno) {
        if (packetlen < TFTP_PACKETSIZE) break;
        blockno++;
        offset += TFTP_DATASIZE;
        retry = 0;
        continue;
      }
    }
    if (++retry > TFTP_RETRIES) {
      error_msg("Retry count exceeded.");
      goto errout_with_sd;
    }
  }
  result = 0;

errout_with_sd: close(sd);
  free(packet);
  return result;
}

void tftp_main(void)
{
  struct addrinfo *info, rp, *res=0;
  int ret;

  if (toys.optflags & FLAG_r) {
    if (!(toys.optflags & FLAG_l)) {
      char *slash = strrchr(TT.remote_file, '/');
      TT.local_file = (slash) ? slash + 1 : TT.remote_file;
    }
  } else if (toys.optflags & FLAG_l) TT.remote_file = TT.local_file;
  else error_exit("Please provide some files.");

  memset(&rp, 0, sizeof(rp));
  rp.ai_family = AF_UNSPEC;
  rp.ai_socktype = SOCK_STREAM;
  ret = getaddrinfo(toys.optargs[0], toys.optargs[1], &rp, &info);
  if (!ret) {
    for (res = info; res; res = res->ai_next)
    if ( (res->ai_family == AF_INET) || (res->ai_family == AF_INET6)) break;
  }
  if (!res)
    error_exit("bad address '%s' : %s", toys.optargs[0], gai_strerror(ret));
  TT.af = info->ai_family;

  memcpy((void *)&TT.inaddr, info->ai_addr, info->ai_addrlen);
  freeaddrinfo(info);

  if (toys.optflags & FLAG_g) file_get();
  if (toys.optflags & FLAG_p) file_put();
}
