/** @file
  Functions implementation related with DHCPv4 for UefiPxeBc Driver.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PxeBcImpl.h"

//
// This is a map from the interested DHCP4 option tags' index to the tag value.
//
UINT8  mInterestedDhcp4Tags[PXEBC_DHCP4_TAG_INDEX_MAX] = {
  DHCP4_TAG_BOOTFILE_LEN,
  DHCP4_TAG_VENDOR,
  DHCP4_TAG_OVERLOAD,
  DHCP4_TAG_MSG_TYPE,
  DHCP4_TAG_SERVER_ID,
  DHCP4_TAG_VENDOR_CLASS_ID,
  DHCP4_TAG_BOOTFILE
};

//
// There are 4 times retries with the value of 4, 8, 16 and 32, refers to PXE2.1 spec.
//
UINT32  mPxeDhcpTimeout[4] = { 4, 8, 16, 32 };

/**
  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 *
PxeBcParseDhcp4Options (
  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;
}

/**
  Parse the PXE vendor options and extract the information from them.

  @param[in]  Dhcp4Option        Pointer to vendor options in buffer.
  @param[in]  VendorOption       Pointer to structure to store information in vendor options.

**/
VOID
PxeBcParseVendorOptions (
  IN EFI_DHCP4_PACKET_OPTION  *Dhcp4Option,
  IN PXEBC_VENDOR_OPTION      *VendorOption
  )
{
  UINT32                   *BitMap;
  UINT8                    VendorOptionLen;
  EFI_DHCP4_PACKET_OPTION  *PxeOption;
  UINT8                    Offset;

  BitMap          = VendorOption->BitMap;
  VendorOptionLen = Dhcp4Option->Length;
  PxeOption       = (EFI_DHCP4_PACKET_OPTION *)&Dhcp4Option->Data[0];
  Offset          = 0;

  ASSERT (PxeOption != NULL);

  while ((Offset < VendorOptionLen) && (PxeOption->OpCode != DHCP4_TAG_EOP)) {
    //
    // Parse all the interesting PXE vendor options one by one.
    //
    switch (PxeOption->OpCode) {
      case PXEBC_VENDOR_TAG_MTFTP_IP:

        CopyMem (&VendorOption->MtftpIp, PxeOption->Data, sizeof (EFI_IPv4_ADDRESS));
        break;

      case PXEBC_VENDOR_TAG_MTFTP_CPORT:

        CopyMem (&VendorOption->MtftpCPort, PxeOption->Data, sizeof (VendorOption->MtftpCPort));
        break;

      case PXEBC_VENDOR_TAG_MTFTP_SPORT:

        CopyMem (&VendorOption->MtftpSPort, PxeOption->Data, sizeof (VendorOption->MtftpSPort));
        break;

      case PXEBC_VENDOR_TAG_MTFTP_TIMEOUT:

        VendorOption->MtftpTimeout = *PxeOption->Data;
        break;

      case PXEBC_VENDOR_TAG_MTFTP_DELAY:

        VendorOption->MtftpDelay = *PxeOption->Data;
        break;

      case PXEBC_VENDOR_TAG_DISCOVER_CTRL:

        VendorOption->DiscoverCtrl = *PxeOption->Data;
        break;

      case PXEBC_VENDOR_TAG_DISCOVER_MCAST:

        CopyMem (&VendorOption->DiscoverMcastIp, PxeOption->Data, sizeof (EFI_IPv4_ADDRESS));
        break;

      case PXEBC_VENDOR_TAG_BOOT_SERVERS:

        VendorOption->BootSvrLen = PxeOption->Length;
        VendorOption->BootSvr    = (PXEBC_BOOT_SVR_ENTRY *)PxeOption->Data;
        break;

      case PXEBC_VENDOR_TAG_BOOT_MENU:

        VendorOption->BootMenuLen = PxeOption->Length;
        VendorOption->BootMenu    = (PXEBC_BOOT_MENU_ENTRY *)PxeOption->Data;
        break;

      case PXEBC_VENDOR_TAG_MENU_PROMPT:

        VendorOption->MenuPromptLen = PxeOption->Length;
        VendorOption->MenuPrompt    = (PXEBC_MENU_PROMPT *)PxeOption->Data;
        break;

      case PXEBC_VENDOR_TAG_MCAST_ALLOC:

        CopyMem (&VendorOption->McastIpBase, PxeOption->Data, sizeof (EFI_IPv4_ADDRESS));
        CopyMem (&VendorOption->McastIpBlock, PxeOption->Data + 4, sizeof (VendorOption->McastIpBlock));
        CopyMem (&VendorOption->McastIpRange, PxeOption->Data + 6, sizeof (VendorOption->McastIpRange));
        break;

      case PXEBC_VENDOR_TAG_CREDENTIAL_TYPES:

        VendorOption->CredTypeLen = PxeOption->Length;
        VendorOption->CredType    = (UINT32 *)PxeOption->Data;
        break;

      case PXEBC_VENDOR_TAG_BOOT_ITEM:

        CopyMem (&VendorOption->BootSrvType, PxeOption->Data, sizeof (VendorOption->BootSrvType));
        CopyMem (&VendorOption->BootSrvLayer, PxeOption->Data + 2, sizeof (VendorOption->BootSrvLayer));
        break;

      default:
        //
        // Not interesting PXE vendor options.
        //
        break;
    }

    //
    // Set the bit map for the special PXE options.
    //
    SET_VENDOR_OPTION_BIT_MAP (BitMap, PxeOption->OpCode);

    //
    // Continue to the next option.
    //
    if (PxeOption->OpCode == DHCP4_TAG_PAD) {
      Offset++;
    } else {
      Offset = (UINT8)(Offset + PxeOption->Length + 2);
    }

    PxeOption = (EFI_DHCP4_PACKET_OPTION *)(Dhcp4Option->Data + Offset);
  }
}

