/** @file
  Dhcp6 support functions implementation.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Dhcp6Impl.h"

/**
  Generate client Duid in the format of Duid-llt.

  @param[in]  Mode          The pointer to the mode of SNP.

  @retval     NULL          If it failed to generate a client Id.
  @retval     others        The pointer to the new client id.

**/
EFI_DHCP6_DUID *
Dhcp6GenerateClientId (
  IN EFI_SIMPLE_NETWORK_MODE  *Mode
  )
{
  EFI_STATUS      Status;
  EFI_DHCP6_DUID  *Duid;
  EFI_TIME        Time;
  UINT32          Stamp;
  EFI_GUID        Uuid;

  //
  // Attempt to get client Id from variable to keep it constant.
  // See details in section-9 of rfc-3315.
  //
  GetVariable2 (L"ClientId", &gEfiDhcp6ServiceBindingProtocolGuid, (VOID **)&Duid, NULL);
  if (Duid != NULL) {
    return Duid;
  }

  //
  //  The format of client identifier option:
  //
  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |        OPTION_CLIENTID        |          option-len           |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    .                                                               .
  //    .                              DUID                             .
  //    .                        (variable length)                      .
  //    .                                                               .
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  // If System UUID is found from SMBIOS Table, use DUID-UUID type.
  //
  if ((PcdGet8 (PcdDhcp6UidType) == Dhcp6DuidTypeUuid) && !EFI_ERROR (NetLibGetSystemGuid (&Uuid)) && !CompareGuid (&Uuid, &gZeroGuid)) {
    //
    //
    //  The format of DUID-UUID:
    //
    //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //   |          DUID-Type (4)        |    UUID (128 bits)            |
    //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
    //   |                                                               |
    //   |                                                               |
    //   |                                -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //   |                                |
    //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

    //
    // sizeof (option-len + Duid-type + UUID-size) = 20 bytes
    //
    Duid = AllocateZeroPool (2 + 2 + sizeof (EFI_GUID));
    if (Duid == NULL) {
      return NULL;
    }

    //
    // sizeof (Duid-type + UUID-size) = 18 bytes
    //
    Duid->Length = (UINT16)(18);

    //
    // Set the Duid-type and copy UUID.
    //
    WriteUnaligned16 ((UINT16 *)(Duid->Duid), HTONS (Dhcp6DuidTypeUuid));

    CopyMem (Duid->Duid + 2, &Uuid, sizeof (EFI_GUID));
  } else {
    //
    //
    //  The format of DUID-LLT:
    //
    //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //    |          Duid type (1)        |    hardware type (16 bits)    |
    //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //    |                        time (32 bits)                         |
    //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //    .                                                               .
    //    .             link-layer address (variable length)              .
    //    .                                                               .
    //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //

    //
    // Generate a time stamp of the seconds from 2000/1/1, assume 30day/month.
    //
    gRT->GetTime (&Time, NULL);
    Stamp = (UINT32)
            (
             ((((UINT32)(Time.Year - 2000) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) *
             60 +
             Time.Second
            );

    //
    // sizeof (option-len + Duid-type + hardware-type + time) = 10 bytes
    //
    Duid = AllocateZeroPool (10 + Mode->HwAddressSize);
    if (Duid == NULL) {
      return NULL;
    }

    //
    // sizeof (Duid-type + hardware-type + time) = 8 bytes
    //
    Duid->Length = (UINT16)(Mode->HwAddressSize + 8);

    //
    // Set the Duid-type, hardware-type, time and copy the hardware address.
    //
    WriteUnaligned16 ((UINT16 *)((UINT8 *)Duid + OFFSET_OF (EFI_DHCP6_DUID, Duid)), HTONS (Dhcp6DuidTypeLlt));
    WriteUnaligned16 ((UINT16 *)((UINT8 *)Duid + OFFSET_OF (EFI_DHCP6_DUID, Duid) + 2), HTONS (NET_IFTYPE_ETHERNET));
    WriteUnaligned32 ((UINT32 *)((UINT8 *)Duid + OFFSET_OF (EFI_DHCP6_DUID, Duid) + 4), HTONL (Stamp));

    CopyMem (Duid->Duid + 8, &Mode->CurrentAddress, Mode->HwAddressSize);
  }

  Status = gRT->SetVariable (
                  L"ClientId",
                  &gEfiDhcp6ServiceBindingProtocolGuid,
                  (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
                  Duid->Length + 2,
                  (VOID *)Duid
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Duid);
    return NULL;
  }

  return Duid;
}

/**
  Copy the Dhcp6 configure data.

  @param[in]  DstCfg        The pointer to the destination configure data.
  @param[in]  SorCfg        The pointer to the source configure data.

  @retval EFI_SUCCESS           Copy the content from SorCfg from DstCfg successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

**/
EFI_STATUS
Dhcp6CopyConfigData (
  IN EFI_DHCP6_CONFIG_DATA  *DstCfg,
  IN EFI_DHCP6_CONFIG_DATA  *SorCfg
  )
{
  UINTN  Index;
  UINTN  OptionListSize;
  UINTN  OptionSize;

  CopyMem (DstCfg, SorCfg, sizeof (EFI_DHCP6_CONFIG_DATA));

  //
  // Allocate another buffer for solicitretransmission, and copy it.
  //
  if (SorCfg->SolicitRetransmission != NULL) {
    DstCfg->SolicitRetransmission = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION));

    if (DstCfg->SolicitRetransmission == NULL) {
      //
      // Error will be handled out of this function.
      //
      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (
      DstCfg->SolicitRetransmission,
      SorCfg->SolicitRetransmission,
      sizeof (EFI_DHCP6_RETRANSMISSION)
      );
  }

  if ((SorCfg->OptionList != NULL) && (SorCfg->OptionCount != 0)) {
    OptionListSize     = SorCfg->OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *);
    DstCfg->OptionList = AllocateZeroPool (OptionListSize);

    if (DstCfg->OptionList == NULL) {
      //
      // Error will be handled out of this function.
      //
      return EFI_OUT_OF_RESOURCES;
    }

    for (Index = 0; Index < SorCfg->OptionCount; Index++) {
      OptionSize                = NTOHS (SorCfg->OptionList[Index]->OpLen) + 4;
      DstCfg->OptionList[Index] = AllocateZeroPool (OptionSize);

      if (DstCfg->OptionList[Index] == NULL) {
        //
        // Error will be handled out of this function.
        //
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (
        DstCfg->OptionList[Index],
        SorCfg->OptionList[Index],
        OptionSize
        );
    }
  }

  return EFI_SUCCESS;
}

/**
  Clean up the configure data.

  @param[in, out]  CfgData       The pointer to the configure data.

**/
VOID
Dhcp6CleanupConfigData (
  IN OUT EFI_DHCP6_CONFIG_DATA  *CfgData
  )
{
  UINTN  Index;

  ASSERT (CfgData != NULL);
  //
  // Clean up all fields in config data including the reference buffers, but do
  // not free the config data buffer itself.
  //
  if (CfgData->OptionList != NULL) {
    for (Index = 0; Index < CfgData->OptionCount; Index++) {
      if (CfgData->OptionList[Index] != NULL) {
        FreePool (CfgData->OptionList[Index]);
      }
    }

    FreePool (CfgData->OptionList);
  }

  if (CfgData->SolicitRetransmission != NULL) {
    FreePool (CfgData->SolicitRetransmission);
  }

  ZeroMem (CfgData, sizeof (EFI_DHCP6_CONFIG_DATA));
}

/**
  Clean up the mode data.

  @param[in, out]  ModeData      The pointer to the mode data.

**/
VOID
Dhcp6CleanupModeData (
  IN OUT EFI_DHCP6_MODE_DATA  *ModeData
  )
{
  ASSERT (ModeData != NULL);
  //
  // Clean up all fields in mode data including the reference buffers, but do
  // not free the mode data buffer itself.
  //
  if (ModeData->ClientId != NULL) {
    FreePool (ModeData->ClientId);
  }

  if (ModeData->Ia != NULL) {
    if (ModeData->Ia->ReplyPacket != NULL) {
      FreePool (ModeData->Ia->ReplyPacket);
    }

    FreePool (ModeData->Ia);
  }

  ZeroMem (ModeData, sizeof (EFI_DHCP6_MODE_DATA));
}

/**
  Calculate the expire time by the algorithm defined in rfc.

  @param[in]  Base          The base value of the time.
  @param[in]  IsFirstRt     If TRUE, it is the first time to calculate expire time.
  @param[in]  NeedSigned    If TRUE, the signed factor is needed.

  @return     Expire        The calculated result for the new expire time.

**/
UINT32
Dhcp6CalculateExpireTime (
  IN UINT32   Base,
  IN BOOLEAN  IsFirstRt,
  IN BOOLEAN  NeedSigned
  )
{
  EFI_TIME  Time;
  BOOLEAN   Signed;
  UINT32    Seed;
  UINT32    Expire;

  //
  // Take the 10bits of microsecond in system time as a uniform distribution.
  // Take the 10th bit as a flag to determine it's signed or not.
  //
  gRT->GetTime (&Time, NULL);
  Seed   = ((Time.Nanosecond >> 10) & DHCP6_10_BIT_MASK);
  Signed = (BOOLEAN)((((Time.Nanosecond >> 9) & 0x01) != 0) ? TRUE : FALSE);
  Signed = (BOOLEAN)(NeedSigned ? Signed : FALSE);

  //
  // Calculate expire by the following algo:
  //   1. base + base * (-0.1 ~ 0) for the first solicit
  //   2. base + base * (-0.1 ~ 0.1) for the first other messages
  //   3. 2 * base + base * (-0.1 ~ 0.1) for the subsequent all messages
  //   4. base + base * (-0.1 ~ 0) for the more than mrt timeout
  //
  // The (Seed / 0x3ff / 10) is used to a random range (0, 0.1).
  //
  if (IsFirstRt && Signed) {
    Expire = Base - (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
  } else if (IsFirstRt && !Signed) {
    Expire = Base + (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
  } else if (!IsFirstRt && Signed) {
    Expire = 2 * Base - (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
  } else {
    Expire = 2 * Base + (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
  }

  Expire = (Expire != 0) ? Expire : 1;

  return Expire;
}

/**
  Calculate the lease time by the algorithm defined in rfc.

  @param[in]  IaCb          The pointer to the Ia control block.

**/
VOID
Dhcp6CalculateLeaseTime (
  IN DHCP6_IA_CB  *IaCb
  )
{
  UINT32  MinLt;
  UINT32  MaxLt;
  UINTN   Index;

  ASSERT (IaCb->Ia->IaAddressCount > 0);

  MinLt = (UINT32)(-1);
  MaxLt = 0;

  //
  // Calculate minlt as min of all valid life time, and maxlt as max of all
  // valid life time.
  //
  for (Index = 0; Index < IaCb->Ia->IaAddressCount; Index++) {
    MinLt = MIN (MinLt, IaCb->Ia->IaAddress[Index].ValidLifetime);
    MaxLt = MAX (MinLt, IaCb->Ia->IaAddress[Index].ValidLifetime);
  }

  //
  // Take 50% minlt as t1, and 80% maxlt as t2 if Dhcp6 server doesn't offer
  // such information.
  //
  IaCb->T1            = (IaCb->T1 != 0) ? IaCb->T1 : (UINT32)(MinLt * 5 / 10);
  IaCb->T2            = (IaCb->T2 != 0) ? IaCb->T2 : (UINT32)(MinLt * 8 / 10);
  IaCb->AllExpireTime = MaxLt;
  IaCb->LeaseTime     = 0;
}

/**
  Check whether the addresses are all included by the configured Ia.

  @param[in]  Ia            The pointer to the Ia.
  @param[in]  AddressCount  The number of addresses.
  @param[in]  Addresses     The pointer to the addresses buffer.

  @retval EFI_SUCCESS         The addresses are all included by the configured IA.
  @retval EFI_NOT_FOUND       The addresses are not included by the configured IA.

**/
EFI_STATUS
Dhcp6CheckAddress (
  IN EFI_DHCP6_IA      *Ia,
  IN UINT32            AddressCount,
  IN EFI_IPv6_ADDRESS  *Addresses
  )
{
  UINTN    Index1;
  UINTN    Index2;
  BOOLEAN  Found;

  //
  // Check whether the addresses are all included by the configured IA. And it
  // will return success if address count is zero, which means all addresses.
  //
  for (Index1 = 0; Index1 < AddressCount; Index1++) {
    Found = FALSE;

    for (Index2 = 0; Index2 < Ia->IaAddressCount; Index2++) {
      if (CompareMem (
            &Addresses[Index1],
            &Ia->IaAddress[Index2],
            sizeof (EFI_IPv6_ADDRESS)
            ) == 0)
      {
        Found = TRUE;
        break;
      }
    }

    if (!Found) {
      return EFI_NOT_FOUND;
    }
  }

  return EFI_SUCCESS;
}

/**
  Deprive the addresses from current Ia, and generate another eliminated Ia.

  @param[in]  Ia            The pointer to the Ia.
  @param[in]  AddressCount  The number of addresses.
  @param[in]  Addresses     The pointer to the addresses buffer.

  @retval     NULL          If it failed to generate the deprived Ia.
  @retval     others        The pointer to the deprived Ia.

**/
EFI_DHCP6_IA *
Dhcp6DepriveAddress (
  IN EFI_DHCP6_IA      *Ia,
  IN UINT32            AddressCount,
  IN EFI_IPv6_ADDRESS  *Addresses
  )
{
  EFI_DHCP6_IA  *IaCopy;
  UINTN         IaCopySize;
  UINTN         Index1;
  UINTN         Index2;
  BOOLEAN       Found;

  if (AddressCount == 0) {
    //
    // It means release all Ia addresses if address count is zero.
    //
    AddressCount = Ia->IaAddressCount;
  }

  ASSERT (AddressCount != 0);

  IaCopySize = sizeof (EFI_DHCP6_IA) + (AddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
  IaCopy     = AllocateZeroPool (IaCopySize);

  if (IaCopy == NULL) {
    return NULL;
  }

  if (AddressCount == Ia->IaAddressCount) {
    //
    // If release all Ia addresses, just copy the configured Ia and then set
    // its address count as zero.
    // We may decline/release part of addresses at the beginning. So it's a
    // forwarding step to update address infor for decline/release, while the
    // other infor such as Ia state will be updated when receiving reply.
    //
    CopyMem (IaCopy, Ia, IaCopySize);
    Ia->IaAddressCount = 0;
    return IaCopy;
  }

  CopyMem (IaCopy, Ia, sizeof (EFI_DHCP6_IA));

  //
  // Move the addresses from the Ia of instance to the deprived Ia.
  //
  for (Index1 = 0; Index1 < AddressCount; Index1++) {
    Found = FALSE;

    for (Index2 = 0; Index2 < Ia->IaAddressCount; Index2++) {
      if (CompareMem (
            &Addresses[Index1],
            &Ia->IaAddress[Index2],
            sizeof (EFI_IPv6_ADDRESS)
            ) == 0)
      {
        //
        // Copy the deprived address to the copy of Ia
        //
        CopyMem (
          &IaCopy->IaAddress[Index1],
          &Ia->IaAddress[Index2],
          sizeof (EFI_DHCP6_IA_ADDRESS)
          );
        //
        // Delete the deprived address from the instance Ia
        //
        if (Index2 + 1 < Ia->IaAddressCount) {
          CopyMem (
            &Ia->IaAddress[Index2],
            &Ia->IaAddress[Index2 + 1],
            (Ia->IaAddressCount - Index2 - 1) * sizeof (EFI_DHCP6_IA_ADDRESS)
            );
        }

        Found = TRUE;
        break;
      }
    }

    ASSERT (Found == TRUE);
  }

  Ia->IaAddressCount    -= AddressCount;
  IaCopy->IaAddressCount = AddressCount;

  return IaCopy;
}

/**
  The dummy ext buffer free callback routine.

  @param[in]  Arg           The pointer to the parameter.

**/
VOID
EFIAPI
Dhcp6DummyExtFree (
  IN VOID  *Arg
  )
{
}

/**
  The callback routine once message transmitted.

  @param[in]  Wrap          The pointer to the received net buffer.
  @param[in]  EndPoint      The pointer to the udp end point.
  @param[in]  IoStatus      The return status from udp io.
  @param[in]  Context       The opaque parameter to the function.

**/
VOID
EFIAPI
Dhcp6OnTransmitted (
  IN NET_BUF        *Wrap,
  IN UDP_END_POINT  *EndPoint,
  IN EFI_STATUS     IoStatus,
  IN VOID           *Context
  )
{
  NetbufFree (Wrap);
}

/**
  Append the option to Buf, and move Buf to the end.

  @param[in, out] Buf           The pointer to the buffer.
  @param[in]      OptType       The option type.
  @param[in]      OptLen        The length of option contents.
  @param[in]      Data          The pointer to the option content.

  @return         Buf           The position to append the next option.

**/
UINT8 *
Dhcp6AppendOption (
  IN OUT UINT8   *Buf,
  IN     UINT16  OptType,
  IN     UINT16  OptLen,
  IN     UINT8   *Data
  )
{
  //
  //  The format of Dhcp6 option:
  //
  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |          option-code          |   option-len (option data)    |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                          option-data                          |
  //    |                      (option-len octets)                      |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  ASSERT (OptLen != 0);

  WriteUnaligned16 ((UINT16 *)Buf, OptType);
  Buf += 2;
  WriteUnaligned16 ((UINT16 *)Buf, OptLen);
  Buf += 2;
  CopyMem (Buf, Data, NTOHS (OptLen));
  Buf += NTOHS (OptLen);

  return Buf;
}

/**
  Append the appointed IA Address option to Buf, and move Buf to the end.

  @param[in, out] Buf           The pointer to the position to append.
  @param[in]      IaAddr        The pointer to the IA Address.
  @param[in]      MessageType   Message type of DHCP6 package.

  @return         Buf           The position to append the next option.

**/
UINT8 *
Dhcp6AppendIaAddrOption (
  IN OUT UINT8                 *Buf,
  IN     EFI_DHCP6_IA_ADDRESS  *IaAddr,
  IN     UINT32                MessageType
  )
{
  //  The format of the IA Address option is:
  //
  //       0                   1                   2                   3
  //       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //      |          OPTION_IAADDR        |          option-len           |
  //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //      |                                                               |
  //      |                         IPv6 address                          |
  //      |                                                               |
  //      |                                                               |
  //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //      |                      preferred-lifetime                       |
  //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //      |                        valid-lifetime                         |
  //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //      .                                                               .
  //      .                        IAaddr-options                         .
  //      .                                                               .
  //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  //
  // Fill the value of Ia Address option type
  //
  WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr));
  Buf += 2;

  WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
  Buf += 2;

  CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
  Buf += sizeof (EFI_IPv6_ADDRESS);

  //
  // Fill the value of preferred-lifetime and valid-lifetime.
  // According to RFC3315 Chapter 18.1.2, the preferred-lifetime and valid-lifetime fields
  // should set to 0 when initiate a Confirm message.
  //
  if (MessageType != Dhcp6MsgConfirm) {
    WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime));
  }

  Buf += 4;

  if (MessageType != Dhcp6MsgConfirm) {
    WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime));
  }

  Buf += 4;

  return Buf;
}

