/** @file
  Functions implementation related with DHCPv6 for HTTP boot driver.

Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under 
the terms and conditions of the BSD License that accompanies this distribution.  
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.                                          
    
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "HttpBootDxe.h"

/**
  Build the options buffer for the DHCPv6 request packet.

  @param[in]  Private             The pointer to HTTP BOOT driver private data.
  @param[out] OptList             The pointer to the option pointer array.
  @param[in]  Buffer              The pointer to the buffer to contain the option list.

  @return     Index               The count of the built-in options.

**/
UINT32
HttpBootBuildDhcp6Options (
  IN  HTTP_BOOT_PRIVATE_DATA       *Private,
  OUT EFI_DHCP6_PACKET_OPTION      **OptList,
  IN  UINT8                        *Buffer
  )
{
  HTTP_BOOT_DHCP6_OPTION_ENTRY     OptEnt;
  UINT16                           Value;
  UINT32                           Index;

  Index      = 0;
  OptList[0] = (EFI_DHCP6_PACKET_OPTION *) Buffer;

  //
  // Append client option request option
  //
  OptList[Index]->OpCode     = HTONS (DHCP6_OPT_ORO);
  OptList[Index]->OpLen      = HTONS (8);
  OptEnt.Oro                 = (HTTP_BOOT_DHCP6_OPTION_ORO *) OptList[Index]->Data;
  OptEnt.Oro->OpCode[0]      = HTONS(DHCP6_OPT_BOOT_FILE_URL);
  OptEnt.Oro->OpCode[1]      = HTONS(DHCP6_OPT_BOOT_FILE_PARAM);
  OptEnt.Oro->OpCode[2]      = HTONS(DHCP6_OPT_DNS_SERVERS);
  OptEnt.Oro->OpCode[3]      = HTONS(DHCP6_OPT_VENDOR_CLASS);
  Index++;
  OptList[Index]             = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);

  //
  // Append client network device interface option
  //
  OptList[Index]->OpCode     = HTONS (DHCP6_OPT_UNDI);
  OptList[Index]->OpLen      = HTONS ((UINT16)3);
  OptEnt.Undi                = (HTTP_BOOT_DHCP6_OPTION_UNDI *) OptList[Index]->Data;

  if (Private->Nii != NULL) {
    OptEnt.Undi->Type        = Private->Nii->Type;
    OptEnt.Undi->MajorVer    = Private->Nii->MajorVer;
    OptEnt.Undi->MinorVer    = Private->Nii->MinorVer;
  } else {
    OptEnt.Undi->Type        = DEFAULT_UNDI_TYPE;
    OptEnt.Undi->MajorVer    = DEFAULT_UNDI_MAJOR;
    OptEnt.Undi->MinorVer    = DEFAULT_UNDI_MINOR;
  }

  Index++;
  OptList[Index]             = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);

  //
  // Append client system architecture option
  //
  OptList[Index]->OpCode     = HTONS (DHCP6_OPT_ARCH);
  OptList[Index]->OpLen      = HTONS ((UINT16) sizeof (HTTP_BOOT_DHCP6_OPTION_ARCH));
  OptEnt.Arch                = (HTTP_BOOT_DHCP6_OPTION_ARCH *) OptList[Index]->Data;
  Value                      = HTONS (EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE);
  CopyMem (&OptEnt.Arch->Type, &Value, sizeof (UINT16));
  Index++;
  OptList[Index]             = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);

  //
  // Append vendor class identify option.
  //
  OptList[Index]->OpCode       = HTONS (DHCP6_OPT_VENDOR_CLASS);
  OptList[Index]->OpLen        = HTONS ((UINT16) sizeof (HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS));
  OptEnt.VendorClass           = (HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS *) OptList[Index]->Data;
  OptEnt.VendorClass->Vendor   = HTONL (HTTP_BOOT_DHCP6_ENTERPRISE_NUM);
  OptEnt.VendorClass->ClassLen = HTONS ((UINT16) sizeof (HTTP_BOOT_CLASS_ID));
  CopyMem (
    &OptEnt.VendorClass->ClassId,
    DEFAULT_CLASS_ID_DATA,
    sizeof (HTTP_BOOT_CLASS_ID)
    );
  HttpBootUintnToAscDecWithFormat (
    EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE,
    OptEnt.VendorClass->ClassId.ArchitectureType,
    sizeof (OptEnt.VendorClass->ClassId.ArchitectureType)
    );

  if (Private->Nii != NULL) {
    CopyMem (
      OptEnt.VendorClass->ClassId.InterfaceName,
      Private->Nii->StringId,
      sizeof (OptEnt.VendorClass->ClassId.InterfaceName)
      );
    HttpBootUintnToAscDecWithFormat (
      Private->Nii->MajorVer,
      OptEnt.VendorClass->ClassId.UndiMajor,
      sizeof (OptEnt.VendorClass->ClassId.UndiMajor)
      );
    HttpBootUintnToAscDecWithFormat (
      Private->Nii->MinorVer,
      OptEnt.VendorClass->ClassId.UndiMinor,
      sizeof (OptEnt.VendorClass->ClassId.UndiMinor)
      );
  }

  Index++;

  return Index;
}