/**
  Build the options buffer for the DHCPv4 request packet.

  @param[in]  Private             Pointer to PxeBc private data.
  @param[out] OptList             Pointer to the option pointer array.
  @param[in]  Buffer              Pointer to the buffer to contain the option list.
  @param[in]  NeedMsgType         If TRUE, it is necessary to include the Msg type option.
                                  Otherwise, it is not necessary.

  @return     Index               The count of the built-in options.

**/
UINT32
PxeBcBuildDhcp4Options (
  IN  PXEBC_PRIVATE_DATA       *Private,
  OUT EFI_DHCP4_PACKET_OPTION  **OptList,
  IN  UINT8                    *Buffer,
  IN  BOOLEAN                  NeedMsgType
  )
{
  UINT32                    Index;
  PXEBC_DHCP4_OPTION_ENTRY  OptEnt;
  UINT16                    Value;

  Index      = 0;
  OptList[0] = (EFI_DHCP4_PACKET_OPTION *)Buffer;

  if (NeedMsgType) {
    //
    // Append message type.
    //
    OptList[Index]->OpCode = DHCP4_TAG_MSG_TYPE;
    OptList[Index]->Length = 1;
    OptEnt.Mesg            = (PXEBC_DHCP4_OPTION_MESG *)OptList[Index]->Data;
    OptEnt.Mesg->Type      = PXEBC_DHCP4_MSG_TYPE_REQUEST;
    Index++;
    OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);

    //
    // Append max message size.
    //
    OptList[Index]->OpCode = DHCP4_TAG_MAXMSG;
    OptList[Index]->Length = (UINT8)sizeof (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE);
    OptEnt.MaxMesgSize     = (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE *)OptList[Index]->Data;
    Value                  = NTOHS (PXEBC_DHCP4_PACKET_MAX_SIZE);
    CopyMem (&OptEnt.MaxMesgSize->Size, &Value, sizeof (UINT16));
    Index++;
    OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);
  }

  //
  // Append parameter request list option.
  //
  OptList[Index]->OpCode    = DHCP4_TAG_PARA_LIST;
  OptList[Index]->Length    = 35;
  OptEnt.Para               = (PXEBC_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[24] = DHCP4_TAG_TFTP;
  OptEnt.Para->ParaList[25] = DHCP4_TAG_BOOTFILE;
  OptEnt.Para->ParaList[26] = DHCP4_TAG_UUID;
  OptEnt.Para->ParaList[27] = 0x80;
  OptEnt.Para->ParaList[28] = 0x81;
  OptEnt.Para->ParaList[29] = 0x82;
  OptEnt.Para->ParaList[30] = 0x83;
  OptEnt.Para->ParaList[31] = 0x84;
  OptEnt.Para->ParaList[32] = 0x85;
  OptEnt.Para->ParaList[33] = 0x86;
  OptEnt.Para->ParaList[34] = 0x87;
  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 (PXEBC_DHCP4_OPTION_UUID);
  OptEnt.Uuid            = (PXEBC_DHCP4_OPTION_UUID *)OptList[Index]->Data;
  OptEnt.Uuid->Type      = 0;
  Index++;
  OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);

  if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *)OptEnt.Uuid->Guid))) {
    //
    // Zero the Guid to indicate NOT programmable if failed to get system Guid.
    //
    DEBUG ((DEBUG_WARN, "PXE: Failed to read system GUID from the smbios table!\n"));
    ZeroMem (OptEnt.Uuid->Guid, sizeof (EFI_GUID));
  }

  //
  // Append client network device interface option
  //
  OptList[Index]->OpCode = DHCP4_TAG_UNDI;
  OptList[Index]->Length = (UINT8)sizeof (PXEBC_DHCP4_OPTION_UNDI);
  OptEnt.Undi            = (PXEBC_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 (PXEBC_DHCP4_OPTION_ARCH);
  OptEnt.Arch            = (PXEBC_DHCP4_OPTION_ARCH *)OptList[Index]->Data;
  Value                  = HTONS (EFI_PXE_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 (PXEBC_DHCP4_OPTION_CLID);
  OptEnt.Clid            = (PXEBC_DHCP4_OPTION_CLID *)OptList[Index]->Data;
  CopyMem (
    OptEnt.Clid,
    DEFAULT_CLASS_ID_DATA,
    sizeof (PXEBC_DHCP4_OPTION_CLID)
    );
  PxeBcUintnToAscDecWithFormat (
    EFI_PXE_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));
    PxeBcUintnToAscDecWithFormat (Private->Nii->MajorVer, OptEnt.Clid->UndiMajor, sizeof (OptEnt.Clid->UndiMajor));
    PxeBcUintnToAscDecWithFormat (Private->Nii->MinorVer, OptEnt.Clid->UndiMinor, sizeof (OptEnt.Clid->UndiMinor));
  }

  Index++;

  return Index;
}

/**
  Create a template DHCPv4 packet as a seed.

  @param[out] Seed           Pointer to the seed packet.
  @param[in]  Udp4           Pointer to EFI_UDP4_PROTOCOL.

**/
VOID
PxeBcSeedDhcp4Packet (
  OUT EFI_DHCP4_PACKET   *Seed,
  IN  EFI_UDP4_PROTOCOL  *Udp4
  )
{
  EFI_SIMPLE_NETWORK_MODE  Mode;
  EFI_DHCP4_HEADER         *Header;

  //
  // Get IfType and HwAddressSize from SNP mode data.
  //
  Udp4->GetModeData (Udp4, NULL, NULL, NULL, &Mode);

  Seed->Size   = sizeof (EFI_DHCP4_PACKET);
  Seed->Length = sizeof (Seed->Dhcp4);
  Header       = &Seed->Dhcp4.Header;
  ZeroMem (Header, sizeof (EFI_DHCP4_HEADER));
  Header->OpCode    = PXEBC_DHCP4_OPCODE_REQUEST;
  Header->HwType    = Mode.IfType;
  Header->HwAddrLen = (UINT8)Mode.HwAddressSize;
  CopyMem (Header->ClientHwAddr, &Mode.CurrentAddress, Header->HwAddrLen);

  Seed->Dhcp4.Magik     = PXEBC_DHCP4_MAGIC;
  Seed->Dhcp4.Option[0] = DHCP4_TAG_EOP;
}