/**
  Append the appointed Ia option to Buf, and move Buf to the end.

  @param[in, out] Buf           The pointer to the position to append.
  @param[in]      Ia            The pointer to the Ia.
  @param[in]      T1            The time of T1.
  @param[in]      T2            The time of T2.
  @param[in]      MessageType   Message type of DHCP6 package.

  @return         Buf           The position to append the next Ia option.

**/
UINT8 *
Dhcp6AppendIaOption (
  IN OUT UINT8         *Buf,
  IN     EFI_DHCP6_IA  *Ia,
  IN     UINT32        T1,
  IN     UINT32        T2,
  IN     UINT32        MessageType
  )
{
  UINT8   *AddrOpt;
  UINT16  *Len;
  UINTN   Index;

  //
  //  The format of IA_NA and IA_TA option:
  //
  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |          OPTION_IA_NA         |          option-len           |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        IAID (4 octets)                        |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        T1 (only for IA_NA)                    |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        T2 (only for IA_NA)                    |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                                                               |
  //    .                  IA_NA-options/IA_TA-options                  .
  //    .                                                               .
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  // Fill the value of Ia option type
  //
  WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type));
  Buf += 2;

  //
  // Fill the len of Ia option later, keep the pointer first
  //
  Len  = (UINT16 *)Buf;
  Buf += 2;

  //
  // Fill the value of iaid
  //
  WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId));
  Buf += 4;

  //
  // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified.
  //
  if (Ia->Descriptor.Type == Dhcp6OptIana) {
    WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff));
    Buf += 4;
    WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff));
    Buf += 4;
  }

  //
  // Fill all the addresses belong to the Ia
  //
  for (Index = 0; Index < Ia->IaAddressCount; Index++) {
    AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS);
    Buf     = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
  }

  //
  // Fill the value of Ia option length
  //
  *Len = HTONS ((UINT16)(Buf - (UINT8 *)Len - 2));

  return Buf;
}

