/** @file
  Functions implementation related with DHCPv4 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"

//
// This is a map from the interested DHCP4 option tags' index to the tag value.
//
UINT8 mInterestedDhcp4Tags[HTTP_BOOT_DHCP4_TAG_INDEX_MAX] = {
  DHCP4_TAG_BOOTFILE_LEN,
  DHCP4_TAG_OVERLOAD,
  DHCP4_TAG_MSG_TYPE,
  DHCP4_TAG_SERVER_ID,
  DHCP4_TAG_VENDOR_CLASS_ID,
  DHCP4_TAG_BOOTFILE,
  DHCP4_TAG_DNS_SERVER
};

//
// There are 4 times retries with the value of 4, 8, 16 and 32, refers to UEFI 2.5 spec.
//
UINT32 mHttpDhcpTimeout[4] = {4, 8, 16, 32};

/**
  Build the options buffer for the DHCPv4 request packet.

  @param[in]  Private             Pointer to HTTP boot driver private data.
  @param[out] OptList             Pointer to the option pointer array.
  @param[in]  Buffer              Pointer to the buffer to contain the option list.

  @return     Index               The count of the built-in options.

**/
UINT32
HttpBootBuildDhcp4Options (
  IN  HTTP_BOOT_PRIVATE_DATA        *Private,
  OUT EFI_DHCP4_PACKET_OPTION       **OptList,
  IN  UINT8                         *Buffer
  )
{
  HTTP_BOOT_DHCP4_OPTION_ENTRY  OptEnt;
  UINT16                        Value;
  UINT32                        Index;

  Index      = 0;
  OptList[0] = (EFI_DHCP4_PACKET_OPTION *) Buffer;

  //
  // Append parameter request list option.
  //
  OptList[Index]->OpCode    = DHCP4_TAG_PARA_LIST;
  OptList[Index]->Length    = 27;
  OptEnt.Para               = (HTTP_BOOT_DHCP4_OPTION_PARA *) OptList[Index]->Data;
  OptEnt.Para->ParaList[0]  = DHCP4_TAG_NETMASK;
  OptEnt.Para->ParaList[1]  = DHCP4_TAG_TIME_OFFSET;
  OptEnt.Para->ParaList[2]  = DHCP4_TAG_ROUTER;
  OptEnt.Para->ParaList[3]  = DHCP4_TAG_TIME_SERVER;
  OptEnt.Para->ParaList[4]  = DHCP4_TAG_NAME_SERVER;
  OptEnt.Para->ParaList[5]  = DHCP4_TAG_DNS_SERVER;
  OptEnt.Para->ParaList[6]  = DHCP4_TAG_HOSTNAME;
  OptEnt.Para->ParaList[7]  = DHCP4_TAG_BOOTFILE_LEN;
  OptEnt.Para->ParaList[8]  = DHCP4_TAG_DOMAINNAME;
  OptEnt.Para->ParaList[9]  = DHCP4_TAG_ROOTPATH;
  OptEnt.Para->ParaList[10] = DHCP4_TAG_EXTEND_PATH;
  OptEnt.Para->ParaList[11] = DHCP4_TAG_EMTU;
  OptEnt.Para->ParaList[12] = DHCP4_TAG_TTL;
  OptEnt.Para->ParaList[13] = DHCP4_TAG_BROADCAST;
  OptEnt.Para->ParaList[14] = DHCP4_TAG_NIS_DOMAIN;
  OptEnt.Para->ParaList[15] = DHCP4_TAG_NIS_SERVER;
  OptEnt.Para->ParaList[16] = DHCP4_TAG_NTP_SERVER;
  OptEnt.Para->ParaList[17] = DHCP4_TAG_VENDOR;
  OptEnt.Para->ParaList[18] = DHCP4_TAG_REQUEST_IP;
  OptEnt.Para->ParaList[19] = DHCP4_TAG_LEASE;
  OptEnt.Para->ParaList[20] = DHCP4_TAG_SERVER_ID;
  OptEnt.Para->ParaList[21] = DHCP4_TAG_T1;
  OptEnt.Para->ParaList[22] = DHCP4_TAG_T2;
  OptEnt.Para->ParaList[23] = DHCP4_TAG_VENDOR_CLASS_ID;
  OptEnt.Para->ParaList[25] = DHCP4_TAG_BOOTFILE;
  OptEnt.Para->ParaList[26] = DHCP4_TAG_UUID;
  Index++;
  OptList[Index]            = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);

  //
  // Append UUID/Guid-based client identifier option
  //
  OptList[Index]->OpCode  = DHCP4_TAG_UUID;
  OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_UUID);
  OptEnt.Uuid             = (HTTP_BOOT_DHCP4_OPTION_UUID *) OptList[Index]->Data;
  OptEnt.Uuid->Type       = 0;
  if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *) OptEnt.Uuid->Guid))) {
    //
    // Zero the Guid to indicate NOT programable if failed to get system Guid.
    //
    ZeroMem (OptEnt.Uuid->Guid, sizeof (EFI_GUID));
  }
  Index++;
  OptList[Index]          = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);

  //
  // Append client network device interface option
  //
  OptList[Index]->OpCode  = DHCP4_TAG_UNDI;
  OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_UNDI);
  OptEnt.Undi             = (HTTP_BOOT_DHCP4_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_DHCP_OPTION (OptList[Index - 1]);

  //
  // Append client system architecture option
  //
  OptList[Index]->OpCode  = DHCP4_TAG_ARCH;
  OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_ARCH);
  OptEnt.Arch             = (HTTP_BOOT_DHCP4_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_DHCP_OPTION (OptList[Index - 1]);

  //
  // Append vendor class identify option
  //
  OptList[Index]->OpCode  = DHCP4_TAG_VENDOR_CLASS_ID;
  OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_CLID);
  OptEnt.Clid             = (HTTP_BOOT_DHCP4_OPTION_CLID *) OptList[Index]->Data;
  CopyMem (
    OptEnt.Clid,
    DEFAULT_CLASS_ID_DATA,
    sizeof (HTTP_BOOT_DHCP4_OPTION_CLID)
    );
  HttpBootUintnToAscDecWithFormat (
    EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE,
    OptEnt.Clid->ArchitectureType,
    sizeof (OptEnt.Clid->ArchitectureType)
    );

  if (Private->Nii != NULL) {
    CopyMem (OptEnt.Clid->InterfaceName, Private->Nii->StringId, sizeof (OptEnt.Clid->InterfaceName));
    HttpBootUintnToAscDecWithFormat (Private->Nii->MajorVer, OptEnt.Clid->UndiMajor, sizeof (OptEnt.Clid->UndiMajor));
    HttpBootUintnToAscDecWithFormat (Private->Nii->MinorVer, OptEnt.Clid->UndiMinor, sizeof (OptEnt.Clid->UndiMinor));
  }

  Index++;

  return Index;
}

