/** @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;
}