/**
  Append the appointed Elapsed time option to Buf, and move Buf to the end.

  @param[in, out] Buf           The pointer to the position to append.
  @param[in]      Instance      The pointer to the Dhcp6 instance.
  @param[out]     Elapsed       The pointer to the elapsed time value in
                                  the generated packet.

  @return         Buf           The position to append the next Ia option.

**/
UINT8 *
Dhcp6AppendETOption (
  IN OUT UINT8           *Buf,
  IN     DHCP6_INSTANCE  *Instance,
  OUT    UINT16          **Elapsed
  )
{
  //
  //  The format of elapsed time option:
  //
  //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //  |      OPTION_ELAPSED_TIME      |           option-len          |
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //  |          elapsed-time         |
  //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  // Fill the value of elapsed-time option type.
  //
  WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime));
  Buf += 2;

  //
  // Fill the len of elapsed-time option, which is fixed.
  //
  WriteUnaligned16 ((UINT16 *)Buf, HTONS (2));
  Buf += 2;

  //
  // Fill in elapsed time value with 0 value for now.  The actual value is
  // filled in later just before the packet is transmitted.
  //
  WriteUnaligned16 ((UINT16 *)Buf, HTONS (0));
  *Elapsed = (UINT16 *)Buf;
  Buf     += 2;

  return Buf;
}