/**
  Parse a certain dhcp4 option by OptTag in Buffer, and return with start pointer.

  @param[in]  Buffer              Pointer to the option buffer.
  @param[in]  Length              Length of the option buffer.
  @param[in]  OptTag              Tag of the required option.

  @retval     NULL                Failed to find the required option.
  @retval     Others              The position of the required option.

**/
EFI_DHCP4_PACKET_OPTION *
HttpBootParseDhcp4Options (
  IN UINT8                      *Buffer,
  IN UINT32                     Length,
  IN UINT8                      OptTag
  )
{
  EFI_DHCP4_PACKET_OPTION       *Option;
  UINT32                        Offset;

  Option  = (EFI_DHCP4_PACKET_OPTION *) Buffer;
  Offset  = 0;

  while (Offset < Length && Option->OpCode != DHCP4_TAG_EOP) {

    if (Option->OpCode == OptTag) {
      //
      // Found the required option.
      //
      return Option;
    }

    //
    // Skip the current option to the next.
    //
    if (Option->OpCode == DHCP4_TAG_PAD) {
      Offset++;
    } else {
      Offset += Option->Length + 2;
    }

    Option = (EFI_DHCP4_PACKET_OPTION *) (Buffer + Offset);
  }

  return NULL;
}

/**
  Cache the DHCPv4 packet.

  @param[in]  Dst          Pointer to the cache buffer for DHCPv4 packet.
  @param[in]  Src          Pointer to the DHCPv4 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
HttpBootCacheDhcp4Packet (
  IN EFI_DHCP4_PACKET     *Dst,
  IN EFI_DHCP4_PACKET     *Src
  )
{
  if (Dst->Size < Src->Length) {
    return EFI_BUFFER_TOO_SMALL;
  }

  CopyMem (&Dst->Dhcp4, &Src->Dhcp4, Src->Length);
  Dst->Length = Src->Length;

  return EFI_SUCCESS;
}

/**
  Parse the cached DHCPv4 packet, including all the options.

  @param[in]  Cache4           Pointer to cached DHCPv4 packet.

  @retval     EFI_SUCCESS      Parsed the DHCPv4 packet successfully.
  @retval     EFI_DEVICE_ERROR Failed to parse an invalid packet.

**/
EFI_STATUS
HttpBootParseDhcp4Packet (
  IN HTTP_BOOT_DHCP4_PACKET_CACHE    *Cache4
  )
{
  EFI_DHCP4_PACKET               *Offer;
  EFI_DHCP4_PACKET_OPTION        **Options;
  UINTN                          Index;
  EFI_DHCP4_PACKET_OPTION        *Option;
  BOOLEAN                        IsProxyOffer;
  BOOLEAN                        IsHttpOffer;
  BOOLEAN                        IsDnsOffer;
  BOOLEAN                        IpExpressedUri;
  UINT8                          *Ptr8;
  EFI_STATUS                     Status;
  HTTP_BOOT_OFFER_TYPE           OfferType;
  EFI_IPv4_ADDRESS               IpAddr;
  BOOLEAN                        FileFieldOverloaded;
  
  IsDnsOffer     = FALSE;
  IpExpressedUri = FALSE;
  IsProxyOffer   = FALSE;
  IsHttpOffer    = FALSE;
  FileFieldOverloaded = FALSE;

  ZeroMem (Cache4->OptList, sizeof (Cache4->OptList));

  Offer   = &Cache4->Packet.Offer;
  Options = Cache4->OptList;

  //
  // Parse DHCPv4 options in this offer, and store the pointers.
  // First, try to parse DHCPv4 options from the DHCP optional parameters field.
  //
  for (Index = 0; Index < HTTP_BOOT_DHCP4_TAG_INDEX_MAX; Index++) {
    Options[Index] = HttpBootParseDhcp4Options (
                       Offer->Dhcp4.Option,
                       GET_OPTION_BUFFER_LEN (Offer),
                       mInterestedDhcp4Tags[Index]
                       );
  }
  //
  // Second, Check if bootfilename and serverhostname is overloaded to carry DHCP options refers to rfc-2132. 
  // If yes, try to parse options from the BootFileName field, then ServerName field.
  //
  Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_OVERLOAD];
  if (Option != NULL) {
    if ((Option->Data[0] & HTTP_BOOT_DHCP4_OVERLOAD_FILE) != 0) {
      FileFieldOverloaded = TRUE;
      for (Index = 0; Index < HTTP_BOOT_DHCP4_TAG_INDEX_MAX; Index++) {
        if (Options[Index] == NULL) {
          Options[Index] = HttpBootParseDhcp4Options (
                             (UINT8 *) Offer->Dhcp4.Header.BootFileName,
                             sizeof (Offer->Dhcp4.Header.BootFileName),
                             mInterestedDhcp4Tags[Index]
                             );
        }
      }
    }
    if ((Option->Data[0] & HTTP_BOOT_DHCP4_OVERLOAD_SERVER_NAME) != 0) {
      for (Index = 0; Index < HTTP_BOOT_DHCP4_TAG_INDEX_MAX; Index++) {
        if (Options[Index] == NULL) {
          Options[Index] = HttpBootParseDhcp4Options (
                             (UINT8 *) Offer->Dhcp4.Header.ServerName,
                             sizeof (Offer->Dhcp4.Header.ServerName),
                             mInterestedDhcp4Tags[Index]
                             );
        }
      }
    }
  }

  //
  // The offer with "yiaddr" is a proxy offer.
  //
  if (Offer->Dhcp4.Header.YourAddr.Addr[0] == 0) {
    IsProxyOffer = TRUE;
  }

  //
  // The offer with "HTTPClient" is a Http offer.
  //
  Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_CLASS_ID];
  if ((Option != NULL) && (Option->Length >= 9) &&
      (CompareMem (Option->Data, DEFAULT_CLASS_ID_DATA, 9) == 0)) {
    IsHttpOffer = TRUE;
  }

  //
  // The offer with Domain Server is a DNS offer.
  //
  Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER];
  if (Option != NULL) {
    IsDnsOffer = TRUE;
  }

  //
  // Parse boot file name:
  // Boot URI information is provided thru 'file' field in DHCP Header or option 67.
  // According to RFC 2132, boot file name should be read from DHCP option 67 (bootfile name) if present.
  // Otherwise, read from boot file field in DHCP header.
  //
  if (Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
    //
    // RFC 2132, Section 9.5 does not strictly state Bootfile name (option 67) is null
    // terminated string. So force to append null terminated character at the end of string.
    //
    Ptr8 =  (UINT8*)&Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data[0];
    Ptr8 += Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Length;
    if (*(Ptr8 - 1) != '\0') {
      *Ptr8 = '\0';
    }
  } else if (!FileFieldOverloaded && Offer->Dhcp4.Header.BootFileName[0] != 0) {
    //
    // If the bootfile is not present and bootfilename is present in DHCPv4 packet, just parse it.
    // Do not count dhcp option header here, or else will destroy the serverhostname.
    //
    Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE] = (EFI_DHCP4_PACKET_OPTION *)
                                                    (&Offer->Dhcp4.Header.BootFileName[0] -
                                                    OFFSET_OF (EFI_DHCP4_PACKET_OPTION, Data[0]));
  }

  //
  // Http offer must have a boot URI.
  //
  if (IsHttpOffer && Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE] == NULL) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Try to retrieve the IP of HTTP server from URI. 
  //
  if (IsHttpOffer) {
    Status = HttpParseUrl (
               (CHAR8*) Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data,
               (UINT32) AsciiStrLen ((CHAR8*) Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data),
               FALSE,
               &Cache4->UriParser
               );
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    Status = HttpUrlGetIp4 (
               (CHAR8*) Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data,
               Cache4->UriParser,
               &IpAddr
               );
    IpExpressedUri = !EFI_ERROR (Status);
  }

  //
  // Determine offer type of the DHCPv4 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 {
      if (Cache4->UriParser != NULL) {
        FreePool (Cache4->UriParser);
      }
      return EFI_DEVICE_ERROR;
    }
  }
  
  Cache4->OfferType = OfferType;
  return EFI_SUCCESS;
}

