/** @file
  Routines to process TCP option.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TcpMain.h"

/**
  Get a UINT16 value from buffer.

  @param[in] Buf              Pointer to input buffer.

  @return                     The UINT16 value obtained from the buffer.

**/
UINT16
TcpGetUint16 (
  IN UINT8 *Buf
  )
{
  UINT16  Value;
  CopyMem (&Value, Buf, sizeof (UINT16));
  return NTOHS (Value);
}

/**
  Get a UINT32 value from buffer.

  @param[in] Buf              Pointer to input buffer.

  @return                     The UINT32 value obtained from the buffer.

**/
UINT32
TcpGetUint32 (
  IN UINT8 *Buf
  )
{
  UINT32  Value;
  CopyMem (&Value, Buf, sizeof (UINT32));
  return NTOHL (Value);
}

/**
  Put a UINT32 value in buffer.

  @param[out] Buf             Pointer to the buffer.
  @param[in] Data             The UINT32 Date to put in the buffer.

**/
VOID
TcpPutUint32 (
     OUT UINT8  *Buf,
  IN     UINT32 Data
  )
{
  Data = HTONL (Data);
  CopyMem (Buf, &Data, sizeof (UINT32));
}

/**
  Compute the window scale value according to the given buffer size.

  @param[in]  Tcb Pointer to the TCP_CB of this TCP instance.

  @return         The scale value.

**/
UINT8
TcpComputeScale (
  IN TCP_CB *Tcb
  )
{
  UINT8   Scale;
  UINT32  BufSize;

  ASSERT ((Tcb != NULL) && (Tcb->Sk != NULL));

  BufSize = GET_RCV_BUFFSIZE (Tcb->Sk);

  Scale   = 0;
  while ((Scale < TCP_OPTION_MAX_WS) && ((UINT32) (TCP_OPTION_MAX_WIN << Scale) < BufSize)) {

    Scale++;
  }

  return Scale;
}

/**
  Build the TCP option in three-way handshake.

  @param[in]  Tcb     Pointer to the TCP_CB of this TCP instance.
  @param[in]  Nbuf    Pointer to the buffer to store the options.

  @return             The total length of the TCP option field.

**/
UINT16
TcpSynBuildOption (
  IN TCP_CB  *Tcb,
  IN NET_BUF *Nbuf
  )
{
  UINT8   *Data;
  UINT16  Len;

  ASSERT ((Tcb != NULL) && (Nbuf != NULL) && (Nbuf->Tcp == NULL));

  Len = 0;

  //
  // Add a timestamp option if not disabled by the application
  // and it is the first SYN segment, or the peer has sent
  // us its timestamp.
  //
  if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS) &&
      (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) ||
        TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_TS))
      ) {

    Data = NetbufAllocSpace (
             Nbuf,
             TCP_OPTION_TS_ALIGNED_LEN,
             NET_BUF_HEAD
             );

    ASSERT (Data != NULL);
    Len += TCP_OPTION_TS_ALIGNED_LEN;

    TcpPutUint32 (Data, TCP_OPTION_TS_FAST);
    TcpPutUint32 (Data + 4, mTcpTick);
    TcpPutUint32 (Data + 8, 0);
  }

  //
  // Build window scale option, only when configured
  // to send WS option, and either we are doing active
  // open or we have received WS option from peer.
  //
  if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS) &&
      (!TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_ACK) ||
        TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_WS))
      ) {

    Data = NetbufAllocSpace (
             Nbuf,
             TCP_OPTION_WS_ALIGNED_LEN,
             NET_BUF_HEAD
             );

    ASSERT (Data != NULL);

    Len += TCP_OPTION_WS_ALIGNED_LEN;
    TcpPutUint32 (Data, TCP_OPTION_WS_FAST | TcpComputeScale (Tcb));
  }

  //
  // Build the MSS option.
  //
  Data = NetbufAllocSpace (Nbuf, TCP_OPTION_MSS_LEN, 1);
  ASSERT (Data != NULL);

  Len += TCP_OPTION_MSS_LEN;
  TcpPutUint32 (Data, TCP_OPTION_MSS_FAST | Tcb->RcvMss);

  return Len;
}

