/** @file
  Functions implementation related with DHCPv4 for UefiPxeBc Driver.

  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "PxeBcImpl.h"

//
// This is a map from the interested DHCP4 option tags' index to the tag value.
//
UINT8 mInterestedDhcp4Tags[PXEBC_DHCP4_TAG_INDEX_MAX] = {
  PXEBC_DHCP4_TAG_BOOTFILE_LEN,
  PXEBC_DHCP4_TAG_VENDOR,
  PXEBC_DHCP4_TAG_OVERLOAD,
  PXEBC_DHCP4_TAG_MSG_TYPE,
  PXEBC_DHCP4_TAG_SERVER_ID,
  PXEBC_DHCP4_TAG_CLASS_ID,
  PXEBC_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 != PXEBC_DHCP4_TAG_EOP) {

    if (Option->OpCode == OptTag) {
      //
      // Found the required option.
      //
      return Option;
    }

    //
    // Skip the current option to the next.
    //
    if (Option->OpCode == PXEBC_DHCP4_TAG_PAD) {
      Offset++;
    } else {
      Offset += Option->Length + 2;
    }

    Option = (EFI_DHCP4_PACKET_OPTION *) (Buffer + Offset);
  }

  return NULL;
}


/**
  Parse the PXE vender 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 != PXEBC_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 == PXEBC_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  = PXEBC_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  = PXEBC_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 - 8);
    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    = PXEBC_DHCP4_TAG_PARA_LIST;
  OptList[Index]->Length    = 35;
  OptEnt.Para               = (PXEBC_DHCP4_OPTION_PARA *) OptList[Index]->Data;
  OptEnt.Para->ParaList[0]  = PXEBC_DHCP4_TAG_NETMASK;
  OptEnt.Para->ParaList[1]  = PXEBC_DHCP4_TAG_TIME_OFFSET;
  OptEnt.Para->ParaList[2]  = PXEBC_DHCP4_TAG_ROUTER;
  OptEnt.Para->ParaList[3]  = PXEBC_DHCP4_TAG_TIME_SERVER;
  OptEnt.Para->ParaList[4]  = PXEBC_DHCP4_TAG_NAME_SERVER;
  OptEnt.Para->ParaList[5]  = PXEBC_DHCP4_TAG_DNS_SERVER;
  OptEnt.Para->ParaList[6]  = PXEBC_DHCP4_TAG_HOSTNAME;
  OptEnt.Para->ParaList[7]  = PXEBC_DHCP4_TAG_BOOTFILE_LEN;
  OptEnt.Para->ParaList[8]  = PXEBC_DHCP4_TAG_DOMAINNAME;
  OptEnt.Para->ParaList[9]  = PXEBC_DHCP4_TAG_ROOTPATH;
  OptEnt.Para->ParaList[10] = PXEBC_DHCP4_TAG_EXTEND_PATH;
  OptEnt.Para->ParaList[11] = PXEBC_DHCP4_TAG_EMTU;
  OptEnt.Para->ParaList[12] = PXEBC_DHCP4_TAG_TTL;
  OptEnt.Para->ParaList[13] = PXEBC_DHCP4_TAG_BROADCAST;
  OptEnt.Para->ParaList[14] = PXEBC_DHCP4_TAG_NIS_DOMAIN;
  OptEnt.Para->ParaList[15] = PXEBC_DHCP4_TAG_NIS_SERVER;
  OptEnt.Para->ParaList[16] = PXEBC_DHCP4_TAG_NTP_SERVER;
  OptEnt.Para->ParaList[17] = PXEBC_DHCP4_TAG_VENDOR;
  OptEnt.Para->ParaList[18] = PXEBC_DHCP4_TAG_REQUEST_IP;
  OptEnt.Para->ParaList[19] = PXEBC_DHCP4_TAG_LEASE;
  OptEnt.Para->ParaList[20] = PXEBC_DHCP4_TAG_SERVER_ID;
  OptEnt.Para->ParaList[21] = PXEBC_DHCP4_TAG_T1;
  OptEnt.Para->ParaList[22] = PXEBC_DHCP4_TAG_T2;
  OptEnt.Para->ParaList[23] = PXEBC_DHCP4_TAG_CLASS_ID;
  OptEnt.Para->ParaList[24] = PXEBC_DHCP4_TAG_TFTP;
  OptEnt.Para->ParaList[25] = PXEBC_DHCP4_TAG_BOOTFILE;
  OptEnt.Para->ParaList[26] = PXEBC_PXE_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  = PXEBC_PXE_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 programable if failed to get system Guid.
    //
    ZeroMem (OptEnt.Uuid->Guid, sizeof (EFI_GUID));
  }

  //
  // Append client network device interface option
  //
  OptList[Index]->OpCode  = PXEBC_PXE_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  = PXEBC_PXE_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  = PXEBC_DHCP4_TAG_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] = PXEBC_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.

**/
VOID
PxeBcCacheDhcp4Packet (
  IN EFI_DHCP4_PACKET     *Dst,
  IN EFI_DHCP4_PACKET     *Src
  )
{
  ASSERT (Dst->Size >= Src->Length);

  CopyMem (&Dst->Dhcp4, &Src->Dhcp4, Src->Length);
  Dst->Length = Src->Length;
}