/**
  Cache all the received DHCPv4 offers, and set OfferIndex and OfferCount.

  @param[in]  Private               Pointer to HTTP boot driver private data.
  @param[in]  RcvdOffer             Pointer to the received offer packet.

  @retval     EFI_SUCCESS      Cache and parse the packet successfully.
  @retval     Others           Operation failed.
**/
EFI_STATUS
HttpBootCacheDhcp4Offer (
  IN HTTP_BOOT_PRIVATE_DATA  *Private,
  IN EFI_DHCP4_PACKET        *RcvdOffer
  )
{
  HTTP_BOOT_DHCP4_PACKET_CACHE  *Cache4;
  EFI_DHCP4_PACKET              *Offer;
  HTTP_BOOT_OFFER_TYPE          OfferType;
  EFI_STATUS                    Status;

  ASSERT (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM);
  Cache4 = &Private->OfferBuffer[Private->OfferNum].Dhcp4;
  Offer  = &Cache4->Packet.Offer;

  //
  // Cache the content of DHCPv4 packet firstly.
  //
  Status = HttpBootCacheDhcp4Packet (Offer, RcvdOffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Validate the DHCPv4 packet, and parse the options and offer type.
  //
  if (EFI_ERROR (HttpBootParseDhcp4Packet (Cache4))) {
    return EFI_ABORTED;
  }

  //
  // Determine whether cache the current offer by type, and record OfferIndex and OfferCount.
  //
  OfferType = Cache4->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;
}

/**
  Select an DHCPv4 or DHCP6 offer, and record SelectIndex and SelectProxyType.

  @param[in]  Private             Pointer to HTTP boot driver private data.

**/
VOID
HttpBootSelectDhcpOffer (
  IN HTTP_BOOT_PRIVATE_DATA  *Private
  )
{
  Private->SelectIndex = 0;
  Private->SelectProxyType = HttpOfferTypeMax;

  if (Private->FilePathUri != NULL) {
    //
    // We are in home environment, the URI is already specified.
    // Just need to choose a DHCP offer.
    // The offer with DNS server address takes priority here.
    //
    if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0) {
      
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
      
    } else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {
    
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;
      
    } else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
    
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
      
    }  else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0) {
    
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
      
    }  else if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
    
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
    }
    
  } else {
    //
    // We are in corporate environment.
    //
    // Priority1: HttpOfferTypeDhcpIpUri or HttpOfferTypeDhcpIpUriDns
    // Priority2: HttpOfferTypeDhcpNameUriDns                      
    // Priority3: HttpOfferTypeDhcpOnly + HttpOfferTypeProxyIpUri  
    // Priority4: HttpOfferTypeDhcpDns  + HttpOfferTypeProxyIpUri  
    // Priority5: HttpOfferTypeDhcpDns  + HttpOfferTypeProxyNameUri
    // Priority6: HttpOfferTypeDhcpDns  + HttpOfferTypeDhcpNameUri 
    //    
    if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
      
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
      
    } else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {
      
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;
      
    }else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
    
      Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
      
    } else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0 &&
               Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
               
      Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
      Private->SelectProxyType = HttpOfferTypeProxyIpUri;
      
    } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
               Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
               
      Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
      Private->SelectProxyType = HttpOfferTypeProxyIpUri;
      
    } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
               Private->OfferCount[HttpOfferTypeProxyNameUri] > 0) {
               
      Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
      Private->SelectProxyType = HttpOfferTypeProxyNameUri;
      
    } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
               Private->OfferCount[HttpOfferTypeDhcpNameUri] > 0) {
               
      Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
      Private->SelectProxyType = HttpOfferTypeDhcpNameUri;
    }
  }
}