/**
  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
PxeBcCacheDhcp4Packet (
  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 and invalid packet.

**/
EFI_STATUS
PxeBcParseDhcp4Packet (
  IN PXEBC_DHCP4_PACKET_CACHE  *Cache4
  )
{
  EFI_DHCP4_PACKET         *Offer;
  EFI_DHCP4_PACKET_OPTION  **Options;
  EFI_DHCP4_PACKET_OPTION  *Option;
  PXEBC_OFFER_TYPE         OfferType;
  UINTN                    Index;
  BOOLEAN                  IsProxyOffer;
  BOOLEAN                  IsPxeOffer;
  UINT8                    *Ptr8;
  BOOLEAN                  FileFieldOverloaded;

  IsProxyOffer        = FALSE;
  IsPxeOffer          = FALSE;
  FileFieldOverloaded = FALSE;

  ZeroMem (Cache4->OptList, sizeof (Cache4->OptList));
  ZeroMem (&Cache4->VendorOpt, sizeof (Cache4->VendorOpt));

  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 < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
    Options[Index] = PxeBcParseDhcp4Options (
                       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[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];
  if (Option != NULL) {
    if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {
      FileFieldOverloaded = TRUE;
      for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
        if (Options[Index] == NULL) {
          Options[Index] = PxeBcParseDhcp4Options (
                             (UINT8 *)Offer->Dhcp4.Header.BootFileName,
                             sizeof (Offer->Dhcp4.Header.BootFileName),
                             mInterestedDhcp4Tags[Index]
                             );
        }
      }
    }

    if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_SERVER_NAME) != 0) {
      for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
        if (Options[Index] == NULL) {
          Options[Index] = PxeBcParseDhcp4Options (
                             (UINT8 *)Offer->Dhcp4.Header.ServerName,
                             sizeof (Offer->Dhcp4.Header.ServerName),
                             mInterestedDhcp4Tags[Index]
                             );
        }
      }
    }
  }

  //
  // The offer with zero "yiaddr" is a proxy offer.
  //
  if (Offer->Dhcp4.Header.YourAddr.Addr[0] == 0) {
    IsProxyOffer = TRUE;
  }

  //
  // The offer with "PXEClient" is a PXE offer.
  //
  Option = Options[PXEBC_DHCP4_TAG_INDEX_CLASS_ID];
  if ((Option != NULL) && (Option->Length >= 9) &&
      (CompareMem (Option->Data, DEFAULT_CLASS_ID_DATA, 9) == 0))
  {
    IsPxeOffer = TRUE;
  }

  //
  // Parse PXE vendor options in this offer, and store the contents/pointers.
  //
  Option = Options[PXEBC_DHCP4_TAG_INDEX_VENDOR];
  if (IsPxeOffer && (Option != NULL)) {
    PxeBcParseVendorOptions (Option, &Cache4->VendorOpt);
  }

  //
  // Parse PXE boot file name:
  // According to PXE spec, 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[PXEBC_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[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data[0];
    Ptr8 += Options[PXEBC_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[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] = (EFI_DHCP4_PACKET_OPTION *)
                                              (&Offer->Dhcp4.Header.BootFileName[0] -
                                               OFFSET_OF (EFI_DHCP4_PACKET_OPTION, Data[0]));
  }

  //
  // Determine offer type of the DHCPv4 packet.
  //
  Option = Options[PXEBC_DHCP4_TAG_INDEX_MSG_TYPE];
  if ((Option == NULL) || (Option->Data[0] == 0)) {
    //
    // It's a Bootp offer.
    //
    OfferType = PxeOfferTypeBootp;

    Option = Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE];
    if (Option == NULL) {
      //
      // If the Bootp offer without bootfilename, discard it.
      //
      return EFI_DEVICE_ERROR;
    }
  } else {
    if (IS_VALID_DISCOVER_VENDOR_OPTION (Cache4->VendorOpt.BitMap)) {
      //
      // It's a PXE10 offer with PXEClient and discover vendor option.
      //
      OfferType = IsProxyOffer ? PxeOfferTypeProxyPxe10 : PxeOfferTypeDhcpPxe10;
    } else if (IS_VALID_MTFTP_VENDOR_OPTION (Cache4->VendorOpt.BitMap)) {
      //
      // It's a WFM11a offer with PXEClient and mtftp vendor option.
      // But multi-cast download is not supported currently, so discard it.
      //
      return EFI_DEVICE_ERROR;
    } else if (IsPxeOffer) {
      //
      // It's a BINL offer only with PXEClient.
      //
      OfferType = IsProxyOffer ? PxeOfferTypeProxyBinl : PxeOfferTypeDhcpBinl;
    } else {
      //
      // It's a DHCPv4 only offer, which is a pure DHCPv4 offer packet.
      //
      OfferType = PxeOfferTypeDhcpOnly;
    }
  }

  Cache4->OfferType = OfferType;

  return EFI_SUCCESS;
}

