/** @file
  Routines to process MTFTP4 options.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Mtftp4Impl.h"

CHAR8  *mMtftp4SupportedOptions[MTFTP4_SUPPORTED_OPTIONS] = {
  "blksize",
  "windowsize",
  "timeout",
  "tsize",
  "multicast"
};

/**
  Check whether two ascii strings are equal, ignore the case.

  @param  Str1                   The first ascii string
  @param  Str2                   The second ascii string

  @retval TRUE                   Two strings are equal when case is ignored.
  @retval FALSE                  Two strings are not equal.

**/
BOOLEAN
NetStringEqualNoCase (
  IN UINT8  *Str1,
  IN UINT8  *Str2
  )
{
  UINT8  Ch1;
  UINT8  Ch2;

  ASSERT ((Str1 != NULL) && (Str2 != NULL));

  for ( ; (*Str1 != '\0') && (*Str2 != '\0'); Str1++, Str2++) {
    Ch1 = *Str1;
    Ch2 = *Str2;

    //
    // Convert them to lower case then compare two
    //
    if (('A' <= Ch1) && (Ch1 <= 'Z')) {
      Ch1 += 'a' - 'A';
    }

    if (('A' <= Ch2) && (Ch2 <= 'Z')) {
      Ch2 += 'a' - 'A';
    }

    if (Ch1 != Ch2) {
      return FALSE;
    }
  }

  return (BOOLEAN)(*Str1 == *Str2);
}

/**
  Convert a string to a UINT32 number.

  @param  Str                    The string to convert from

  @return The number get from the string

**/
UINT32
NetStringToU32 (
  IN UINT8  *Str
  )
{
  UINT32  Num;

  ASSERT (Str != NULL);

  Num = 0;

  for ( ; NET_IS_DIGIT (*Str); Str++) {
    Num = Num * 10 + (*Str - '0');
  }

  return Num;
}

/**
  Convert a string of the format "192.168.0.1" to an IP address.

  @param  Str                    The string representation of IP
  @param  Ip                     The variable to get IP.

  @retval EFI_INVALID_PARAMETER  The IP string is invalid.
  @retval EFI_SUCCESS            The IP is parsed into the Ip

**/
EFI_STATUS
NetStringToIp (
  IN     UINT8  *Str,
  OUT IP4_ADDR  *Ip
  )
{
  UINT32  Byte;
  UINT32  Addr;
  UINTN   Index;

  *Ip  = 0;
  Addr = 0;

  for (Index = 0; Index < 4; Index++) {
    if (!NET_IS_DIGIT (*Str)) {
      return EFI_INVALID_PARAMETER;
    }

    Byte = NetStringToU32 (Str);

    if (Byte > 255) {
      return EFI_INVALID_PARAMETER;
    }

    Addr = (Addr << 8) | Byte;

    //
    // Skip all the digitals and check whether the separator is the dot
    //
    while (NET_IS_DIGIT (*Str)) {
      Str++;
    }

    if ((Index < 3) && (*Str != '.')) {
      return EFI_INVALID_PARAMETER;
    }

    Str++;
  }

  *Ip = Addr;

  return EFI_SUCCESS;
}

/**
  Go through the packet to fill the Options array with the start
  addresses of each MTFTP option name/value pair.

  @param  Packet                 The packet to check
  @param  PacketLen              The packet's length
  @param  Count                  The size of the Options on input. The actual
                                 options on output
  @param  Options                The option array to fill in

  @retval EFI_INVALID_PARAMETER  The packet is malformatted
  @retval EFI_BUFFER_TOO_SMALL   The Options array is too small
  @retval EFI_SUCCESS            The packet has been parsed into the Options array.

**/
EFI_STATUS
Mtftp4FillOptions (
  IN     EFI_MTFTP4_PACKET  *Packet,
  IN     UINT32             PacketLen,
  IN OUT UINT32             *Count,
  OUT EFI_MTFTP4_OPTION     *Options          OPTIONAL
  )
{
  UINT8  *Cur;
  UINT8  *Last;
  UINT8  Num;
  UINT8  *Name;
  UINT8  *Value;

  Num  = 0;
  Cur  = (UINT8 *)Packet + MTFTP4_OPCODE_LEN;
  Last = (UINT8 *)Packet + PacketLen - 1;

  //
  // process option name and value pairs. The last byte is always zero
  //
  while (Cur < Last) {
    Name = Cur;

    while (*Cur != 0) {
      Cur++;
    }

    if (Cur == Last) {
      return EFI_INVALID_PARAMETER;
    }

    Value = ++Cur;

    while (*Cur != 0) {
      Cur++;
    }

    Num++;

    if ((Options != NULL) && (Num <= *Count)) {
      Options[Num - 1].OptionStr = Name;
      Options[Num - 1].ValueStr  = Value;
    }

    Cur++;
  }

  if ((*Count < Num) || (Options == NULL)) {
    *Count = Num;
    return EFI_BUFFER_TOO_SMALL;
  }

  *Count = Num;
  return EFI_SUCCESS;
}