/**
  EFI_DHCP4_CALLBACK is provided by the consumer of the EFI DHCPv4 Protocol driver
  to intercept events that occurred in the configuration process.

  @param[in]  This              Pointer to the EFI DHCPv4 Protocol.
  @param[in]  Context           Pointer to the context set by EFI_DHCP4_PROTOCOL.Configure().
  @param[in]  CurrentState      The current operational state of the EFI DHCPv4 Protocol driver.
  @param[in]  Dhcp4Event        The event that occurs in the current state, which usually means a
                                state transition.
  @param[in]  Packet            The DHCPv4 packet that is going to be sent or already received.
  @param[out] NewPacket         The packet that is used to replace the above Packet.

  @retval EFI_SUCCESS           Tells the EFI DHCPv4 Protocol driver to continue the DHCP process.
  @retval EFI_NOT_READY         Only used in the Dhcp4Selecting state. The EFI DHCPv4 Protocol
                                driver will continue to wait for more DHCPOFFER packets until the
                                retry timeout expires.
  @retval EFI_ABORTED           Tells the EFI DHCPv4 Protocol driver to abort the current process
                                and return to the Dhcp4Init or Dhcp4InitReboot state.

**/
EFI_STATUS
EFIAPI
HttpBootDhcp4CallBack (
  IN  EFI_DHCP4_PROTOCOL               *This,
  IN  VOID                             *Context,
  IN  EFI_DHCP4_STATE                  CurrentState,
  IN  EFI_DHCP4_EVENT                  Dhcp4Event,
  IN  EFI_DHCP4_PACKET                 *Packet            OPTIONAL,
  OUT EFI_DHCP4_PACKET                 **NewPacket        OPTIONAL
  )
{
  HTTP_BOOT_PRIVATE_DATA               *Private;
  EFI_DHCP4_PACKET_OPTION              *MaxMsgSize;
  UINT16                               Value;
  EFI_STATUS                           Status;
  BOOLEAN                              Received;

  if ((Dhcp4Event != Dhcp4SendDiscover) && 
      (Dhcp4Event != Dhcp4RcvdOffer) && 
      (Dhcp4Event != Dhcp4SendRequest) && 
      (Dhcp4Event != Dhcp4RcvdAck) && 
      (Dhcp4Event != Dhcp4SelectOffer)) {
    return EFI_SUCCESS;
  }
  
  Private = (HTTP_BOOT_PRIVATE_DATA *) Context;

  //
  // Override the Maximum DHCP Message Size.
  //
  MaxMsgSize = HttpBootParseDhcp4Options (
                 Packet->Dhcp4.Option,
                 GET_OPTION_BUFFER_LEN (Packet),
                 DHCP4_TAG_MAXMSG
                 );
  if (MaxMsgSize != NULL) {
    Value = HTONS (HTTP_BOOT_DHCP4_PACKET_MAX_SIZE);
    CopyMem (MaxMsgSize->Data, &Value, sizeof (Value));
  }
  
  //
  // Callback to user if any packets sent or received.
  //
  if (Private->HttpBootCallback != NULL && Dhcp4Event != Dhcp4SelectOffer) {
    Received = (BOOLEAN) (Dhcp4Event == Dhcp4RcvdOffer || Dhcp4Event == Dhcp4RcvdAck);
    Status = Private->HttpBootCallback->Callback (
               Private->HttpBootCallback, 
               HttpBootDhcp4,
               Received,
               Packet->Length,
               &Packet->Dhcp4
               );
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }
  }

  Status = EFI_SUCCESS;
  switch (Dhcp4Event) {
  case Dhcp4RcvdOffer:
    Status = EFI_NOT_READY;
    if (Packet->Length > HTTP_BOOT_DHCP4_PACKET_MAX_SIZE) {
      //
      // Ignore the incoming packets which exceed the maximum length.
      //
      break;
    }
    if (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM) {
      //
      // Cache the DHCPv4 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.
      //
      HttpBootCacheDhcp4Offer (Private, Packet);
    }
    break;

  case Dhcp4SelectOffer:
    //
    // Select offer according to the priority in UEFI spec, and record the SelectIndex 
    // and SelectProxyType.
    //
    HttpBootSelectDhcpOffer (Private);

    if (Private->SelectIndex == 0) {
      Status = EFI_ABORTED;
    } else {
      *NewPacket = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp4.Packet.Offer;
    }
    break;
    
  default:
    break;
  }

  return Status;
}