/**
  Parse out a DHCPv6 option by OptTag, and find the position in buffer.

  @param[in]  Buffer        The pointer to the option buffer.
  @param[in]  Length        Length of the option buffer.
  @param[in]  OptTag        The required option tag.

  @retval     NULL          Failed to parse the required option.
  @retval     Others        The postion of the required option in buffer.

**/
EFI_DHCP6_PACKET_OPTION *
HttpBootParseDhcp6Options (
  IN UINT8                       *Buffer,
  IN UINT32                      Length,
  IN UINT16                      OptTag
  )
{
  EFI_DHCP6_PACKET_OPTION        *Option;
  UINT32                         Offset;

  Option  = (EFI_DHCP6_PACKET_OPTION *) Buffer;
  Offset  = 0;

  //
  // OpLen and OpCode here are both stored in network order.
  //
  while (Offset < Length) {

    if (NTOHS (Option->OpCode) == OptTag) {

      return Option;
    }

    Offset += (NTOHS(Option->OpLen) + 4);
    Option  = (EFI_DHCP6_PACKET_OPTION *) (Buffer + Offset);
  }

  return NULL;

}

/**
  Parse the cached DHCPv6 packet, including all the options.

  @param[in]  Cache6           The pointer to a cached DHCPv6 packet.

  @retval     EFI_SUCCESS      Parsed the DHCPv6 packet successfully.
  @retval     EFI_DEVICE_ERROR Failed to parse and invalid the packet.

**/
EFI_STATUS
HttpBootParseDhcp6Packet (
  IN  HTTP_BOOT_DHCP6_PACKET_CACHE    *Cache6
  )
{
  EFI_DHCP6_PACKET               *Offer;
  EFI_DHCP6_PACKET_OPTION        **Options;
  EFI_DHCP6_PACKET_OPTION        *Option;
  HTTP_BOOT_OFFER_TYPE           OfferType;
  EFI_IPv6_ADDRESS               IpAddr;
  BOOLEAN                        IsProxyOffer;
  BOOLEAN                        IsHttpOffer;
  BOOLEAN                        IsDnsOffer;
  BOOLEAN                        IpExpressedUri;
  EFI_STATUS                     Status;
  UINT32                         Offset;
  UINT32                         Length;
  
  IsDnsOffer     = FALSE;
  IpExpressedUri = FALSE;
  IsProxyOffer   = TRUE;
  IsHttpOffer    = FALSE;
  Offer        = &Cache6->Packet.Offer;
  Options      = Cache6->OptList;
  
  ZeroMem (Cache6->OptList, sizeof (Cache6->OptList));

  Option  = (EFI_DHCP6_PACKET_OPTION *) (Offer->Dhcp6.Option);
  Offset  = 0;
  Length  = GET_DHCP6_OPTION_SIZE (Offer);

  //
  // OpLen and OpCode here are both stored in network order, since they are from original packet.
  //
  while (Offset < Length) {

    if (NTOHS (Option->OpCode) == DHCP6_OPT_IA_NA) {
      Options[HTTP_BOOT_DHCP6_IDX_IA_NA] = Option;
    } else if (NTOHS (Option->OpCode) == DHCP6_OPT_BOOT_FILE_URL) {
      //
      // The server sends this option to inform the client about an URL to a boot file.
      //
      Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL] = Option;
    } else if (NTOHS (Option->OpCode) == DHCP6_OPT_BOOT_FILE_PARAM) {
      Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_PARAM] = Option;
    } else if (NTOHS (Option->OpCode) == DHCP6_OPT_VENDOR_CLASS) {
      Options[HTTP_BOOT_DHCP6_IDX_VENDOR_CLASS] = Option;
    } else if (NTOHS (Option->OpCode) == DHCP6_OPT_DNS_SERVERS) {
      Options[HTTP_BOOT_DHCP6_IDX_DNS_SERVER] = Option;
    }

    Offset += (NTOHS (Option->OpLen) + 4);
    Option  = (EFI_DHCP6_PACKET_OPTION *) (Offer->Dhcp6.Option + Offset);
  }
  //
  // The offer with assigned client address is NOT a proxy offer.
  // An ia_na option, embeded with valid ia_addr option and a status_code of success.
  //
  Option = Options[HTTP_BOOT_DHCP6_IDX_IA_NA];
  if (Option != NULL) {
    Option = HttpBootParseDhcp6Options (
               Option->Data + 12,
               NTOHS (Option->OpLen),
               DHCP6_OPT_STATUS_CODE
               );
    if ((Option != NULL && Option->Data[0] == 0) || (Option == NULL)) {
      IsProxyOffer = FALSE;
    }
  }

  //
  // The offer with "HTTPClient" is a Http offer.
  //
  Option = Options[HTTP_BOOT_DHCP6_IDX_VENDOR_CLASS];

  if (Option != NULL &&
      NTOHS(Option->OpLen) >= 16 &&
      CompareMem ((Option->Data + 6), DEFAULT_CLASS_ID_DATA, 10) == 0) {
      IsHttpOffer = TRUE;
  }

  //
  // The offer with Domain Server is a DNS offer.
  //
  Option = Options[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];
  if (Option != NULL) {
    IsDnsOffer = TRUE;
  }

  //
  // Http offer must have a boot URI.
  //
  if (IsHttpOffer && Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL] == NULL) {
    return EFI_DEVICE_ERROR;
  }
 
  //
  // Try to retrieve the IP of HTTP server from URI. 
  //
  if (IsHttpOffer) {
    Status = HttpParseUrl (
               (CHAR8*) Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,
               (UINT32) AsciiStrLen ((CHAR8*) Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data),
               FALSE,
               &Cache6->UriParser
               );
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    Status = HttpUrlGetIp6 (
               (CHAR8*) Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,
               Cache6->UriParser,
               &IpAddr
               );
    IpExpressedUri = !EFI_ERROR (Status);
  }

  //
  // Determine offer type of the DHCPv6 packet.
  //
  if (IsHttpOffer) {
    if (IpExpressedUri) {
      if (IsProxyOffer) {
        OfferType = HttpOfferTypeProxyIpUri;
      } else {
        OfferType = IsDnsOffer ? HttpOfferTypeDhcpIpUriDns : HttpOfferTypeDhcpIpUri;
      }
    } else {
      if (!IsProxyOffer) {
        OfferType = IsDnsOffer ? HttpOfferTypeDhcpNameUriDns : HttpOfferTypeDhcpNameUri;
      } else {
        OfferType = HttpOfferTypeProxyNameUri;
      }
    }

  } else {
    if (!IsProxyOffer) {
      OfferType = IsDnsOffer ? HttpOfferTypeDhcpDns : HttpOfferTypeDhcpOnly;
    } else {
      return EFI_DEVICE_ERROR;
    }
  }
  
  Cache6->OfferType = OfferType;
  return EFI_SUCCESS;
}