/**
  Build the TCP option in synchronized states.

  @param[in]  Tcb     Pointer to the TCP_CB of this TCP instance.
  @param[in]  Nbuf    Pointer to the buffer to store the options.

  @return             The total length of the TCP option field.

**/
UINT16
TcpBuildOption (
  IN TCP_CB  *Tcb,
  IN NET_BUF *Nbuf
  )
{
  UINT8   *Data;
  UINT16  Len;

  ASSERT ((Tcb != NULL) && (Nbuf != NULL) && (Nbuf->Tcp == NULL));
  Len = 0;

  //
  // Build the Timestamp option.
  //
  if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_SND_TS) &&
      !TCP_FLG_ON (TCPSEG_NETBUF (Nbuf)->Flag, TCP_FLG_RST)
      ) {

    Data = NetbufAllocSpace (
            Nbuf,
            TCP_OPTION_TS_ALIGNED_LEN,
            NET_BUF_HEAD
            );

    ASSERT (Data != NULL);
    Len += TCP_OPTION_TS_ALIGNED_LEN;

    TcpPutUint32 (Data, TCP_OPTION_TS_FAST);
    TcpPutUint32 (Data + 4, mTcpTick);
    TcpPutUint32 (Data + 8, Tcb->TsRecent);
  }

  return Len;
}

/**
  Parse the supported options.

  @param[in]       Tcp     Pointer to the TCP_CB of this TCP instance.
  @param[in, out]  Option  Pointer to the TCP_OPTION used to store the
                           successfully pasrsed options.

  @retval          0       The options are successfully pasrsed.
  @retval          -1      Illegal option was found.

**/
INTN
TcpParseOption (
  IN     TCP_HEAD   *Tcp,
  IN OUT TCP_OPTION *Option
  )
{
  UINT8 *Head;
  UINT8 TotalLen;
  UINT8 Cur;
  UINT8 Type;
  UINT8 Len;

  ASSERT ((Tcp != NULL) && (Option != NULL));

  Option->Flag  = 0;

  TotalLen      = (UINT8) ((Tcp->HeadLen << 2) - sizeof (TCP_HEAD));
  if (TotalLen <= 0) {
    return 0;
  }

  Head = (UINT8 *) (Tcp + 1);

  //
  // Fast process of the timestamp option.
  //
  if ((TotalLen == TCP_OPTION_TS_ALIGNED_LEN) && (TcpGetUint32 (Head) == TCP_OPTION_TS_FAST)) {

    Option->TSVal = TcpGetUint32 (Head + 4);
    Option->TSEcr = TcpGetUint32 (Head + 8);
    Option->Flag  = TCP_OPTION_RCVD_TS;

    return 0;
  }
  //
  // Slow path to process the options.
  //
  Cur = 0;

  while (Cur < TotalLen) {
    Type = Head[Cur];

    switch (Type) {
    case TCP_OPTION_MSS:
      Len = Head[Cur + 1];

      if ((Len != TCP_OPTION_MSS_LEN) || (TotalLen - Cur < TCP_OPTION_MSS_LEN)) {

        return -1;
      }

      Option->Mss = TcpGetUint16 (&Head[Cur + 2]);
      TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_MSS);

      Cur += TCP_OPTION_MSS_LEN;
      break;

    case TCP_OPTION_WS:
      Len = Head[Cur + 1];

      if ((Len != TCP_OPTION_WS_LEN) || (TotalLen - Cur < TCP_OPTION_WS_LEN)) {

        return -1;
      }

      Option->WndScale = (UINT8) MIN (14, Head[Cur + 2]);
      TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_WS);

      Cur += TCP_OPTION_WS_LEN;
      break;

    case TCP_OPTION_TS:
      Len = Head[Cur + 1];

      if ((Len != TCP_OPTION_TS_LEN) || (TotalLen - Cur < TCP_OPTION_TS_LEN)) {

        return -1;
      }

      Option->TSVal = TcpGetUint32 (&Head[Cur + 2]);
      Option->TSEcr = TcpGetUint32 (&Head[Cur + 6]);
      TCP_SET_FLG (Option->Flag, TCP_OPTION_RCVD_TS);

      Cur += TCP_OPTION_TS_LEN;
      break;

    case TCP_OPTION_NOP:
      Cur++;
      break;

    case TCP_OPTION_EOP:
      Cur = TotalLen;
      break;

    default:
      Len = Head[Cur + 1];

      if ((TotalLen - Cur) < Len || Len < 2) {
        return -1;
      }

      Cur = (UINT8) (Cur + Len);
      break;
    }

  }

  return 0;
}