/**
  Allocate and fill in a array of Mtftp options from the Packet.

  It first calls Mtftp4FillOption to get the option number, then allocate
  the array, at last, call Mtftp4FillOption again to save the options.

  @param  Packet                 The packet to parse
  @param  PacketLen              The length of the packet
  @param  OptionCount            The number of options in the packet
  @param  OptionList             The point to get the option array.

  @retval EFI_INVALID_PARAMETER  The parametera are invalid or packet isn't a
                                 well-formatted OACK packet.
  @retval EFI_SUCCESS            The option array is build
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory for the array

**/
EFI_STATUS
Mtftp4ExtractOptions (
  IN     EFI_MTFTP4_PACKET  *Packet,
  IN     UINT32             PacketLen,
  OUT UINT32                *OptionCount,
  OUT EFI_MTFTP4_OPTION     **OptionList        OPTIONAL
  )
{
  EFI_STATUS  Status;

  *OptionCount = 0;

  if (OptionList != NULL) {
    *OptionList = NULL;
  }

  if (NTOHS (Packet->OpCode) != EFI_MTFTP4_OPCODE_OACK) {
    return EFI_INVALID_PARAMETER;
  }

  if (PacketLen == MTFTP4_OPCODE_LEN) {
    return EFI_SUCCESS;
  }

  //
  // The last byte must be zero to terminate the options
  //
  if (*((UINT8 *)Packet + PacketLen - 1) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get the number of options
  //
  Status = Mtftp4FillOptions (Packet, PacketLen, OptionCount, NULL);

  if ((Status == EFI_SUCCESS) || (Status != EFI_BUFFER_TOO_SMALL)) {
    return Status;
  }

  //
  // Allocate memory for the options, then call Mtftp4FillOptions to
  // fill it if caller want that.
  //
  if (OptionList == NULL) {
    return EFI_SUCCESS;
  }

  *OptionList = AllocatePool (*OptionCount * sizeof (EFI_MTFTP4_OPTION));

  if (*OptionList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Mtftp4FillOptions (Packet, PacketLen, OptionCount, *OptionList);
  return EFI_SUCCESS;
}

/**
  Parse the MTFTP multicast option.

  @param  Value                  The Mtftp multicast value string
  @param  Option                 The option to save the info into.

  @retval EFI_INVALID_PARAMETER  The multicast value string is invalid.
  @retval EFI_SUCCESS            The multicast value is parsed into the Option

**/
EFI_STATUS
Mtftp4ExtractMcast (
  IN     UINT8          *Value,
  IN OUT MTFTP4_OPTION  *Option
  )
{
  EFI_STATUS  Status;
  UINT32      Num;

  //
  // The multicast option is formatted like "204.0.0.1,1857,1"
  // The server can also omit the ip and port, use ",,1"
  //
  if (*Value == ',') {
    Option->McastIp = 0;
  } else {
    Status = NetStringToIp (Value, &Option->McastIp);

    if (EFI_ERROR (Status)) {
      return Status;
    }

    while ((*Value != 0) && (*Value != ',')) {
      Value++;
    }
  }

  if (*Value != ',') {
    return EFI_INVALID_PARAMETER;
  }

  Value++;

  //
  // Convert the port setting. the server can send us a port number or
  // empty string. such as the port in ",,1"
  //
  if (*Value == ',') {
    Option->McastPort = 0;
  } else {
    Num = NetStringToU32 (Value);

    if (Num > 65535) {
      return EFI_INVALID_PARAMETER;
    }

    Option->McastPort = (UINT16)Num;

    while (NET_IS_DIGIT (*Value)) {
      Value++;
    }
  }

  if (*Value != ',') {
    return EFI_INVALID_PARAMETER;
  }

  Value++;

  //
  // Check the master/slave setting, 1 for master, 0 for slave.
  //
  Num = NetStringToU32 (Value);

  if ((Num != 0) && (Num != 1)) {
    return EFI_INVALID_PARAMETER;
  }

  Option->Master = (BOOLEAN)(Num == 1);

  while (NET_IS_DIGIT (*Value)) {
    Value++;
  }

  if (*Value != '\0') {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Parse the option in Options array to MTFTP4_OPTION which program
  can access directly.

  @param  Options                The option array, which contains addresses of each
                                 option's name/value string.
  @param  Count                  The number of options in the Options
  @param  Request                Whether this is a request or OACK. The format of
                                 multicast is different according to this setting.
  @param  Operation              The current performed operation.
  @param  MtftpOption            The MTFTP4_OPTION for easy access.

  @retval EFI_INVALID_PARAMETER  The option is malformatted
  @retval EFI_UNSUPPORTED        Some option isn't supported
  @retval EFI_SUCCESS            The option are OK and has been parsed.

**/
EFI_STATUS
Mtftp4ParseOption (
  IN     EFI_MTFTP4_OPTION  *Options,
  IN     UINT32             Count,
  IN     BOOLEAN            Request,
  IN     UINT16             Operation,
  OUT MTFTP4_OPTION         *MtftpOption
  )
{
  EFI_STATUS         Status;
  UINT32             Index;
  UINT32             Value;
  EFI_MTFTP4_OPTION  *This;

  MtftpOption->Exist = 0;

  for (Index = 0; Index < Count; Index++) {
    This = Options + Index;

    if ((This->OptionStr == NULL) || (This->ValueStr == NULL)) {
      return EFI_INVALID_PARAMETER;
    }

    if (NetStringEqualNoCase (This->OptionStr, (UINT8 *)"blksize")) {
      //
      // block size option, valid value is between [8, 65464]
      //
      Value = NetStringToU32 (This->ValueStr);

      if ((Value < 8) || (Value > 65464)) {
        return EFI_INVALID_PARAMETER;
      }

      MtftpOption->BlkSize = (UINT16)Value;
      MtftpOption->Exist  |= MTFTP4_BLKSIZE_EXIST;
    } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *)"timeout")) {
      //
      // timeout option, valid value is between [1, 255]
      //
      Value = NetStringToU32 (This->ValueStr);

      if ((Value < 1) || (Value > 255)) {
        return EFI_INVALID_PARAMETER;
      }

      MtftpOption->Timeout = (UINT8)Value;
    } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *)"tsize")) {
      //
      // tsize option, the biggest transfer supported is 4GB with block size option
      //
      MtftpOption->Tsize  = NetStringToU32 (This->ValueStr);
      MtftpOption->Exist |= MTFTP4_TSIZE_EXIST;
    } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *)"multicast")) {
      //
      // Multicast option, if it is a request, the value must be a zero
      // length string, otherwise, it is formatted like "204.0.0.1,1857,1\0"
      //
      if (Request) {
        if (*(This->ValueStr) != '\0') {
          return EFI_INVALID_PARAMETER;
        }
      } else {
        Status = Mtftp4ExtractMcast (This->ValueStr, MtftpOption);

        if (EFI_ERROR (Status)) {
          return Status;
        }
      }

      MtftpOption->Exist |= MTFTP4_MCAST_EXIST;
    } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *)"windowsize")) {
      if (Operation == EFI_MTFTP4_OPCODE_WRQ) {
        //
        // Currently, windowsize is not supported in the write operation.
        //
        return EFI_UNSUPPORTED;
      }

      Value = NetStringToU32 (This->ValueStr);

      if (Value < 1) {
        return EFI_INVALID_PARAMETER;
      }

      MtftpOption->WindowSize = (UINT16)Value;
      MtftpOption->Exist     |= MTFTP4_WINDOWSIZE_EXIST;
    } else if (Request) {
      //
      // Ignore the unsupported option if it is a reply, and return
      // EFI_UNSUPPORTED if it's a request according to the UEFI spec.
      //
      return EFI_UNSUPPORTED;
    }
  }

  return EFI_SUCCESS;
}