/**
  Cache the DHCPv4 ack packet, and parse it on demand.

  @param[in]  Private             Pointer to PxeBc private data.
  @param[in]  Ack                 Pointer to the DHCPv4 ack packet.
  @param[in]  Verified            If TRUE, parse the ACK packet and store info into mode data.

  @retval     EFI_SUCCESS                Cache and parse the packet successfully.
  @retval     EFI_BUFFER_TOO_SMALL       Cache buffer is not big enough to hold the packet.

**/
EFI_STATUS
PxeBcCopyDhcp4Ack (
  IN PXEBC_PRIVATE_DATA  *Private,
  IN EFI_DHCP4_PACKET    *Ack,
  IN BOOLEAN             Verified
  )
{
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_STATUS              Status;

  Mode = Private->PxeBc.Mode;

  Status = PxeBcCacheDhcp4Packet (&Private->DhcpAck.Dhcp4.Packet.Ack, Ack);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Verified) {
    //
    // Parse the ack packet and store it into mode data if needed.
    //
    PxeBcParseDhcp4Packet (&Private->DhcpAck.Dhcp4);
    CopyMem (&Mode->DhcpAck.Dhcpv4, &Ack->Dhcp4, Ack->Length);
    Mode->DhcpAckReceived = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Cache the DHCPv4 proxy offer packet according to the received order.

  @param[in]  Private               Pointer to PxeBc private data.
  @param[in]  OfferIndex            The received order of offer packets.

  @retval     EFI_SUCCESS                Cache and parse the packet successfully.
  @retval     EFI_BUFFER_TOO_SMALL       Cache buffer is not big enough to hold the packet.

**/
EFI_STATUS
PxeBcCopyProxyOffer (
  IN PXEBC_PRIVATE_DATA  *Private,
  IN UINT32              OfferIndex
  )
{
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_DHCP4_PACKET        *Offer;
  EFI_STATUS              Status;

  ASSERT (OfferIndex < Private->OfferNum);
  ASSERT (OfferIndex < PXEBC_OFFER_MAX_NUM);

  Mode  = Private->PxeBc.Mode;
  Offer = &Private->OfferBuffer[OfferIndex].Dhcp4.Packet.Offer;

  //
  // Cache the proxy offer packet and parse it.
  //
  Status = PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Offer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  PxeBcParseDhcp4Packet (&Private->ProxyOffer.Dhcp4);

  //
  // Store this packet into mode data.
  //
  CopyMem (&Mode->ProxyOffer.Dhcpv4, &Offer->Dhcp4, Offer->Length);
  Mode->ProxyOfferReceived = TRUE;

  return EFI_SUCCESS;
}

/**
  Retry to request bootfile name by the BINL offer.

  @param[in]  Private              Pointer to PxeBc private data.
  @param[in]  Index                The received order of offer packets.

  @retval     EFI_SUCCESS          Successfully retried to request bootfile name.
  @retval     EFI_DEVICE_ERROR     Failed to retry bootfile name.

**/
EFI_STATUS
PxeBcRetryBinlOffer (
  IN PXEBC_PRIVATE_DATA  *Private,
  IN UINT32              Index
  )
{
  EFI_DHCP4_PACKET          *Offer;
  EFI_IP_ADDRESS            ServerIp;
  EFI_STATUS                Status;
  PXEBC_DHCP4_PACKET_CACHE  *Cache4;
  EFI_DHCP4_PACKET          *Reply;

  ASSERT (Index < PXEBC_OFFER_MAX_NUM);
  ASSERT (
    Private->OfferBuffer[Index].Dhcp4.OfferType == PxeOfferTypeDhcpBinl ||
    Private->OfferBuffer[Index].Dhcp4.OfferType == PxeOfferTypeProxyBinl
    );

  Offer = &Private->OfferBuffer[Index].Dhcp4.Packet.Offer;

  //
  // Prefer to siaddr in header as next server address. If it's zero, then use option 54.
  //
  if (Offer->Dhcp4.Header.ServerAddr.Addr[0] == 0) {
    CopyMem (
      &ServerIp.Addr[0],
      Private->OfferBuffer[Index].Dhcp4.OptList[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,
      sizeof (EFI_IPv4_ADDRESS)
      );
  } else {
    CopyMem (
      &ServerIp.Addr[0],
      &Offer->Dhcp4.Header.ServerAddr,
      sizeof (EFI_IPv4_ADDRESS)
      );
  }

  Private->IsDoDiscover = FALSE;
  Cache4                = &Private->ProxyOffer.Dhcp4;
  Reply                 = &Cache4->Packet.Offer;

  //
  // Send another request packet for bootfile name.
  //
  Status = PxeBcDhcp4Discover (
             Private,
             0,
             NULL,
             FALSE,
             &ServerIp,
             0,
             NULL
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Parse the reply for the last request packet.
  //
  Status = PxeBcParseDhcp4Packet (Cache4);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((Cache4->OfferType != PxeOfferTypeProxyPxe10) &&
      (Cache4->OfferType != PxeOfferTypeProxyWfm11a) &&
      (Cache4->OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL))
  {
    //
    // This BINL ack doesn't have discovery option set or multicast option set
    // or bootfile name specified.
    //
    return EFI_DEVICE_ERROR;
  }

  //
  // Store the reply into mode data.
  //
  Private->PxeBc.Mode->ProxyOfferReceived = TRUE;
  CopyMem (&Private->PxeBc.Mode->ProxyOffer.Dhcpv4, &Reply->Dhcp4, Reply->Length);

  return EFI_SUCCESS;
}

/**
  Cache all the received DHCPv4 offers, and set OfferIndex and OfferCount.

  @param[in]  Private               Pointer to PxeBc 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
PxeBcCacheDhcp4Offer (
  IN PXEBC_PRIVATE_DATA  *Private,
  IN EFI_DHCP4_PACKET    *RcvdOffer
  )
{
  PXEBC_DHCP4_PACKET_CACHE  *Cache4;
  EFI_DHCP4_PACKET          *Offer;
  PXEBC_OFFER_TYPE          OfferType;
  EFI_STATUS                Status;

  ASSERT (Private->OfferNum < PXEBC_OFFER_MAX_NUM);
  Cache4 = &Private->OfferBuffer[Private->OfferNum].Dhcp4;
  Offer  = &Cache4->Packet.Offer;

  //
  // Cache the content of DHCPv4 packet firstly.
  //
  Status = PxeBcCacheDhcp4Packet (Offer, RcvdOffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Validate the DHCPv4 packet, and parse the options and offer type.
  //
  if (EFI_ERROR (PxeBcParseDhcp4Packet (Cache4))) {
    return EFI_ABORTED;
  }

  //
  // Determine whether cache the current offer by type, and record OfferIndex and OfferCount.
  //
  OfferType = Cache4->OfferType;
  ASSERT (OfferType < PxeOfferTypeMax);

  if (OfferType == PxeOfferTypeBootp) {
    //
    // It's a Bootp offer, only cache the first one, and discard the others.
    //
    if (Private->OfferCount[OfferType] == 0) {
      Private->OfferIndex[OfferType][0] = Private->OfferNum;
      Private->OfferCount[OfferType]    = 1;
    } else {
      return EFI_ABORTED;
    }
  } else {
    ASSERT (Private->OfferCount[OfferType] < PXEBC_OFFER_MAX_NUM);
    if (IS_PROXY_DHCP_OFFER (Offer)) {
      //
      // It's a proxy offer without yiaddr, including PXE10, WFM11a or BINL offer.
      //
      Private->IsProxyRecved = TRUE;

      if (OfferType == PxeOfferTypeProxyBinl) {
        //
        // Cache all proxy BINL offers.
        //
        Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;
        Private->OfferCount[OfferType]++;
      } else if (((OfferType == PxeOfferTypeProxyPxe10) || (OfferType == PxeOfferTypeProxyWfm11a)) &&
                 (Private->OfferCount[OfferType] < 1))
      {
        //
        // Only cache the first PXE10/WFM11a offer, and discard the others.
        //
        Private->OfferIndex[OfferType][0] = Private->OfferNum;
        Private->OfferCount[OfferType]    = 1;
      } else {
        return EFI_ABORTED;
      }
    } else {
      //
      // It's a DHCPv4 offer with yiaddr, and cache them all.
      //
      Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;
      Private->OfferCount[OfferType]++;
    }
  }

  Private->OfferNum++;

  return EFI_SUCCESS;
}

/**
  Select an DHCPv4 offer, and record SelectIndex and SelectProxyType.

  @param[in]  Private             Pointer to PxeBc private data.

**/
VOID
PxeBcSelectDhcp4Offer (
  IN PXEBC_PRIVATE_DATA  *Private
  )
{
  UINT32            Index;
  UINT32            OfferIndex;
  EFI_DHCP4_PACKET  *Offer;

  Private->SelectIndex = 0;

  if (Private->IsOfferSorted) {
    //
    // Select offer by default policy.
    //
    if (Private->OfferCount[PxeOfferTypeDhcpPxe10] > 0) {
      //
      // 1. DhcpPxe10 offer
      //
      Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpPxe10][0] + 1;
    } else if (Private->OfferCount[PxeOfferTypeDhcpWfm11a] > 0) {
      //
      // 2. DhcpWfm11a offer
      //
      Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpWfm11a][0] + 1;
    } else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) &&
               (Private->OfferCount[PxeOfferTypeProxyPxe10] > 0))
    {
      //
      // 3. DhcpOnly offer and ProxyPxe10 offer.
      //
      Private->SelectIndex     = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1;
      Private->SelectProxyType = PxeOfferTypeProxyPxe10;
    } else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) &&
               (Private->OfferCount[PxeOfferTypeProxyWfm11a] > 0))
    {
      //
      // 4. DhcpOnly offer and ProxyWfm11a offer.
      //
      Private->SelectIndex     = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1;
      Private->SelectProxyType = PxeOfferTypeProxyWfm11a;
    } else if (Private->OfferCount[PxeOfferTypeDhcpBinl] > 0) {
      //
      // 5. DhcpBinl offer.
      //
      Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpBinl][0] + 1;
    } else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) &&
               (Private->OfferCount[PxeOfferTypeProxyBinl] > 0))
    {
      //
      // 6. DhcpOnly offer and ProxyBinl offer.
      //
      Private->SelectIndex     = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1;
      Private->SelectProxyType = PxeOfferTypeProxyBinl;
    } else {
      //
      // 7. DhcpOnly offer with bootfilename.
      //
      for (Index = 0; Index < Private->OfferCount[PxeOfferTypeDhcpOnly]; Index++) {
        OfferIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][Index];
        if (Private->OfferBuffer[OfferIndex].Dhcp4.OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
          Private->SelectIndex = OfferIndex + 1;
          break;
        }
      }

      //
      // 8. Bootp offer with bootfilename.
      //
      OfferIndex = Private->OfferIndex[PxeOfferTypeBootp][0];
      if ((Private->SelectIndex == 0) &&
          (Private->OfferCount[PxeOfferTypeBootp] > 0) &&
          (Private->OfferBuffer[OfferIndex].Dhcp4.OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL))
      {
        Private->SelectIndex = OfferIndex + 1;
      }
    }
  } else {
    //
    // Select offer by received order.
    //
    for (Index = 0; Index < Private->OfferNum; Index++) {
      Offer = &Private->OfferBuffer[Index].Dhcp4.Packet.Offer;

      if (IS_PROXY_DHCP_OFFER (Offer)) {
        //
        // Skip proxy offers
        //
        continue;
      }

      if (!Private->IsProxyRecved &&
          (Private->OfferBuffer[Index].Dhcp4.OfferType == PxeOfferTypeDhcpOnly) &&
          (Private->OfferBuffer[Index].Dhcp4.OptList[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL))
      {
        //
        // Skip if DhcpOnly offer without any other proxy offers or bootfilename.
        //
        continue;
      }

      //
      // Record the index of the select offer.
      //
      Private->SelectIndex = Index + 1;
      break;
    }
  }
}