/**
  Cache the DHCPv6 packet.

  @param[in]  Dst          The pointer to the cache buffer for DHCPv6 packet.
  @param[in]  Src          The pointer to the DHCPv6 packet to be cached.

  @retval     EFI_SUCCESS                Packet is copied.
  @retval     EFI_BUFFER_TOO_SMALL       Cache buffer is not big enough to hold the packet.

**/
EFI_STATUS
HttpBootCacheDhcp6Packet (
  IN EFI_DHCP6_PACKET          *Dst,
  IN EFI_DHCP6_PACKET          *Src
  )
{
  if (Dst->Size < Src->Length) {
    return EFI_BUFFER_TOO_SMALL;
  }

  CopyMem (&Dst->Dhcp6, &Src->Dhcp6, Src->Length);
  Dst->Length = Src->Length;
  
  return EFI_SUCCESS;
}

/**
  Cache all the received DHCPv6 offers, and set OfferIndex and OfferCount.

  @param[in]  Private               The pointer to HTTP_BOOT_PRIVATE_DATA.
  @param[in]  RcvdOffer             The pointer to the received offer packet.

  @retval     EFI_SUCCESS      Cache and parse the packet successfully.
  @retval     Others           Operation failed.

**/
EFI_STATUS
HttpBootCacheDhcp6Offer (
  IN HTTP_BOOT_PRIVATE_DATA  *Private,
  IN EFI_DHCP6_PACKET        *RcvdOffer
  )
{
  HTTP_BOOT_DHCP6_PACKET_CACHE   *Cache6;
  EFI_DHCP6_PACKET               *Offer;
  HTTP_BOOT_OFFER_TYPE           OfferType;
  EFI_STATUS                     Status;

  Cache6 = &Private->OfferBuffer[Private->OfferNum].Dhcp6;
  Offer  = &Cache6->Packet.Offer;

  //
  // Cache the content of DHCPv6 packet firstly.
  //
  Status = HttpBootCacheDhcp6Packet(Offer, RcvdOffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Validate the DHCPv6 packet, and parse the options and offer type.
  //
  if (EFI_ERROR (HttpBootParseDhcp6Packet (Cache6))) {
    return EFI_ABORTED;
  }

  //
  // Determine whether cache the current offer by type, and record OfferIndex and OfferCount.
  //
  OfferType = Cache6->OfferType;
  ASSERT (OfferType < HttpOfferTypeMax);
  ASSERT (Private->OfferCount[OfferType] < HTTP_BOOT_OFFER_MAX_NUM);
  Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;
  Private->OfferCount[OfferType]++;
  Private->OfferNum++;
  
  return EFI_SUCCESS;
}

/**
  EFI_DHCP6_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol driver
  to intercept events that occurred in the configuration process.

  @param[in]  This              The pointer to the EFI DHCPv6 Protocol.
  @param[in]  Context           The pointer to the context set by EFI_DHCP6_PROTOCOL.Configure().
  @param[in]  CurrentState      The current operational state of the EFI DHCPv Protocol driver.
  @param[in]  Dhcp6Event        The event that occurs in the current state, which usually means a
                                state transition.
  @param[in]  Packet            The DHCPv6 packet that is going to be sent or was already received.
  @param[out] NewPacket         The packet that is used to replace the Packet above.

  @retval EFI_SUCCESS           Told the EFI DHCPv6 Protocol driver to continue the DHCP process.
  @retval EFI_NOT_READY         Only used in the Dhcp6Selecting state. The EFI DHCPv6 Protocol
                                driver will continue to wait for more packets.
  @retval EFI_ABORTED           Told the EFI DHCPv6 Protocol driver to abort the current process.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources.

**/
EFI_STATUS
EFIAPI
HttpBootDhcp6CallBack (
  IN  EFI_DHCP6_PROTOCOL           *This,
  IN  VOID                         *Context,
  IN  EFI_DHCP6_STATE              CurrentState,
  IN  EFI_DHCP6_EVENT              Dhcp6Event,
  IN  EFI_DHCP6_PACKET             *Packet,
  OUT EFI_DHCP6_PACKET             **NewPacket     OPTIONAL
  )
{
  HTTP_BOOT_PRIVATE_DATA          *Private;
  EFI_DHCP6_PACKET                *SelectAd;
  EFI_STATUS                      Status;
  BOOLEAN                         Received;
  
  if ((Dhcp6Event != Dhcp6SendSolicit) &&
    (Dhcp6Event != Dhcp6RcvdAdvertise) &&
    (Dhcp6Event != Dhcp6SendRequest) &&
    (Dhcp6Event != Dhcp6RcvdReply) &&
    (Dhcp6Event != Dhcp6SelectAdvertise)) {
    return EFI_SUCCESS;
  }

  ASSERT (Packet != NULL);
  
  Private     = (HTTP_BOOT_PRIVATE_DATA *) Context;
  Status = EFI_SUCCESS;
  if (Private->HttpBootCallback != NULL && Dhcp6Event != Dhcp6SelectAdvertise) {
    Received = (BOOLEAN) (Dhcp6Event == Dhcp6RcvdAdvertise || Dhcp6Event == Dhcp6RcvdReply);
    Status = Private->HttpBootCallback->Callback (
               Private->HttpBootCallback, 
               HttpBootDhcp6,
               Received,
               Packet->Length,
               &Packet->Dhcp6
               );
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }
  }
  switch (Dhcp6Event) {
   
  case Dhcp6RcvdAdvertise:
    Status = EFI_NOT_READY;
    if (Packet->Length > HTTP_BOOT_DHCP6_PACKET_MAX_SIZE) {
      //
      // Ignore the incoming packets which exceed the maximum length.
      //
      break;
    }
    if (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM) {
      //
      // Cache the dhcp offers to OfferBuffer[] for select later, and record
      // the OfferIndex and OfferCount.
      // If error happens, just ignore this packet and continue to wait more offer.
      //
      HttpBootCacheDhcp6Offer (Private, Packet);
    }
    break;

  case Dhcp6SelectAdvertise:
    //
    // Select offer by the default policy or by order, and record the SelectIndex
    // and SelectProxyType.
    //
    HttpBootSelectDhcpOffer (Private);

    if (Private->SelectIndex == 0) {
      Status = EFI_ABORTED;
    } else {
      ASSERT (NewPacket != NULL);
      SelectAd   = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp6.Packet.Offer;
      *NewPacket = AllocateZeroPool (SelectAd->Size);
      if (*NewPacket == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      CopyMem (*NewPacket, SelectAd, SelectAd->Size);
    }
    break;
     
  default:
    break;
  }

  return Status;   
}

/**
  Check whether IP driver could route the message which will be sent to ServerIp address.
  
  This function will check the IP6 route table every 1 seconds until specified timeout is expired, if a valid
  route is found in IP6 route table, the address will be filed in GatewayAddr and return.

  @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.
  @param[in]  TimeOutInSecond     Timeout value in seconds.
  @param[out] GatewayAddr         Pointer to store the gateway IP address.

  @retval     EFI_SUCCESS         Found a valid gateway address successfully.
  @retval     EFI_TIMEOUT         The operation is time out.
  @retval     Other               Unexpect error happened.
  
**/
EFI_STATUS
HttpBootCheckRouteTable (
  IN  HTTP_BOOT_PRIVATE_DATA        *Private,
  IN  UINTN                         TimeOutInSecond,
  OUT EFI_IPv6_ADDRESS              *GatewayAddr
  )
{
  EFI_STATUS                       Status;
  EFI_IP6_PROTOCOL                 *Ip6;
  EFI_IP6_MODE_DATA                Ip6ModeData;
  UINTN                            Index;
  EFI_EVENT                        TimeOutEvt;
  UINTN                            RetryCount;
  BOOLEAN                          GatewayIsFound;

  ASSERT (GatewayAddr != NULL);
  ASSERT (Private != NULL);

  Ip6            = Private->Ip6;
  GatewayIsFound = FALSE;
  RetryCount     = 0;
  TimeOutEvt     = NULL;
  Status         = EFI_SUCCESS;
  ZeroMem (GatewayAddr, sizeof (EFI_IPv6_ADDRESS));

  while (TRUE) {
    Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
    
    //
    // Find out the gateway address which can route the message which send to ServerIp.
    //
    for (Index = 0; Index < Ip6ModeData.RouteCount; Index++) {
      if (NetIp6IsNetEqual (&Private->ServerIp.v6, &Ip6ModeData.RouteTable[Index].Destination, Ip6ModeData.RouteTable[Index].PrefixLength)) {
        IP6_COPY_ADDRESS (GatewayAddr, &Ip6ModeData.RouteTable[Index].Gateway);
        GatewayIsFound = TRUE;
        break;
      }
    }

    if (Ip6ModeData.AddressList != NULL) {
      FreePool (Ip6ModeData.AddressList);
    }
    if (Ip6ModeData.GroupTable != NULL) {
      FreePool (Ip6ModeData.GroupTable);
    }
    if (Ip6ModeData.RouteTable != NULL) {
      FreePool (Ip6ModeData.RouteTable);
    }
    if (Ip6ModeData.NeighborCache != NULL) {
      FreePool (Ip6ModeData.NeighborCache);
    }
    if (Ip6ModeData.PrefixTable != NULL) {
      FreePool (Ip6ModeData.PrefixTable);
    }
    if (Ip6ModeData.IcmpTypeList != NULL) {
      FreePool (Ip6ModeData.IcmpTypeList);
    }
    
    if (GatewayIsFound || RetryCount == TimeOutInSecond) {
      break;
    }
    
    RetryCount++;
    
    //
    // Delay 1 second then recheck it again.
    //
    if (TimeOutEvt == NULL) {
      Status = gBS->CreateEvent (
                      EVT_TIMER,
                      TPL_CALLBACK,
                      NULL,
                      NULL,
                      &TimeOutEvt
                      );
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }
    }

    Status = gBS->SetTimer (TimeOutEvt, TimerRelative, TICKS_PER_SECOND);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
    while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {
      Ip6->Poll (Ip6);
    }
  }
  
ON_EXIT:
  if (TimeOutEvt != NULL) {
    gBS->CloseEvent (TimeOutEvt);
  }
  
  if (GatewayIsFound) {
    Status = EFI_SUCCESS;
  } else if (RetryCount == TimeOutInSecond) {
    Status = EFI_TIMEOUT;
  }

  return Status; 
}

