/** @file
  Functions implementation related with DHCPv4 for UefiPxeBc Driver.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  Copyright (c) Microsoft Corporation
  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;

  Status = PseudoRandomU32 (&Xid);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
    return Status;
  }

  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.
  //
  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;
}