/**
  This function will register the IPv4 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
HttpBootRegisterIp4Gateway (
  IN HTTP_BOOT_PRIVATE_DATA         *Private
  )
{
  EFI_STATUS                      Status;
  EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2;

  ASSERT (!Private->UsingIpv6);

  Ip4Config2 = Private->Ip4Config2;

  //
  // Configure the gateway if valid.
  //
  if (!EFI_IP4_EQUAL (&Private->GatewayIp, &mZeroIp4Addr)) {
    Status = Ip4Config2->SetData (
                           Ip4Config2,
                           Ip4Config2DataTypeGateway,
                           sizeof (EFI_IPv4_ADDRESS),
                           &Private->GatewayIp
                           );
    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_IPv4_ADDRESS instances.

  @retval     EFI_SUCCESS         The DNS configuration has been configured successfully.
  @retval     Others              Failed to configure the address.

**/
EFI_STATUS
HttpBootRegisterIp4Dns (
  IN HTTP_BOOT_PRIVATE_DATA         *Private,
  IN UINTN                          DataLength,
  IN VOID                           *DnsServerData
  )
{
  EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2;
  
  ASSERT (!Private->UsingIpv6);

  Ip4Config2 = Private->Ip4Config2;
  
  return Ip4Config2->SetData (
                       Ip4Config2,
                       Ip4Config2DataTypeDnsServer,
                       DataLength,
                       DnsServerData
                       );
}