/**
  Parse the options in the OACK packet to MTFTP4_OPTION which program
  can access directly.

  @param  Packet                 The OACK packet to parse
  @param  PacketLen              The length of the packet
  @param  Operation              The current performed operation.
  @param  MtftpOption            The MTFTP_OPTION for easy access.

  @retval EFI_INVALID_PARAMETER  The packet option is malformatted
  @retval EFI_UNSUPPORTED        Some option isn't supported
  @retval EFI_SUCCESS            The option are OK and has been parsed.

**/
EFI_STATUS
Mtftp4ParseOptionOack (
  IN     EFI_MTFTP4_PACKET  *Packet,
  IN     UINT32             PacketLen,
  IN     UINT16             Operation,
  OUT MTFTP4_OPTION         *MtftpOption
  )
{
  EFI_MTFTP4_OPTION  *OptionList;
  EFI_STATUS         Status;
  UINT32             Count;

  MtftpOption->Exist = 0;

  Status = Mtftp4ExtractOptions (Packet, PacketLen, &Count, &OptionList);

  if (EFI_ERROR (Status) || (Count == 0)) {
    return Status;
  }

  ASSERT (OptionList != NULL);

  Status = Mtftp4ParseOption (OptionList, Count, FALSE, Operation, MtftpOption);

  FreePool (OptionList);
  return Status;
}