/**
  Set the IP6 policy to Automatic.

  @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.

  @retval     EFI_SUCCESS         Switch the IP policy succesfully.
  @retval     Others              Unexpect error happened.

**/
EFI_STATUS
HttpBootSetIp6Policy (
  IN HTTP_BOOT_PRIVATE_DATA        *Private
  )
{
  EFI_IP6_CONFIG_POLICY            Policy;
  EFI_IP6_CONFIG_PROTOCOL          *Ip6Config;
  EFI_STATUS                       Status;
  UINTN                            DataSize;

  Ip6Config       = Private->Ip6Config;
  DataSize        = sizeof (EFI_IP6_CONFIG_POLICY);
  
  //
  // Get and store the current policy of IP6 driver.
  //
  Status = Ip6Config->GetData (
                        Ip6Config,
                        Ip6ConfigDataTypePolicy,
                        &DataSize,
                        &Policy
                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Policy == Ip6ConfigPolicyManual) {
    Policy = Ip6ConfigPolicyAutomatic;
    Status = Ip6Config->SetData (
                          Ip6Config,
                          Ip6ConfigDataTypePolicy,
                          sizeof(EFI_IP6_CONFIG_POLICY),
                          &Policy
                          );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  return EFI_SUCCESS;
}

/**
  This function will register the default DNS addresses to the network device.
  
  @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.
  @param[in]  DataLength          Size of the buffer pointed to by DnsServerData in bytes.
  @param[in]  DnsServerData       Point a list of DNS server address in an array
                                  of EFI_IPv6_ADDRESS instances.

  @retval     EFI_SUCCESS         The DNS configuration has been configured successfully.
  @retval     Others              Failed to configure the address.

**/
EFI_STATUS
HttpBootSetIp6Dns (
  IN HTTP_BOOT_PRIVATE_DATA         *Private,
  IN UINTN                          DataLength,
  IN VOID                           *DnsServerData
  )
{
  EFI_IP6_CONFIG_PROTOCOL        *Ip6Config;
  
  ASSERT (Private->UsingIpv6);

  Ip6Config = Private->Ip6Config;
  
  return Ip6Config->SetData (
                      Ip6Config,
                      Ip6ConfigDataTypeDnsServer,
                      DataLength,
                      DnsServerData
                      );
}

/**
  This function will register the IPv6 gateway address to the network device.
  
  @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.

  @retval     EFI_SUCCESS         The new IP configuration has been configured successfully.
  @retval     Others              Failed to configure the address.

**/
EFI_STATUS
HttpBootSetIp6Gateway (
  IN HTTP_BOOT_PRIVATE_DATA         *Private
  )
{
  EFI_IP6_CONFIG_PROTOCOL           *Ip6Config;
  EFI_STATUS                        Status;

  ASSERT (Private->UsingIpv6);
  Ip6Config = Private->Ip6Config;
 
  //
  // Set the default gateway address. 
  //
  if (!Private->NoGateway && !NetIp6IsUnspecifiedAddr (&Private->GatewayIp.v6)) {
    Status = Ip6Config->SetData (
                          Ip6Config,
                          Ip6ConfigDataTypeGateway,
                          sizeof (EFI_IPv6_ADDRESS),
                          &Private->GatewayIp.v6
                          );
    if (EFI_ERROR(Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  This function will register the station IP address.
  
  @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.

  @retval     EFI_SUCCESS         The new IP address has been configured successfully.
  @retval     Others              Failed to configure the address.

**/
EFI_STATUS
HttpBootSetIp6Address (
  IN HTTP_BOOT_PRIVATE_DATA         *Private
)
{
  EFI_STATUS                         Status;
  EFI_IP6_PROTOCOL                   *Ip6;
  EFI_IP6_CONFIG_PROTOCOL            *Ip6Cfg;
  EFI_IP6_CONFIG_POLICY              Policy;
  EFI_IP6_CONFIG_MANUAL_ADDRESS      CfgAddr;
  EFI_IPv6_ADDRESS                   *Ip6Addr;
  EFI_IPv6_ADDRESS                   GatewayAddr;
  EFI_IP6_CONFIG_DATA                Ip6CfgData;
  EFI_EVENT                          MappedEvt; 
  UINTN                              DataSize;
  BOOLEAN                            IsAddressOk;
  UINTN                              Index;

  ASSERT (Private->UsingIpv6);
  
  MappedEvt   = NULL;
  IsAddressOk = FALSE;
  Ip6Addr     = NULL;
  Ip6Cfg      = Private->Ip6Config;
  Ip6         = Private->Ip6;
  
  ZeroMem (&CfgAddr, sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));
  CopyMem (&CfgAddr, &Private->StationIp.v6, sizeof (EFI_IPv6_ADDRESS));
  ZeroMem (&Ip6CfgData, sizeof (EFI_IP6_CONFIG_DATA));
  
  Ip6CfgData.AcceptIcmpErrors    = TRUE;
  Ip6CfgData.DefaultProtocol     = IP6_ICMP;
  Ip6CfgData.HopLimit            = HTTP_BOOT_DEFAULT_HOPLIMIT;
  Ip6CfgData.ReceiveTimeout      = HTTP_BOOT_DEFAULT_LIFETIME;
  Ip6CfgData.TransmitTimeout     = HTTP_BOOT_DEFAULT_LIFETIME;
    
  Status = Ip6->Configure (Ip6, &Ip6CfgData);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Retrieve the gateway address from IP6 route table.
  //
  Status = HttpBootCheckRouteTable (Private, HTTP_BOOT_IP6_ROUTE_TABLE_TIMEOUT, &GatewayAddr);
  if (EFI_ERROR (Status)) {
    Private->NoGateway = TRUE;
  } else {
    IP6_COPY_ADDRESS (&Private->GatewayIp.v6, &GatewayAddr);
  }

  //
  // Set the new address by Ip6ConfigProtocol manually.
  //
  Policy = Ip6ConfigPolicyManual;
  Status = Ip6Cfg->SetData (
                     Ip6Cfg,
                     Ip6ConfigDataTypePolicy,
                     sizeof(EFI_IP6_CONFIG_POLICY),
                     &Policy
                     );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  //
  // Create a notify event to set address flag when DAD if IP6 driver succeeded.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  HttpBootCommonNotify,
                  &IsAddressOk,
                  &MappedEvt
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  //
  // Set static host ip6 address. This is a asynchronous process.
  //
  Status = Ip6Cfg->RegisterDataNotify (
                     Ip6Cfg,
                     Ip6ConfigDataTypeManualAddress,
                     MappedEvt
                     );
  if (EFI_ERROR(Status)) {
    goto ON_EXIT;
  }

  Status = Ip6Cfg->SetData (
                     Ip6Cfg,
                     Ip6ConfigDataTypeManualAddress,
                     sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS),
                     &CfgAddr
                     ); 
  if (EFI_ERROR (Status) && Status != EFI_NOT_READY) {
    goto ON_EXIT;
  } else if (Status == EFI_NOT_READY) {
    //
    // Poll the network until the asynchronous process is finished.
    //
    while (!IsAddressOk) {
      Ip6->Poll (Ip6);
    }
    //
    // Check whether the Ip6 Address setting is successed.
    //
    DataSize = 0;
    Status = Ip6Cfg->GetData (
                       Ip6Cfg,
                       Ip6ConfigDataTypeManualAddress,
                       &DataSize,
                       NULL
                       );
    if (Status != EFI_BUFFER_TOO_SMALL || DataSize == 0) {
      Status = EFI_DEVICE_ERROR;
      goto ON_EXIT;
    }
    
    Ip6Addr = AllocatePool (DataSize);
    if (Ip6Addr == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    Status = Ip6Cfg->GetData (
                       Ip6Cfg,
                       Ip6ConfigDataTypeManualAddress,
                       &DataSize,
                       (VOID *) Ip6Addr
                       );
    if (EFI_ERROR (Status)) {
      Status = EFI_DEVICE_ERROR;
      goto ON_EXIT;
    }

    for (Index = 0; Index < DataSize / sizeof (EFI_IPv6_ADDRESS); Index ++) {
      if (CompareMem (Ip6Addr + Index, &CfgAddr, sizeof (EFI_IPv6_ADDRESS)) == 0) {
        break;
      }
    }
    if (Index == DataSize / sizeof (EFI_IPv6_ADDRESS)) {
      Status = EFI_ABORTED;
      goto ON_EXIT;
    } 
  }
    
ON_EXIT:
  if (MappedEvt != NULL) {
    Ip6Cfg->UnregisterDataNotify (
              Ip6Cfg,
              Ip6ConfigDataTypeManualAddress,
              MappedEvt
              );
    gBS->CloseEvent (MappedEvt);
  }

  if (Ip6Addr != NULL) {
    FreePool (Ip6Addr);
  }
  
  return Status;    
}

/**
  Start the S.A.R.R DHCPv6 process to acquire the IPv6 address and other Http boot information.

  @param[in]  Private           Pointer to HTTP_BOOT private data.

  @retval EFI_SUCCESS           The S.A.R.R process successfully finished.
  @retval Others                Failed to finish the S.A.R.R process.

**/
EFI_STATUS
HttpBootDhcp6Sarr (
  IN HTTP_BOOT_PRIVATE_DATA         *Private
  )
{
  EFI_DHCP6_PROTOCOL               *Dhcp6;
  EFI_DHCP6_CONFIG_DATA            Config;
  EFI_DHCP6_MODE_DATA              Mode;
  EFI_DHCP6_RETRANSMISSION         *Retransmit;
  EFI_DHCP6_PACKET_OPTION          *OptList[HTTP_BOOT_DHCP6_OPTION_MAX_NUM];
  UINT32                           OptCount;
  UINT8                            Buffer[HTTP_BOOT_DHCP6_OPTION_MAX_SIZE];
  EFI_STATUS                       Status;

  Dhcp6 = Private->Dhcp6;
  ASSERT (Dhcp6 != NULL);

  //
  // Build options list for the request packet.
  //
  OptCount = HttpBootBuildDhcp6Options (Private, OptList, Buffer);
  ASSERT (OptCount >0);
  
  Retransmit = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION));
  if (Retransmit == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  
  ZeroMem (&Mode, sizeof (EFI_DHCP6_MODE_DATA));
  ZeroMem (&Config, sizeof (EFI_DHCP6_CONFIG_DATA));
  
  Config.OptionCount           = OptCount;
  Config.OptionList            = OptList;
  Config.Dhcp6Callback         = HttpBootDhcp6CallBack;
  Config.CallbackContext       = Private;
  Config.IaInfoEvent           = NULL;
  Config.RapidCommit           = FALSE;
  Config.ReconfigureAccept     = FALSE;
  Config.IaDescriptor.IaId     = NET_RANDOM (NetRandomInitSeed ());
  Config.IaDescriptor.Type     = EFI_DHCP6_IA_TYPE_NA;
  Config.SolicitRetransmission = Retransmit;
  Retransmit->Irt              = 4;
  Retransmit->Mrc              = 4;
  Retransmit->Mrt              = 32;
  Retransmit->Mrd              = 60;
  
  //
  // Configure the DHCPv6 instance for HTTP boot.
  //
  Status = Dhcp6->Configure (Dhcp6, &Config);
  FreePool (Retransmit);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  //
  // Initialize the record fields for DHCPv6 offer in private data.
  //
  Private->OfferNum      = 0;
  Private->SelectIndex   = 0;
  ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
  ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));
  
  //
  // Start DHCPv6 S.A.R.R. process to acquire IPv6 address.
  //
  Status = Dhcp6->Start (Dhcp6);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  //
  // Get the acquired IPv6 address and store them.
  //
  Status = Dhcp6->GetModeData (Dhcp6, &Mode, NULL);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  
  ASSERT (Mode.Ia->State == Dhcp6Bound);
  CopyMem (&Private->StationIp.v6, &Mode.Ia->IaAddress[0].IpAddress, sizeof (EFI_IPv6_ADDRESS));
  
  AsciiPrint ("\n  Station IPv6 address is ");
  HttpBootShowIp6Addr (&Private->StationIp.v6);
  AsciiPrint ("\n");
  
ON_EXIT:
  if (EFI_ERROR (Status)) {
    Dhcp6->Stop (Dhcp6);
    Dhcp6->Configure (Dhcp6, NULL);
  } else {
    ZeroMem (&Config, sizeof (EFI_DHCP6_CONFIG_DATA));
    Dhcp6->Configure (Dhcp6, &Config);
    if (Mode.ClientId != NULL) {
      FreePool (Mode.ClientId);
    }
    if (Mode.Ia != NULL) {
      FreePool (Mode.Ia);
    }
  }

  return Status; 
    
}