/**
  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;

  IsProxyOffer = FALSE;
  IsPxeOffer   = 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) {
      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 (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.

**/
VOID
PxeBcCopyDhcp4Ack (
  IN PXEBC_PRIVATE_DATA   *Private,
  IN EFI_DHCP4_PACKET     *Ack,
  IN BOOLEAN              Verified
  )
{
  EFI_PXE_BASE_CODE_MODE  *Mode;

  Mode = Private->PxeBc.Mode;

  PxeBcCacheDhcp4Packet (&Private->DhcpAck.Dhcp4.Packet.Ack, Ack);

  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;
  }
}


/**
  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.

**/
VOID
PxeBcCopyProxyOffer (
  IN PXEBC_PRIVATE_DATA   *Private,
  IN UINT32               OfferIndex
  )
{
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_DHCP4_PACKET        *Offer;

  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.
  //
  PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Offer);
  PxeBcParseDhcp4Packet (&Private->ProxyOffer.Dhcp4);

  //
  // Store this packet into mode data.
  //
  CopyMem (&Mode->ProxyOffer.Dhcpv4, &Offer->Dhcp4, Offer->Length);
  Mode->ProxyOfferReceived = TRUE;
}


/**
  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.

**/
VOID
PxeBcCacheDhcp4Offer (
  IN PXEBC_PRIVATE_DATA     *Private,
  IN EFI_DHCP4_PACKET       *RcvdOffer
  )
{
  PXEBC_DHCP4_PACKET_CACHE  *Cache4;
  EFI_DHCP4_PACKET          *Offer;
  PXEBC_OFFER_TYPE          OfferType;

  ASSERT (Private->OfferNum < PXEBC_OFFER_MAX_NUM);
  Cache4 = &Private->OfferBuffer[Private->OfferNum].Dhcp4;
  Offer  = &Cache4->Packet.Offer;

  //
  // Cache the content of DHCPv4 packet firstly.
  //
  PxeBcCacheDhcp4Packet (Offer, RcvdOffer);

  //
  // Validate the DHCPv4 packet, and parse the options and offer type.
  //
  if (EFI_ERROR (PxeBcParseDhcp4Packet (Cache4))) {
    return;
  }

  //
  // 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;
    }
  } 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 (Private->OfferCount[OfferType] > 0) {
        //
        // Only cache the first PXE10/WFM11a offer, and discard the others.
        //
        Private->OfferIndex[OfferType][0] = Private->OfferNum;
        Private->OfferCount[OfferType]    = 1;
      } else {
        return ;
      }
    } 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++;
}


/**
  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.

**/
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.
        //
        PxeBcCopyProxyOffer (Private, ProxyIndex);
      }
    } else {
      //
      //  Othewise, 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;
    }

    PxeBcCopyDhcp4Ack (Private, Ack, TRUE);
    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;
  }

  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),
                 PXEBC_DHCP4_TAG_MAXMSG
                 );
  if (MaxMsgSize != NULL) {
    Value = HTONS (PXEBC_DHCP4_PACKET_MAX_SIZE - 8);
    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:
    //
    // 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 (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 programable if failed to get system Guid.
        //
        ZeroMem (Packet->Dhcp4.Header.ClientHwAddr, sizeof (EFI_GUID));
      }
      Packet->Dhcp4.Header.HwAddrLen = (UINT8) sizeof (EFI_GUID);
    }
    break;

  case Dhcp4RcvdOffer:
    Status = EFI_NOT_READY;
    if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) {
      //
      // Cache the DHCPv4 offers to OfferBuffer[] for select later, and record
      // the OfferIndex and OfferCount.
      //
      PxeBcCacheDhcp4Offer (Private, Packet);
    }
    break;

  case Dhcp4SelectOffer:
    //
    // 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);

    PxeBcCopyDhcp4Ack (Private, Packet, FALSE);
    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     = PXEBC_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]  = PXEBC_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 programable if failed to get system Guid.
      //
      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) {

      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) {
        PxeBcCacheDhcp4Packet (&Private->PxeReply.Dhcp4.Packet.Ack, Response);
        CopyMem (&Mode->PxeDiscover, &Token.Packet->Dhcp4, Token.Packet->Length);
      } else {
        PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Response);
      }
    } else {
      //
      // Not found the right PXE reply packet.
      //
      Status = EFI_NOT_FOUND;
    }
    if (Token.ResponseList != NULL) {
      FreePool (Token.ResponseList);
    }
  }

  FreePool (Token.Packet);
  return Status;
}


/**
  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));

  //
  // Start DHCPv4 D.O.R.A. process to acquire IPv4 address.
  //
  Status = Dhcp4->Start (Dhcp4, NULL);
  if (EFI_ERROR (Status)) {
    if (Status == EFI_ICMP_ERROR) {
      PxeMode->IcmpErrorReceived = TRUE;
    }
    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;
}