/**
  This function will switch the IP4 configuration policy to Static.

  @param[in]  Private             Pointer to HTTP boot driver private data.

  @retval     EFI_SUCCESS         The policy is already configured to static.
  @retval     Others              Other error as indicated..

**/
EFI_STATUS
HttpBootSetIp4Policy (
  IN HTTP_BOOT_PRIVATE_DATA         *Private
  )
{
  EFI_IP4_CONFIG2_POLICY          Policy;
  EFI_STATUS                      Status;
  EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2;
  UINTN                           DataSize;

  Ip4Config2 = Private->Ip4Config2;

  DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);
  Status = Ip4Config2->GetData (
                         Ip4Config2,
                         Ip4Config2DataTypePolicy,
                         &DataSize,
                         &Policy
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Policy != Ip4Config2PolicyStatic) {
    Policy = Ip4Config2PolicyStatic;
    Status= Ip4Config2->SetData (
                          Ip4Config2,
                          Ip4Config2DataTypePolicy,
                          sizeof (EFI_IP4_CONFIG2_POLICY),
                          &Policy
                          );
    if (EFI_ERROR (Status)) {
      return Status;
    } 
  }

  return EFI_SUCCESS;
}

/**
  Start the D.O.R.A DHCPv4 process to acquire the IPv4 address and other Http boot information.

  @param[in]  Private           Pointer to HTTP boot driver private data.

  @retval EFI_SUCCESS           The D.O.R.A process successfully finished.
  @retval Others                Failed to finish the D.O.R.A process.

**/
EFI_STATUS
HttpBootDhcp4Dora (
  IN HTTP_BOOT_PRIVATE_DATA         *Private
  )
{
  EFI_DHCP4_PROTOCOL           *Dhcp4;
  UINT32                       OptCount;
  EFI_DHCP4_PACKET_OPTION      *OptList[HTTP_BOOT_DHCP4_OPTION_MAX_NUM];
  UINT8                        Buffer[HTTP_BOOT_DHCP4_OPTION_MAX_SIZE];
  EFI_DHCP4_CONFIG_DATA        Config;
  EFI_STATUS                   Status;
  EFI_DHCP4_MODE_DATA          Mode;
  
  Dhcp4 = Private->Dhcp4;
  ASSERT (Dhcp4 != NULL);

  Status = HttpBootSetIp4Policy (Private);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Build option list for the request packet.
  //
  OptCount = HttpBootBuildDhcp4Options (Private, OptList, Buffer);
  ASSERT (OptCount > 0);

  ZeroMem (&Config, sizeof(Config));
  Config.OptionCount      = OptCount;
  Config.OptionList       = OptList;
  Config.Dhcp4Callback    = HttpBootDhcp4CallBack;
  Config.CallbackContext  = Private;
  Config.DiscoverTryCount = HTTP_BOOT_DHCP_RETRIES;
  Config.DiscoverTimeout  = mHttpDhcpTimeout;

  //
  // Configure the DHCPv4 instance for HTTP boot.
  //
  Status = Dhcp4->Configure (Dhcp4, &Config);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Initialize the record fields for DHCPv4 offer in private data.
  //
  Private->OfferNum = 0;
  ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
  ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));

  //
  // Start DHCPv4 D.O.R.A. process to acquire IPv4 address.
  //
  Status = Dhcp4->Start (Dhcp4, NULL);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Get the acquired IPv4 address and store them.
  //
  Status = Dhcp4->GetModeData (Dhcp4, &Mode);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  ASSERT (Mode.State == Dhcp4Bound);
  CopyMem (&Private->StationIp, &Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));
  CopyMem (&Private->SubnetMask, &Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
  CopyMem (&Private->GatewayIp, &Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));

  Status = HttpBootRegisterIp4Gateway (Private);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  AsciiPrint ("\n  Station IP address is ");
  HttpBootShowIp4Addr (&Private->StationIp.v4);
  AsciiPrint ("\n");

ON_EXIT:
  if (EFI_ERROR (Status)) {
    Dhcp4->Stop (Dhcp4);
    Dhcp4->Configure (Dhcp4, NULL);
  } else {
    ZeroMem (&Config, sizeof (EFI_DHCP4_CONFIG_DATA));
    Dhcp4->Configure (Dhcp4, &Config);
  }

  return Status;
}