/**
  Handle the DHCPv4 offer packet.

  @param[in]  Private               Pointer to PxeBc private data.

  @retval     EFI_SUCCESS           Handled the DHCPv4 offer packet successfully.
  @retval     EFI_NO_RESPONSE       No response to the following request packet.
  @retval     EFI_NOT_FOUND         No boot filename received.
  @retval     EFI_BUFFER_TOO_SMALL  Can't cache the offer pacet.

**/
EFI_STATUS
PxeBcHandleDhcp4Offer (
  IN PXEBC_PRIVATE_DATA  *Private
  )
{
  PXEBC_DHCP4_PACKET_CACHE  *Cache4;
  EFI_DHCP4_PACKET_OPTION   **Options;
  UINT32                    Index;
  EFI_DHCP4_PACKET          *Offer;
  PXEBC_OFFER_TYPE          OfferType;
  UINT32                    ProxyIndex;
  UINT32                    SelectIndex;
  EFI_STATUS                Status;
  EFI_PXE_BASE_CODE_MODE    *Mode;
  EFI_DHCP4_PACKET          *Ack;

  ASSERT (Private->SelectIndex > 0);
  SelectIndex = (UINT32)(Private->SelectIndex - 1);
  ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM);
  Cache4  = &Private->OfferBuffer[SelectIndex].Dhcp4;
  Options = Cache4->OptList;
  Status  = EFI_SUCCESS;

  if (Cache4->OfferType == PxeOfferTypeDhcpBinl) {
    //
    // DhcpBinl offer is selected, so need try to request bootfilename by this offer.
    //
    if (EFI_ERROR (PxeBcRetryBinlOffer (Private, SelectIndex))) {
      Status = EFI_NO_RESPONSE;
    }
  } else if (Cache4->OfferType == PxeOfferTypeDhcpOnly) {
    if (Private->IsProxyRecved) {
      //
      // DhcpOnly offer is selected, so need try to request bootfile name.
      //
      ProxyIndex = 0;
      if (Private->IsOfferSorted) {
        //
        // The proxy offer should be determined if select by default policy.
        // IsOfferSorted means all offers are labeled by OfferIndex.
        //
        ASSERT (Private->SelectProxyType < PxeOfferTypeMax);
        ASSERT (Private->OfferCount[Private->SelectProxyType] > 0);

        if (Private->SelectProxyType == PxeOfferTypeProxyBinl) {
          //
          // Try all the cached ProxyBinl offer one by one to request bootfile name.
          //
          for (Index = 0; Index < Private->OfferCount[Private->SelectProxyType]; Index++) {
            ASSERT (Index < PXEBC_OFFER_MAX_NUM);
            ProxyIndex = Private->OfferIndex[Private->SelectProxyType][Index];
            if (!EFI_ERROR (PxeBcRetryBinlOffer (Private, ProxyIndex))) {
              break;
            }
          }

          if (Index == Private->OfferCount[Private->SelectProxyType]) {
            Status = EFI_NO_RESPONSE;
          }
        } else {
          //
          // For other proxy offers, only one is buffered.
          //
          ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
        }
      } else {
        //
        // The proxy offer should not be determined if select by received order.
        //
        Status = EFI_NO_RESPONSE;

        for (Index = 0; Index < Private->OfferNum; Index++) {
          ASSERT (Index < PXEBC_OFFER_MAX_NUM);
          Offer     = &Private->OfferBuffer[Index].Dhcp4.Packet.Offer;
          OfferType = Private->OfferBuffer[Index].Dhcp4.OfferType;
          if (!IS_PROXY_DHCP_OFFER (Offer)) {
            //
            // Skip non proxy DHCPv4 offers.
            //
            continue;
          }

          if (OfferType == PxeOfferTypeProxyBinl) {
            //
            // Try all the cached ProxyBinl offer one by one to request bootfile name.
            //
            if (EFI_ERROR (PxeBcRetryBinlOffer (Private, Index))) {
              continue;
            }
          }

          Private->SelectProxyType = OfferType;
          ProxyIndex               = Index;
          Status                   = EFI_SUCCESS;
          break;
        }
      }

      if (!EFI_ERROR (Status) && (Private->SelectProxyType != PxeOfferTypeProxyBinl)) {
        //
        // Success to try to request by a ProxyPxe10 or ProxyWfm11a offer, copy and parse it.
        //
        Status = PxeBcCopyProxyOffer (Private, ProxyIndex);
      }
    } else {
      //
      //  Otherwise, the bootfile name must be included in DhcpOnly offer.
      //
      if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL) {
        Status = EFI_NOT_FOUND;
      }
    }
  }

  if (!EFI_ERROR (Status)) {
    //
    // All PXE boot information is ready by now.
    //
    Mode  = Private->PxeBc.Mode;
    Offer = &Cache4->Packet.Offer;
    Ack   = &Private->DhcpAck.Dhcp4.Packet.Ack;
    if (Cache4->OfferType == PxeOfferTypeBootp) {
      //
      // Bootp is a special case that only 2 packets involved instead of 4. So the bootp's reply
      // should be taken as ack.
      //
      Ack = Offer;
    }

    Status = PxeBcCopyDhcp4Ack (Private, Ack, TRUE);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Mode->DhcpDiscoverValid = TRUE;
  }

  return Status;
}