/**
  Set the elapsed time based on the given instance and the pointer to the
  elapsed time option.

  @param[in]      Elapsed       The pointer to the position to append.
  @param[in]      Instance      The pointer to the Dhcp6 instance.

**/
VOID
SetElapsedTime (
  IN     UINT16          *Elapsed,
  IN     DHCP6_INSTANCE  *Instance
  )
{
  EFI_TIME  Time;
  UINT64    CurrentStamp;
  UINT64    ElapsedTimeValue;

  //
  // Generate a time stamp of the centiseconds from 2000/1/1, assume 30day/month.
  //
  gRT->GetTime (&Time, NULL);
  CurrentStamp = MultU64x32 (
                   ((((UINT32)(Time.Year - 2000) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) * 60 + Time.Second,
                   100
                   ) +
                 DivU64x32 (
                   Time.Nanosecond,
                   10000000
                   );

  //
  // Sentinel value of 0 means that this is the first DHCP packet that we are
  // sending and that we need to initialize the value.  First DHCP message
  // gets 0 elapsed-time.  Otherwise, calculate based on StartTime.
  //
  if (Instance->StartTime == 0) {
    ElapsedTimeValue    = 0;
    Instance->StartTime = CurrentStamp;
  } else {
    ElapsedTimeValue = CurrentStamp - Instance->StartTime;

    //
    // If elapsed time cannot fit in two bytes, set it to 0xffff.
    //
    if (ElapsedTimeValue > 0xffff) {
      ElapsedTimeValue = 0xffff;
    }
  }

  WriteUnaligned16 (Elapsed, HTONS ((UINT16)ElapsedTimeValue));
}

/**
  Seek the address of the first byte of the option header.

  @param[in]  Buf           The pointer to the buffer.
  @param[in]  SeekLen       The length to seek.
  @param[in]  OptType       The option type.

  @retval     NULL          If it failed to seek the option.
  @retval     others        The position to the option.

**/
UINT8 *
Dhcp6SeekOption (
  IN UINT8   *Buf,
  IN UINT32  SeekLen,
  IN UINT16  OptType
  )
{
  UINT8   *Cursor;
  UINT8   *Option;
  UINT16  DataLen;
  UINT16  OpCode;

  Option = NULL;
  Cursor = Buf;

  //
  // The format of Dhcp6 option refers to Dhcp6AppendOption().
  //
  while (Cursor < Buf + SeekLen) {
    OpCode = ReadUnaligned16 ((UINT16 *)Cursor);
    if (OpCode == HTONS (OptType)) {
      Option = Cursor;
      break;
    }

    DataLen = NTOHS (ReadUnaligned16 ((UINT16 *)(Cursor + 2)));
    Cursor += (DataLen + 4);
  }

  return Option;
}

/**
  Seek the address of the first byte of the Ia option header.

  @param[in]  Buf           The pointer to the buffer.
  @param[in]  SeekLen       The length to seek.
  @param[in]  IaDesc        The pointer to the Ia descriptor.

  @retval     NULL          If it failed to seek the Ia option.
  @retval     others        The position to the Ia option.

**/
UINT8 *
Dhcp6SeekIaOption (
  IN UINT8                    *Buf,
  IN UINT32                   SeekLen,
  IN EFI_DHCP6_IA_DESCRIPTOR  *IaDesc
  )
{
  UINT8   *Cursor;
  UINT8   *Option;
  UINT16  DataLen;
  UINT16  OpCode;
  UINT32  IaId;

  //
  // The format of IA_NA and IA_TA option refers to Dhcp6AppendIaOption().
  //
  Option = NULL;
  Cursor = Buf;

  while (Cursor < Buf + SeekLen) {
    OpCode = ReadUnaligned16 ((UINT16 *)Cursor);
    IaId   = ReadUnaligned32 ((UINT32 *)(Cursor + 4));
    if ((OpCode == HTONS (IaDesc->Type)) && (IaId == HTONL (IaDesc->IaId))) {
      Option = Cursor;
      break;
    }

    DataLen = NTOHS (ReadUnaligned16 ((UINT16 *)(Cursor + 2)));
    Cursor += (DataLen + 4);
  }

  return Option;
}

/**
  Check whether the incoming IPv6 address in IaAddr is one of the maintained
  addresses in the IA control block.

  @param[in]  IaAddr            The pointer to the IA Address to be checked.
  @param[in]  CurrentIa         The pointer to the IA in IA control block.

  @retval     TRUE              Yes, this Address is already in IA control block.
  @retval     FALSE             No, this Address is NOT in IA control block.

**/
BOOLEAN
Dhcp6AddrIsInCurrentIa (
  IN    EFI_DHCP6_IA_ADDRESS  *IaAddr,
  IN    EFI_DHCP6_IA          *CurrentIa
  )
{
  UINT32  Index;

  ASSERT (IaAddr != NULL && CurrentIa != NULL);

  for (Index = 0; Index < CurrentIa->IaAddressCount; Index++) {
    if (EFI_IP6_EQUAL (&IaAddr->IpAddress, &CurrentIa->IaAddress[Index].IpAddress)) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Parse the address option and update the address information.

  @param[in]      CurrentIa     The pointer to the Ia Address in control block.
  @param[in]      IaInnerOpt    The pointer to the buffer.
  @param[in]      IaInnerLen    The length to parse.
  @param[out]     AddrNum       The number of addresses.
  @param[in, out] AddrBuf       The pointer to the address buffer.

**/
VOID
Dhcp6ParseAddrOption (
  IN     EFI_DHCP6_IA          *CurrentIa,
  IN     UINT8                 *IaInnerOpt,
  IN     UINT16                IaInnerLen,
  OUT UINT32                   *AddrNum,
  IN OUT EFI_DHCP6_IA_ADDRESS  *AddrBuf
  )
{
  UINT8                 *Cursor;
  UINT16                DataLen;
  UINT16                OpCode;
  UINT32                ValidLt;
  UINT32                PreferredLt;
  EFI_DHCP6_IA_ADDRESS  *IaAddr;

  //
  //  The format of the IA Address option:
  //
  //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |          OPTION_IAADDR        |          option-len           |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                                                               |
  //    |                         IPv6 address                          |
  //    |                                                               |
  //    |                                                               |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                      preferred-lifetime                       |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    |                        valid-lifetime                         |
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //    .                                                               .
  //    .                        IAaddr-options                         .
  //    .                                                               .
  //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //

  //
  //  Two usage model:
  //
  //    1. Pass addrbuf == null, to get the addrnum over the Ia inner options.
  //    2. Pass addrbuf != null, to resolve the addresses over the Ia inner
  //       options to the addrbuf.
  //

  Cursor   = IaInnerOpt;
  *AddrNum = 0;

  while (Cursor < IaInnerOpt + IaInnerLen) {
    //
    // Refer to RFC3315 Chapter 18.1.8, we need to update lifetimes for any addresses in the IA option
    // that the client already has recorded in the IA, and discard the Ia address option with 0 valid time.
    //
    OpCode      = ReadUnaligned16 ((UINT16 *)Cursor);
    PreferredLt = NTOHL (ReadUnaligned32 ((UINT32 *)(Cursor + 20)));
    ValidLt     = NTOHL (ReadUnaligned32 ((UINT32 *)(Cursor + 24)));
    IaAddr      = (EFI_DHCP6_IA_ADDRESS *)(Cursor + 4);
    if ((OpCode == HTONS (Dhcp6OptIaAddr)) && (ValidLt >= PreferredLt) &&
        (Dhcp6AddrIsInCurrentIa (IaAddr, CurrentIa) || (ValidLt != 0)))
    {
      if (AddrBuf != NULL) {
        CopyMem (AddrBuf, IaAddr, sizeof (EFI_DHCP6_IA_ADDRESS));
        AddrBuf->PreferredLifetime = PreferredLt;
        AddrBuf->ValidLifetime     = ValidLt;
        AddrBuf                    = (EFI_DHCP6_IA_ADDRESS *)((UINT8 *)AddrBuf + sizeof (EFI_DHCP6_IA_ADDRESS));
      }

      (*AddrNum)++;
    }

    DataLen = NTOHS (ReadUnaligned16 ((UINT16 *)(Cursor + 2)));
    Cursor += (DataLen + 4);
  }
}

/**
  Create a control block for the Ia according to the corresponding options.

  @param[in]  Instance              The pointer to DHCP6 Instance.
  @param[in]  IaInnerOpt            The pointer to the inner options in the Ia option.
  @param[in]  IaInnerLen            The length of all the inner options in the Ia option.
  @param[in]  T1                    T1 time in the Ia option.
  @param[in]  T2                    T2 time in the Ia option.

  @retval     EFI_NOT_FOUND         No valid IA option is found.
  @retval     EFI_SUCCESS           Create an IA control block successfully.
  @retval     EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
  @retval     EFI_DEVICE_ERROR      An unexpected error.

**/
EFI_STATUS
Dhcp6GenerateIaCb (
  IN  DHCP6_INSTANCE  *Instance,
  IN  UINT8           *IaInnerOpt,
  IN  UINT16          IaInnerLen,
  IN  UINT32          T1,
  IN  UINT32          T2
  )
{
  UINT32        AddrNum;
  UINT32        IaSize;
  EFI_DHCP6_IA  *Ia;

  if (Instance->IaCb.Ia == NULL) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Calculate the number of addresses for this Ia, excluding the addresses with
  // the value 0 of valid lifetime.
  //
  Dhcp6ParseAddrOption (Instance->IaCb.Ia, IaInnerOpt, IaInnerLen, &AddrNum, NULL);

  if (AddrNum == 0) {
    return EFI_NOT_FOUND;
  }

  //
  // Allocate for new IA.
  //
  IaSize = sizeof (EFI_DHCP6_IA) + (AddrNum - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
  Ia     = AllocateZeroPool (IaSize);

  if (Ia == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Fill up this new IA fields.
  //
  Ia->State          = Instance->IaCb.Ia->State;
  Ia->IaAddressCount = AddrNum;
  CopyMem (&Ia->Descriptor, &Instance->Config->IaDescriptor, sizeof (EFI_DHCP6_IA_DESCRIPTOR));
  Dhcp6ParseAddrOption (Instance->IaCb.Ia, IaInnerOpt, IaInnerLen, &AddrNum, Ia->IaAddress);

  //
  // Free original IA resource.
  //
  if (Instance->IaCb.Ia->ReplyPacket != NULL) {
    FreePool (Instance->IaCb.Ia->ReplyPacket);
  }

  FreePool (Instance->IaCb.Ia);

  ZeroMem (&Instance->IaCb, sizeof (DHCP6_IA_CB));

  //
  // Update IaCb to use new IA.
  //
  Instance->IaCb.Ia = Ia;

  //

  // Fill in IaCb fields. Such as T1, T2, AllExpireTime and LeaseTime.
  //
  Instance->IaCb.T1 = T1;
  Instance->IaCb.T2 = T2;
  Dhcp6CalculateLeaseTime (&Instance->IaCb);

  return EFI_SUCCESS;
}

/**
  Cache the current IA configuration information.

  @param[in] Instance           The pointer to DHCP6 Instance.

  @retval EFI_SUCCESS           Cache the current IA successfully.
  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.

**/
EFI_STATUS
Dhcp6CacheIa (
  IN DHCP6_INSTANCE  *Instance
  )
{
  UINTN         IaSize;
  EFI_DHCP6_IA  *Ia;

  Ia = Instance->IaCb.Ia;

  if ((Instance->CacheIa == NULL) && (Ia != NULL)) {
    //
    // Cache the current IA.
    //
    IaSize = sizeof (EFI_DHCP6_IA) + (Ia->IaAddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);

    Instance->CacheIa = AllocateZeroPool (IaSize);
    if (Instance->CacheIa == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (Instance->CacheIa, Ia, IaSize);
  }

  return EFI_SUCCESS;
}

/**
  Append CacheIa to the current IA. Meanwhile, clear CacheIa.ValidLifetime to 0.

  @param[in]  Instance            The pointer to DHCP6 instance.

**/
VOID
Dhcp6AppendCacheIa (
  IN DHCP6_INSTANCE  *Instance
  )
{
  UINT8         *Ptr;
  UINTN         Index;
  UINTN         IaSize;
  UINTN         NewIaSize;
  EFI_DHCP6_IA  *Ia;
  EFI_DHCP6_IA  *NewIa;
  EFI_DHCP6_IA  *CacheIa;

  Ia      = Instance->IaCb.Ia;
  CacheIa = Instance->CacheIa;

  if ((CacheIa != NULL) && (CacheIa->IaAddressCount != 0)) {
    //
    // There are old addresses existing. Merge with current addresses.
    //
    NewIaSize = sizeof (EFI_DHCP6_IA) + (Ia->IaAddressCount + CacheIa->IaAddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
    NewIa     = AllocateZeroPool (NewIaSize);
    if (NewIa == NULL) {
      return;
    }

    IaSize = sizeof (EFI_DHCP6_IA) + (Ia->IaAddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
    CopyMem (NewIa, Ia, IaSize);

    //
    // Clear old address.ValidLifetime
    //
    for (Index = 0; Index < CacheIa->IaAddressCount; Index++) {
      CacheIa->IaAddress[Index].ValidLifetime = 0;
    }

    NewIa->IaAddressCount += CacheIa->IaAddressCount;
    Ptr                    = (UINT8 *)&NewIa->IaAddress[Ia->IaAddressCount];
    CopyMem (Ptr, CacheIa->IaAddress, CacheIa->IaAddressCount * sizeof (EFI_DHCP6_IA_ADDRESS));

    //
    // Migrate to the NewIa and free previous.
    //
    FreePool (Instance->CacheIa);
    FreePool (Instance->IaCb.Ia);
    Instance->CacheIa = NULL;
    Instance->IaCb.Ia = NewIa;
  }
}

/**
  Calculate the Dhcp6 get mapping timeout by adding additional delay to the IP6 DAD transmits count.

  @param[in]   Ip6Cfg              The pointer to Ip6 config protocol.
  @param[out]  TimeOut             The time out value in 100ns units.

  @retval   EFI_INVALID_PARAMETER  Input parameters are invalid.
  @retval   EFI_SUCCESS            Calculate the time out value successfully.
**/
EFI_STATUS
Dhcp6GetMappingTimeOut (
  IN  EFI_IP6_CONFIG_PROTOCOL  *Ip6Cfg,
  OUT UINTN                    *TimeOut
  )
{
  EFI_STATUS                                Status;
  UINTN                                     DataSize;
  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS  DadXmits;

  if ((Ip6Cfg == NULL) || (TimeOut == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
  Status   = Ip6Cfg->GetData (
                       Ip6Cfg,
                       Ip6ConfigDataTypeDupAddrDetectTransmits,
                       &DataSize,
                       &DadXmits
                       );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *TimeOut = TICKS_PER_SECOND * DadXmits.DupAddrDetectTransmits + DHCP6_DAD_ADDITIONAL_DELAY;

  return EFI_SUCCESS;
}