/**
  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
PxeBcDhcp4CallBack (
  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
  )
{
  PXEBC_PRIVATE_DATA                   *Private;
  EFI_PXE_BASE_CODE_MODE               *Mode;
  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  *Callback;
  EFI_DHCP4_PACKET_OPTION              *MaxMsgSize;
  UINT16                               Value;
  EFI_STATUS                           Status;
  BOOLEAN                              Received;

  if ((Dhcp4Event != Dhcp4RcvdOffer) &&
      (Dhcp4Event != Dhcp4SelectOffer) &&
      (Dhcp4Event != Dhcp4SendDiscover) &&
      (Dhcp4Event != Dhcp4RcvdAck))
  {
    return EFI_SUCCESS;
  }

  ASSERT (Packet != NULL);

  Private  = (PXEBC_PRIVATE_DATA *)Context;
  Mode     = Private->PxeBc.Mode;
  Callback = Private->PxeBcCallback;

  //
  // Override the Maximum DHCP Message Size.
  //
  MaxMsgSize = PxeBcParseDhcp4Options (
                 Packet->Dhcp4.Option,
                 GET_OPTION_BUFFER_LEN (Packet),
                 DHCP4_TAG_MAXMSG
                 );
  if (MaxMsgSize != NULL) {
    Value = HTONS (PXEBC_DHCP4_PACKET_MAX_SIZE);
    CopyMem (MaxMsgSize->Data, &Value, sizeof (Value));
  }

  //
  // Callback to user if any packets sent or received.
  //
  if ((Dhcp4Event != Dhcp4SelectOffer) && (Callback != NULL)) {
    Received = (BOOLEAN)(Dhcp4Event == Dhcp4RcvdOffer || Dhcp4Event == Dhcp4RcvdAck);
    Status   = Callback->Callback (
                           Callback,
                           Private->Function,
                           Received,
                           Packet->Length,
                           (EFI_PXE_BASE_CODE_PACKET *)&Packet->Dhcp4
                           );
    if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
      return EFI_ABORTED;
    }
  }

  Status = EFI_SUCCESS;

  switch (Dhcp4Event) {
    case Dhcp4SendDiscover:
      if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {
        //
        // If the to be sent packet exceeds the maximum length, abort the DHCP process.
        //
        Status = EFI_ABORTED;
        break;
      }

      //
      // Cache the DHCPv4 discover packet to mode data directly.
      // It need to check SendGuid as well as Dhcp4SendRequest.
      //
      CopyMem (&Mode->DhcpDiscover.Dhcpv4, &Packet->Dhcp4, Packet->Length);

    case Dhcp4SendRequest:
      if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {
        //
        // If the to be sent packet exceeds the maximum length, abort the DHCP process.
        //
        Status = EFI_ABORTED;
        break;
      }

      if (Mode->SendGUID) {
        //
        // Send the system Guid instead of the MAC address as the hardware address if required.
        //
        if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *)Packet->Dhcp4.Header.ClientHwAddr))) {
          //
          // Zero the Guid to indicate NOT programmable if failed to get system Guid.
          //
          DEBUG ((DEBUG_WARN, "PXE: Failed to read system GUID from the smbios table!\n"));
          ZeroMem (Packet->Dhcp4.Header.ClientHwAddr, sizeof (EFI_GUID));
        }

        Packet->Dhcp4.Header.HwAddrLen = (UINT8)sizeof (EFI_GUID);
      }

      break;

    case Dhcp4RcvdOffer:
      Status = EFI_NOT_READY;
      if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {
        //
        // Ignore the incoming packets which exceed the maximum length.
        //
        break;
      }

      if (Private->OfferNum < PXEBC_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.
        //
        PxeBcCacheDhcp4Offer (Private, Packet);
      }

      break;

    case Dhcp4SelectOffer:
      ASSERT (NewPacket != NULL);

      //
      // Select offer by the default policy or by order, and record the SelectIndex
      // and SelectProxyType.
      //
      PxeBcSelectDhcp4Offer (Private);

      if (Private->SelectIndex == 0) {
        Status = EFI_ABORTED;
      } else {
        *NewPacket = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp4.Packet.Offer;
      }

      break;

    case Dhcp4RcvdAck:
      //
      // Cache the DHCPv4 ack to Private->Dhcp4Ack, but it's not the final ack in mode data
      // without verification.
      //
      ASSERT (Private->SelectIndex != 0);

      Status = PxeBcCopyDhcp4Ack (Private, Packet, FALSE);
      if (EFI_ERROR (Status)) {
        Status = EFI_ABORTED;
      }

      break;

    default:
      break;
  }

  return Status;
}

/**
  Build and send out the request packet for the bootfile, and parse the reply.

  @param[in]  Private               Pointer to PxeBc private data.
  @param[in]  Type                  PxeBc option boot item type.
  @param[in]  Layer                 Pointer to option boot item layer.
  @param[in]  UseBis                Use BIS or not.
  @param[in]  DestIp                Pointer to the server address.
  @param[in]  IpCount               The total count of the server address.
  @param[in]  SrvList               Pointer to EFI_PXE_BASE_CODE_SRVLIST.

  @retval     EFI_SUCCESS           Successfully discovered boot file.
  @retval     EFI_OUT_OF_RESOURCES  Failed to allocate resource.
  @retval     EFI_NOT_FOUND         Can't get the PXE reply packet.
  @retval     Others                Failed to discover boot file.

**/
EFI_STATUS
PxeBcDhcp4Discover (
  IN  PXEBC_PRIVATE_DATA         *Private,
  IN  UINT16                     Type,
  IN  UINT16                     *Layer,
  IN  BOOLEAN                    UseBis,
  IN  EFI_IP_ADDRESS             *DestIp,
  IN  UINT16                     IpCount,
  IN  EFI_PXE_BASE_CODE_SRVLIST  *SrvList
  )
{
  EFI_PXE_BASE_CODE_UDP_PORT        Sport;
  EFI_PXE_BASE_CODE_MODE            *Mode;
  EFI_DHCP4_PROTOCOL                *Dhcp4;
  EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN  Token;
  BOOLEAN                           IsBCast;
  EFI_STATUS                        Status;
  UINT16                            RepIndex;
  UINT16                            SrvIndex;
  UINT16                            TryIndex;
  EFI_DHCP4_LISTEN_POINT            ListenPoint;
  EFI_DHCP4_PACKET                  *Response;
  UINT8                             Buffer[PXEBC_DHCP4_OPTION_MAX_SIZE];
  EFI_DHCP4_PACKET_OPTION           *OptList[PXEBC_DHCP4_OPTION_MAX_NUM];
  UINT32                            OptCount;
  EFI_DHCP4_PACKET_OPTION           *PxeOpt;
  PXEBC_OPTION_BOOT_ITEM            *PxeBootItem;
  UINT8                             VendorOptLen;
  UINT32                            Xid;

  Mode   = Private->PxeBc.Mode;
  Dhcp4  = Private->Dhcp4;
  Status = EFI_SUCCESS;

  ZeroMem (&Token, sizeof (EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN));

  //
  // Use broadcast if destination address not specified.
  //
  if (DestIp == NULL) {
    Sport   = PXEBC_DHCP4_S_PORT;
    IsBCast = TRUE;
  } else {
    Sport   = PXEBC_BS_DISCOVER_PORT;
    IsBCast = FALSE;
  }

  if (!UseBis && (Layer != NULL)) {
    *Layer &= EFI_PXE_BASE_CODE_BOOT_LAYER_MASK;
  }

  //
  // Build all the options for the request packet.
  //
  OptCount = PxeBcBuildDhcp4Options (Private, OptList, Buffer, TRUE);

  if (Private->IsDoDiscover) {
    //
    // Add vendor option of PXE_BOOT_ITEM
    //
    VendorOptLen      = (UINT8)((sizeof (EFI_DHCP4_PACKET_OPTION) - 1) * 2 + sizeof (PXEBC_OPTION_BOOT_ITEM) + 1);
    OptList[OptCount] = AllocateZeroPool (VendorOptLen);
    if (OptList[OptCount] == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    OptList[OptCount]->OpCode    = DHCP4_TAG_VENDOR;
    OptList[OptCount]->Length    = (UINT8)(VendorOptLen - 2);
    PxeOpt                       = (EFI_DHCP4_PACKET_OPTION *)OptList[OptCount]->Data;
    PxeOpt->OpCode               = PXEBC_VENDOR_TAG_BOOT_ITEM;
    PxeOpt->Length               = (UINT8)sizeof (PXEBC_OPTION_BOOT_ITEM);
    PxeBootItem                  = (PXEBC_OPTION_BOOT_ITEM *)PxeOpt->Data;
    PxeBootItem->Type            = HTONS (Type);
    PxeOpt->Data[PxeOpt->Length] = DHCP4_TAG_EOP;

    if (Layer != NULL) {
      PxeBootItem->Layer = HTONS (*Layer);
    }

    OptCount++;
  }

  //
  // Build the request packet with seed packet and option list.
  //
  Status = Dhcp4->Build (
                    Dhcp4,
                    &Private->SeedPacket,
                    0,
                    NULL,
                    OptCount,
                    OptList,
                    &Token.Packet
                    );
  //
  // Free the vendor option of PXE_BOOT_ITEM.
  //
  if (Private->IsDoDiscover) {
    FreePool (OptList[OptCount - 1]);
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Mode->SendGUID) {
    if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *)Token.Packet->Dhcp4.Header.ClientHwAddr))) {
      //
      // Zero the Guid to indicate NOT programmable if failed to get system Guid.
      //
      DEBUG ((DEBUG_WARN, "PXE: Failed to read system GUID from the smbios table!\n"));
      ZeroMem (Token.Packet->Dhcp4.Header.ClientHwAddr, sizeof (EFI_GUID));
    }

    Token.Packet->Dhcp4.Header.HwAddrLen = (UINT8)sizeof (EFI_GUID);
  }

  //
  // Set fields of the token for the request packet.
  //
  Xid                                 = NET_RANDOM (NetRandomInitSeed ());
  Token.Packet->Dhcp4.Header.Xid      = HTONL (Xid);
  Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)((IsBCast) ? 0x8000 : 0x0));
  CopyMem (&Token.Packet->Dhcp4.Header.ClientAddr, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));

  Token.RemotePort = Sport;

  if (IsBCast) {
    SetMem (&Token.RemoteAddress, sizeof (EFI_IPv4_ADDRESS), 0xff);
  } else {
    CopyMem (&Token.RemoteAddress, DestIp, sizeof (EFI_IPv4_ADDRESS));
  }

  CopyMem (&Token.GatewayAddress, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));

  if (!IsBCast) {
    Token.ListenPointCount           = 1;
    Token.ListenPoints               = &ListenPoint;
    Token.ListenPoints[0].ListenPort = PXEBC_BS_DISCOVER_PORT;
    CopyMem (&Token.ListenPoints[0].ListenAddress, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Token.ListenPoints[0].SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
  }

  //
  // Send out the request packet to discover the bootfile.
  //
  for (TryIndex = 1; TryIndex <= PXEBC_BOOT_REQUEST_RETRIES; TryIndex++) {
    Token.TimeoutValue                 = (UINT16)(PXEBC_BOOT_REQUEST_TIMEOUT * TryIndex);
    Token.Packet->Dhcp4.Header.Seconds = (UINT16)(PXEBC_BOOT_REQUEST_TIMEOUT * (TryIndex - 1));

    Status = Dhcp4->TransmitReceive (Dhcp4, &Token);
    if (Token.Status != EFI_TIMEOUT) {
      break;
    }
  }

  if (TryIndex > PXEBC_BOOT_REQUEST_RETRIES) {
    //
    // No server response our PXE request
    //
    Status = EFI_TIMEOUT;
  }

  if (!EFI_ERROR (Status)) {
    RepIndex = 0;
    SrvIndex = 0;
    Response = Token.ResponseList;
    //
    // Find the right PXE Reply according to server address.
    //
    while (RepIndex < Token.ResponseCount) {
      if (Response->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {
        SrvIndex = 0;
        RepIndex++;
        Response = (EFI_DHCP4_PACKET *)((UINT8 *)Response + Response->Size);
        continue;
      }

      while (SrvIndex < IpCount) {
        if (SrvList[SrvIndex].AcceptAnyResponse) {
          break;
        }

        if ((SrvList[SrvIndex].Type == Type) &&
            EFI_IP4_EQUAL (&Response->Dhcp4.Header.ServerAddr, &SrvList[SrvIndex].IpAddr))
        {
          break;
        }

        SrvIndex++;
      }

      if ((IpCount != SrvIndex) || (IpCount == 0)) {
        break;
      }

      SrvIndex = 0;
      RepIndex++;
      Response = (EFI_DHCP4_PACKET *)((UINT8 *)Response + Response->Size);
    }

    if (RepIndex < Token.ResponseCount) {
      //
      // Cache the right PXE reply packet here, set valid flag later.
      // Especially for PXE discover packet, store it into mode data here.
      //
      if (Private->IsDoDiscover) {
        Status = PxeBcCacheDhcp4Packet (&Private->PxeReply.Dhcp4.Packet.Ack, Response);
        if (EFI_ERROR (Status)) {
          goto ON_EXIT;
        }

        CopyMem (&Mode->PxeDiscover, &Token.Packet->Dhcp4, Token.Packet->Length);
      } else {
        Status = PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Response);
        if (EFI_ERROR (Status)) {
          goto ON_EXIT;
        }
      }
    } else {
      //
      // Not found the right PXE reply packet.
      //
      Status = EFI_NOT_FOUND;
    }
  }

ON_EXIT:

  if (Token.ResponseList != NULL) {
    FreePool (Token.ResponseList);
  }

  if (Token.Packet != NULL) {
    FreePool (Token.Packet);
  }

  return Status;
}

/**
  Switch the Ip4 policy to static.

  @param[in]  Private             The pointer to PXEBC_PRIVATE_DATA.

  @retval     EFI_SUCCESS         The policy is already configured to static.
  @retval     Others              Other error as indicated..

**/
EFI_STATUS
PxeBcSetIp4Policy (
  IN PXEBC_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS                Status;
  EFI_IP4_CONFIG2_PROTOCOL  *Ip4Config2;
  EFI_IP4_CONFIG2_POLICY    Policy;
  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 PXE boot information.

  @param[in]  Private           Pointer to PxeBc private data.
  @param[in]  Dhcp4             Pointer to the EFI_DHCP4_PROTOCOL

  @retval EFI_SUCCESS           The D.O.R.A process successfully finished.
  @retval Others                Failed to finish the D.O.R.A process.

**/
EFI_STATUS
PxeBcDhcp4Dora (
  IN PXEBC_PRIVATE_DATA  *Private,
  IN EFI_DHCP4_PROTOCOL  *Dhcp4
  )
{
  EFI_PXE_BASE_CODE_MODE   *PxeMode;
  EFI_DHCP4_CONFIG_DATA    Config;
  EFI_DHCP4_MODE_DATA      Mode;
  EFI_DHCP4_PACKET_OPTION  *OptList[PXEBC_DHCP4_OPTION_MAX_NUM];
  UINT8                    Buffer[PXEBC_DHCP4_OPTION_MAX_SIZE];
  UINT32                   OptCount;
  EFI_STATUS               Status;

  ASSERT (Dhcp4 != NULL);

  Status  = EFI_SUCCESS;
  PxeMode = Private->PxeBc.Mode;

  //
  // Build option list for the request packet.
  //
  OptCount = PxeBcBuildDhcp4Options (Private, OptList, Buffer, FALSE);
  ASSERT (OptCount > 0);

  ZeroMem (&Mode, sizeof (EFI_DHCP4_MODE_DATA));
  ZeroMem (&Config, sizeof (EFI_DHCP4_CONFIG_DATA));

  Config.OptionCount      = OptCount;
  Config.OptionList       = OptList;
  Config.Dhcp4Callback    = PxeBcDhcp4CallBack;
  Config.CallbackContext  = Private;
  Config.DiscoverTryCount = PXEBC_DHCP_RETRIES;
  Config.DiscoverTimeout  = mPxeDhcpTimeout;

  //
  // Configure the DHCPv4 instance for PXE boot.
  //
  Status = Dhcp4->Configure (Dhcp4, &Config);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Initialize the record fields for DHCPv4 offer in private data.
  //
  Private->IsProxyRecved = FALSE;
  Private->OfferNum      = 0;
  ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
  ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));

  Status = Dhcp4->Start (Dhcp4, NULL);
  if (EFI_ERROR (Status)) {
    if (Status == EFI_ICMP_ERROR) {
      PxeMode->IcmpErrorReceived = TRUE;
    }

    if ((Status == EFI_TIMEOUT) && (Private->OfferNum > 0)) {
      Status = EFI_NO_RESPONSE;
    }

    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));
  CopyMem (&PxeMode->StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));
  CopyMem (&PxeMode->SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));

  Status = PxeBcFlushStationIp (Private, &Private->StationIp, &Private->SubnetMask);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Check the selected offer whether BINL retry is needed.
  //
  Status = PxeBcHandleDhcp4Offer (Private);

  AsciiPrint ("\n  Station IP address is ");

  PxeBcShowIp4Addr (&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);
    Private->IsAddressOk = TRUE;
  }

  return Status;
}
