/** @file
  Support functions implementation for UefiPxeBc Driver.

  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PxeBcImpl.h"

/**
  Flush the previous configuration using the new station Ip address.

  @param[in]   Private        The pointer to the PxeBc private data.
  @param[in]   StationIp      The pointer to the station Ip address.
  @param[in]   SubnetMask     The pointer to the subnet mask address for v4.

  @retval EFI_SUCCESS         Successfully flushed the previous configuration.
  @retval Others              Failed to flush using the new station Ip.

**/
EFI_STATUS
PxeBcFlushStationIp (
  PXEBC_PRIVATE_DATA  *Private,
  EFI_IP_ADDRESS      *StationIp      OPTIONAL,
  EFI_IP_ADDRESS      *SubnetMask     OPTIONAL
  )
{
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_STATUS              Status;
  EFI_ARP_CONFIG_DATA     ArpConfigData;

  Mode   = Private->PxeBc.Mode;
  Status = EFI_SUCCESS;
  ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));

  if (Mode->UsingIpv6 && (StationIp != NULL)) {
    //
    // Overwrite Udp6CfgData/Ip6CfgData StationAddress.
    //
    CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
    CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));

    //
    // Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.
    //
    Private->Ip6->Cancel (Private->Ip6, &Private->Icmp6Token);
    Private->Ip6->Configure (Private->Ip6, NULL);

    Status = Private->Ip6->Configure (Private->Ip6, &Private->Ip6CfgData);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);
  } else {
    if (StationIp != NULL) {
      //
      // Reconfigure the ARP instance with station Ip address.
      //
      ArpConfigData.SwAddressType   = 0x0800;
      ArpConfigData.SwAddressLength = (UINT8)sizeof (EFI_IPv4_ADDRESS);
      ArpConfigData.StationAddress  = StationIp;

      Private->Arp->Configure (Private->Arp, NULL);
      Private->Arp->Configure (Private->Arp, &ArpConfigData);

      //
      // Overwrite Udp4CfgData/Ip4CfgData StationAddress.
      //
      CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
      CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
    }

    if (SubnetMask != NULL) {
      //
      // Overwrite Udp4CfgData/Ip4CfgData SubnetMask.
      //
      CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
      CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    }

    if ((StationIp != NULL) && (SubnetMask != NULL)) {
      //
      // Updated the route table.
      //
      Mode->RouteTableEntries                = 1;
      Mode->RouteTable[0].IpAddr.Addr[0]     = StationIp->Addr[0] & SubnetMask->Addr[0];
      Mode->RouteTable[0].SubnetMask.Addr[0] = SubnetMask->Addr[0];
      Mode->RouteTable[0].GwAddr.Addr[0]     = 0;
    }

    if ((StationIp != NULL) || (SubnetMask != NULL)) {
      //
      // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.
      //
      Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);
      Private->Ip4->Configure (Private->Ip4, NULL);

      Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);
    }
  }

ON_EXIT:
  return Status;
}

/**
  Notify the callback function when an event is triggered.

  @param[in]  Event           The triggered event.
  @param[in]  Context         The opaque parameter to the function.

**/
VOID
EFIAPI
PxeBcCommonNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  *((BOOLEAN *)Context) = TRUE;
}

/**
  Do arp resolution from arp cache in PxeBcMode.

  @param  Mode           The pointer to EFI_PXE_BASE_CODE_MODE.
  @param  Ip4Addr        The Ip4 address for resolution.
  @param  MacAddress     The resolved MAC address if the resolution is successful.
                         The value is undefined if the resolution fails.

  @retval TRUE           Found an matched entry.
  @retval FALSE          Did not find a matched entry.

**/
BOOLEAN
PxeBcCheckArpCache (
  IN  EFI_PXE_BASE_CODE_MODE  *Mode,
  IN  EFI_IPv4_ADDRESS        *Ip4Addr,
  OUT EFI_MAC_ADDRESS         *MacAddress
  )
{
  UINT32  Index;

  ASSERT (!Mode->UsingIpv6);

  //
  // Check whether the current Arp cache in mode data contains this information or not.
  //
  for (Index = 0; Index < Mode->ArpCacheEntries; Index++) {
    if (EFI_IP4_EQUAL (&Mode->ArpCache[Index].IpAddr.v4, Ip4Addr)) {
      CopyMem (
        MacAddress,
        &Mode->ArpCache[Index].MacAddr,
        sizeof (EFI_MAC_ADDRESS)
        );
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Update the arp cache periodically.

  @param  Event              The pointer to EFI_PXE_BC_PROTOCOL.
  @param  Context            Context of the timer event.

**/
VOID
EFIAPI
PxeBcArpCacheUpdate (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_ARP_FIND_DATA       *ArpEntry;
  UINT32                  EntryLength;
  UINT32                  EntryCount;
  UINT32                  Index;
  EFI_STATUS              Status;

  Private = (PXEBC_PRIVATE_DATA *)Context;
  Mode    = Private->PxeBc.Mode;

  ASSERT (!Mode->UsingIpv6);

  //
  // Get the current Arp cache from Arp driver.
  //
  Status = Private->Arp->Find (
                           Private->Arp,
                           TRUE,
                           NULL,
                           &EntryLength,
                           &EntryCount,
                           &ArpEntry,
                           TRUE
                           );
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Update the Arp cache in mode data.
  //
  Mode->ArpCacheEntries = MIN (EntryCount, EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES);

  for (Index = 0; Index < Mode->ArpCacheEntries; Index++) {
    CopyMem (
      &Mode->ArpCache[Index].IpAddr,
      ArpEntry + 1,
      ArpEntry->SwAddressLength
      );
    CopyMem (
      &Mode->ArpCache[Index].MacAddr,
      (UINT8 *)(ArpEntry + 1) + ArpEntry->SwAddressLength,
      ArpEntry->HwAddressLength
      );
    ArpEntry = (EFI_ARP_FIND_DATA *)((UINT8 *)ArpEntry + EntryLength);
  }
}

/**
  Notify function to handle the received ICMP message in DPC.

  @param  Context               The PXEBC private data.

**/
VOID
EFIAPI
PxeBcIcmpErrorDpcHandle (
  IN VOID  *Context
  )
{
  EFI_STATUS              Status;
  EFI_IP4_RECEIVE_DATA    *RxData;
  EFI_IP4_PROTOCOL        *Ip4;
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  UINT8                   Type;
  UINTN                   Index;
  UINT32                  CopiedLen;
  UINT8                   *IcmpError;

  Private = (PXEBC_PRIVATE_DATA *)Context;
  Mode    = &Private->Mode;
  Status  = Private->IcmpToken.Status;
  RxData  = Private->IcmpToken.Packet.RxData;
  Ip4     = Private->Ip4;

  ASSERT (!Mode->UsingIpv6);

  if (Status == EFI_ABORTED) {
    //
    // It's triggered by user cancellation.
    //
    return;
  }

  if (RxData == NULL) {
    goto ON_EXIT;
  }

  if (Status != EFI_ICMP_ERROR) {
    //
    // The return status should be recognized as EFI_ICMP_ERROR.
    //
    goto ON_RECYCLE;
  }

  if ((EFI_IP4 (RxData->Header->SourceAddress) != 0) &&
      (NTOHL (Mode->SubnetMask.Addr[0]) != 0) &&
      IP4_NET_EQUAL (NTOHL (Mode->StationIp.Addr[0]), EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0])) &&
      !NetIp4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0])))
  {
    //
    // The source address of the received packet should be a valid unicast address.
    //
    goto ON_RECYCLE;
  }

  if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) {
    //
    // The destination address of the received packet should be equal to the host address.
    //
    goto ON_RECYCLE;
  }

  //
  // The protocol has been configured to only receive ICMP packet.
  //
  ASSERT (RxData->Header->Protocol == EFI_IP_PROTO_ICMP);

  Type = *((UINT8 *)RxData->FragmentTable[0].FragmentBuffer);

  if ((Type != ICMP_DEST_UNREACHABLE) &&
      (Type != ICMP_SOURCE_QUENCH) &&
      (Type != ICMP_REDIRECT) &&
      (Type != ICMP_TIME_EXCEEDED) &&
      (Type != ICMP_PARAMETER_PROBLEM))
  {
    //
    // The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE.
    //
    goto ON_RECYCLE;
  }

  //
  // Copy the right ICMP error message into mode data.
  //
  CopiedLen = 0;
  IcmpError = (UINT8 *)&Mode->IcmpError;

  for (Index = 0; Index < RxData->FragmentCount; Index++) {
    CopiedLen += RxData->FragmentTable[Index].FragmentLength;
    if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
      CopyMem (
        IcmpError,
        RxData->FragmentTable[Index].FragmentBuffer,
        RxData->FragmentTable[Index].FragmentLength
        );
    } else {
      CopyMem (
        IcmpError,
        RxData->FragmentTable[Index].FragmentBuffer,
        CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)
        );
    }

    IcmpError += CopiedLen;
  }

ON_RECYCLE:
  gBS->SignalEvent (RxData->RecycleSignal);

ON_EXIT:
  Private->IcmpToken.Status = EFI_NOT_READY;
  Ip4->Receive (Ip4, &Private->IcmpToken);
}

/**
  Callback function to update the latest ICMP6 error message.

  @param  Event                 The event signalled.
  @param  Context               The context passed in using the event notifier.

**/
VOID
EFIAPI
PxeBcIcmpErrorUpdate (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  QueueDpc (TPL_CALLBACK, PxeBcIcmpErrorDpcHandle, Context);
}

/**
  Notify function to handle the received ICMP6 message in DPC.

  @param  Context               The PXEBC private data.

**/
VOID
EFIAPI
PxeBcIcmp6ErrorDpcHandle (
  IN VOID  *Context
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_IP6_RECEIVE_DATA    *RxData;
  EFI_IP6_PROTOCOL        *Ip6;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_STATUS              Status;
  UINTN                   Index;
  UINT8                   Type;
  UINT32                  CopiedLen;
  UINT8                   *Icmp6Error;

  Private = (PXEBC_PRIVATE_DATA *)Context;
  Mode    = &Private->Mode;
  Status  = Private->Icmp6Token.Status;
  RxData  = Private->Icmp6Token.Packet.RxData;
  Ip6     = Private->Ip6;

  ASSERT (Mode->UsingIpv6);

  if (Status == EFI_ABORTED) {
    //
    // It's triggered by user cancellation.
    //
    return;
  }

  if (RxData == NULL) {
    goto ON_EXIT;
  }

  if (Status != EFI_ICMP_ERROR) {
    //
    // The return status should be recognized as EFI_ICMP_ERROR.
    //
    goto ON_RECYCLE;
  }

  if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) {
    //
    // The source address of the received packet should be a valid unicast address.
    //
    goto ON_RECYCLE;
  }

  if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) &&
      !EFI_IP6_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v6))
  {
    //
    // The destination address of the received packet should be equal to the host address.
    //
    goto ON_RECYCLE;
  }

  //
  // The protocol has been configured to only receive ICMP packet.
  //
  ASSERT (RxData->Header->NextHeader == IP6_ICMP);

  Type = *((UINT8 *)RxData->FragmentTable[0].FragmentBuffer);

  if ((Type != ICMP_V6_DEST_UNREACHABLE) &&
      (Type != ICMP_V6_PACKET_TOO_BIG) &&
      (Type != ICMP_V6_TIME_EXCEEDED) &&
      (Type != ICMP_V6_PARAMETER_PROBLEM))
  {
    //
    // The type of the receveid packet should be an ICMP6 error message.
    //
    goto ON_RECYCLE;
  }

  //
  // Copy the right ICMP6 error message into mode data.
  //
  CopiedLen  = 0;
  Icmp6Error = (UINT8 *)&Mode->IcmpError;

  for (Index = 0; Index < RxData->FragmentCount; Index++) {
    CopiedLen += RxData->FragmentTable[Index].FragmentLength;
    if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
      CopyMem (
        Icmp6Error,
        RxData->FragmentTable[Index].FragmentBuffer,
        RxData->FragmentTable[Index].FragmentLength
        );
    } else {
      CopyMem (
        Icmp6Error,
        RxData->FragmentTable[Index].FragmentBuffer,
        CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)
        );
    }

    Icmp6Error += CopiedLen;
  }

ON_RECYCLE:
  gBS->SignalEvent (RxData->RecycleSignal);

ON_EXIT:
  Private->Icmp6Token.Status = EFI_NOT_READY;
  Ip6->Receive (Ip6, &Private->Icmp6Token);
}

/**
  Callback function to update the latest ICMP6 error message.

  @param  Event                 The event signalled.
  @param  Context               The context passed in using the event notifier.

**/
VOID
EFIAPI
PxeBcIcmp6ErrorUpdate (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  QueueDpc (TPL_CALLBACK, PxeBcIcmp6ErrorDpcHandle, Context);
}

/**
  This function is to configure a UDPv4 instance for UdpWrite.

  @param[in]       Udp4                 The pointer to EFI_UDP4_PROTOCOL.
  @param[in]       StationIp            The pointer to the station address.
  @param[in]       SubnetMask           The pointer to the subnet mask.
  @param[in]       Gateway              The pointer to the gateway address.
  @param[in, out]  SrcPort              The pointer to the source port.
  @param[in]       DoNotFragment        If TRUE, fragment is not enabled.
                                        Otherwise, fragment is enabled.
  @param[in]       Ttl                  The time to live field of the IP header.
  @param[in]       ToS                  The type of service field of the IP header.

  @retval          EFI_SUCCESS          Successfully configured this instance.
  @retval          Others               Failed to configure this instance.

**/
EFI_STATUS
PxeBcConfigUdp4Write (
  IN     EFI_UDP4_PROTOCOL  *Udp4,
  IN     EFI_IPv4_ADDRESS   *StationIp,
  IN     EFI_IPv4_ADDRESS   *SubnetMask,
  IN     EFI_IPv4_ADDRESS   *Gateway,
  IN OUT UINT16             *SrcPort,
  IN     BOOLEAN            DoNotFragment,
  IN     UINT8              Ttl,
  IN     UINT8              ToS
  )
{
  EFI_UDP4_CONFIG_DATA  Udp4CfgData;
  EFI_STATUS            Status;

  ZeroMem (&Udp4CfgData, sizeof (Udp4CfgData));

  Udp4CfgData.TransmitTimeout    = PXEBC_DEFAULT_LIFETIME;
  Udp4CfgData.ReceiveTimeout     = PXEBC_DEFAULT_LIFETIME;
  Udp4CfgData.TypeOfService      = ToS;
  Udp4CfgData.TimeToLive         = Ttl;
  Udp4CfgData.AllowDuplicatePort = TRUE;
  Udp4CfgData.DoNotFragment      = DoNotFragment;

  CopyMem (&Udp4CfgData.StationAddress, StationIp, sizeof (*StationIp));
  CopyMem (&Udp4CfgData.SubnetMask, SubnetMask, sizeof (*SubnetMask));

  Udp4CfgData.StationPort = *SrcPort;

  //
  // Reset the UDPv4 instance.
  //
  Udp4->Configure (Udp4, NULL);

  Status = Udp4->Configure (Udp4, &Udp4CfgData);
  if (!EFI_ERROR (Status) && !EFI_IP4_EQUAL (Gateway, &mZeroIp4Addr)) {
    //
    // The basic configuration is OK, need to add the default route entry
    //
    Status = Udp4->Routes (Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, Gateway);
    if (EFI_ERROR (Status)) {
      Udp4->Configure (Udp4, NULL);
    }
  }

  if (!EFI_ERROR (Status) && (*SrcPort == 0)) {
    Udp4->GetModeData (Udp4, &Udp4CfgData, NULL, NULL, NULL);
    *SrcPort = Udp4CfgData.StationPort;
  }

  return Status;
}

/**
  This function is to configure a UDPv6 instance for UdpWrite.

  @param[in]       Udp6                 The pointer to EFI_UDP6_PROTOCOL.
  @param[in]       StationIp            The pointer to the station address.
  @param[in, out]  SrcPort              The pointer to the source port.

  @retval          EFI_SUCCESS          Successfully configured this instance.
  @retval          Others               Failed to configure this instance.

**/
EFI_STATUS
PxeBcConfigUdp6Write (
  IN     EFI_UDP6_PROTOCOL  *Udp6,
  IN     EFI_IPv6_ADDRESS   *StationIp,
  IN OUT UINT16             *SrcPort
  )
{
  EFI_UDP6_CONFIG_DATA  CfgData;
  EFI_STATUS            Status;

  ZeroMem (&CfgData, sizeof (EFI_UDP6_CONFIG_DATA));

  CfgData.ReceiveTimeout     = PXEBC_DEFAULT_LIFETIME;
  CfgData.TransmitTimeout    = PXEBC_DEFAULT_LIFETIME;
  CfgData.HopLimit           = PXEBC_DEFAULT_HOPLIMIT;
  CfgData.AllowDuplicatePort = TRUE;
  CfgData.StationPort        = *SrcPort;

  CopyMem (&CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));

  //
  // Reset the UDPv6 instance.
  //
  Udp6->Configure (Udp6, NULL);

  Status = Udp6->Configure (Udp6, &CfgData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!EFI_ERROR (Status) && (*SrcPort == 0)) {
    Udp6->GetModeData (Udp6, &CfgData, NULL, NULL, NULL);
    *SrcPort = CfgData.StationPort;
  }

  return Status;
}

/**
  This function is to configure a UDPv4 instance for UdpWrite.

  @param[in]       Udp4                 The pointer to EFI_UDP4_PROTOCOL.
  @param[in]       Session              The pointer to the UDP4 session data.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       Gateway              The pointer to the gateway address.
  @param[in]       HeaderSize           An optional field which may be set to the length of a header
                                        at HeaderPtr to be prefixed to the data at BufferPtr.
  @param[in]       HeaderPtr            If HeaderSize is not NULL, a pointer to a header to be
                                        prefixed to the data at BufferPtr.
  @param[in]       BufferSize           A pointer to the size of the data at BufferPtr.
  @param[in]       BufferPtr            A pointer to the data to be written.

  @retval          EFI_SUCCESS          Successfully send out data using Udp4Write.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp4Write (
  IN EFI_UDP4_PROTOCOL      *Udp4,
  IN EFI_UDP4_SESSION_DATA  *Session,
  IN EFI_EVENT              TimeoutEvent,
  IN EFI_IPv4_ADDRESS       *Gateway      OPTIONAL,
  IN UINTN                  *HeaderSize   OPTIONAL,
  IN VOID                   *HeaderPtr    OPTIONAL,
  IN UINTN                  *BufferSize,
  IN VOID                   *BufferPtr
  )
{
  EFI_UDP4_COMPLETION_TOKEN  Token;
  EFI_UDP4_TRANSMIT_DATA     *TxData;
  UINT32                     TxLength;
  UINT32                     FragCount;
  UINT32                     DataLength;
  BOOLEAN                    IsDone;
  EFI_STATUS                 Status;

  //
  // Arrange one fragment buffer for data, and another fragment buffer for header if has.
  //
  FragCount = (HeaderSize != NULL) ? 2 : 1;
  TxLength  = sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA);
  TxData    = (EFI_UDP4_TRANSMIT_DATA *)AllocateZeroPool (TxLength);
  if (TxData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TxData->FragmentCount                               = FragCount;
  TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32)*BufferSize;
  TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr;
  DataLength                                          = (UINT32)*BufferSize;

  if (HeaderSize != NULL) {
    TxData->FragmentTable[0].FragmentLength = (UINT32)*HeaderSize;
    TxData->FragmentTable[0].FragmentBuffer = HeaderPtr;
    DataLength                             += (UINT32)*HeaderSize;
  }

  if (Gateway != NULL) {
    TxData->GatewayAddress = Gateway;
  }

  TxData->UdpSessionData = Session;
  TxData->DataLength     = DataLength;
  Token.Packet.TxData    = TxData;
  Token.Status           = EFI_NOT_READY;
  IsDone                 = FALSE;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  PxeBcCommonNotify,
                  &IsDone,
                  &Token.Event
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = Udp4->Transmit (Udp4, &Token);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!IsDone &&
         Token.Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
  {
    Udp4->Poll (Udp4);
  }

  Status = (Token.Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token.Status;

ON_EXIT:
  if (Token.Event != NULL) {
    gBS->CloseEvent (Token.Event);
  }

  FreePool (TxData);

  return Status;
}

/**
  This function is to configure a UDPv4 instance for UdpWrite.

  @param[in]       Udp6                 The pointer to EFI_UDP6_PROTOCOL.
  @param[in]       Session              The pointer to the UDP6 session data.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       HeaderSize           An optional field which may be set to the length of a header
                                        at HeaderPtr to be prefixed to the data at BufferPtr.
  @param[in]       HeaderPtr            If HeaderSize is not NULL, a pointer to a header to be
                                        prefixed to the data at BufferPtr.
  @param[in]       BufferSize           A pointer to the size of the data at BufferPtr.
  @param[in]       BufferPtr            A pointer to the data to be written.

  @retval          EFI_SUCCESS          Successfully sent out data using Udp6Write.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp6Write (
  IN EFI_UDP6_PROTOCOL      *Udp6,
  IN EFI_UDP6_SESSION_DATA  *Session,
  IN EFI_EVENT              TimeoutEvent,
  IN UINTN                  *HeaderSize   OPTIONAL,
  IN VOID                   *HeaderPtr    OPTIONAL,
  IN UINTN                  *BufferSize,
  IN VOID                   *BufferPtr
  )
{
  EFI_UDP6_COMPLETION_TOKEN  Token;
  EFI_UDP6_TRANSMIT_DATA     *TxData;
  UINT32                     TxLength;
  UINT32                     FragCount;
  UINT32                     DataLength;
  BOOLEAN                    IsDone;
  EFI_STATUS                 Status;

  //
  // Arrange one fragment buffer for data, and another fragment buffer for header if has.
  //
  FragCount = (HeaderSize != NULL) ? 2 : 1;
  TxLength  = sizeof (EFI_UDP6_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP6_FRAGMENT_DATA);
  TxData    = (EFI_UDP6_TRANSMIT_DATA *)AllocateZeroPool (TxLength);
  if (TxData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TxData->FragmentCount                               = FragCount;
  TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32)*BufferSize;
  TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr;
  DataLength                                          = (UINT32)*BufferSize;

  if (HeaderSize != NULL) {
    TxData->FragmentTable[0].FragmentLength = (UINT32)*HeaderSize;
    TxData->FragmentTable[0].FragmentBuffer = HeaderPtr;
    DataLength                             += (UINT32)*HeaderSize;
  }

  TxData->UdpSessionData = Session;
  TxData->DataLength     = DataLength;
  Token.Packet.TxData    = TxData;
  Token.Status           = EFI_NOT_READY;
  IsDone                 = FALSE;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  PxeBcCommonNotify,
                  &IsDone,
                  &Token.Event
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = Udp6->Transmit (Udp6, &Token);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!IsDone &&
         Token.Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
  {
    Udp6->Poll (Udp6);
  }

  Status = (Token.Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token.Status;

ON_EXIT:
  if (Token.Event != NULL) {
    gBS->CloseEvent (Token.Event);
  }

  FreePool (TxData);

  return Status;
}

/**
  Check the received packet using the Ip filter.

  @param[in]  Mode                The pointer to the mode data of PxeBc.
  @param[in]  Session             The pointer to the current UDPv4 session.
  @param[in]  OpFlags             Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the Ip filter successfully.
  @retval     FALSE               Failed to pass the Ip filter.

**/
BOOLEAN
PxeBcCheckByIpFilter (
  IN EFI_PXE_BASE_CODE_MODE  *Mode,
  IN VOID                    *Session,
  IN UINT16                  OpFlags
  )
{
  EFI_IP_ADDRESS  DestinationIp;
  UINTN           Index;

  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) == 0) {
    return TRUE;
  }

  if ((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0) {
    return TRUE;
  }

  //
  // Convert the destination address in session data to host order.
  //
  if (Mode->UsingIpv6) {
    CopyMem (
      &DestinationIp,
      &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress,
      sizeof (EFI_IPv6_ADDRESS)
      );
    NTOHLLL (&DestinationIp.v6);
  } else {
    ZeroMem (&DestinationIp, sizeof (EFI_IP_ADDRESS));
    CopyMem (
      &DestinationIp,
      &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress,
      sizeof (EFI_IPv4_ADDRESS)
      );
    EFI_NTOHL (DestinationIp);
  }

  if (((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) != 0) &&
      (IP4_IS_MULTICAST (DestinationIp.Addr[0]) ||
       IP6_IS_MULTICAST (&DestinationIp)))
  {
    return TRUE;
  }

  if (((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0) &&
      IP4_IS_LOCAL_BROADCAST (DestinationIp.Addr[0]))
  {
    ASSERT (!Mode->UsingIpv6);
    return TRUE;
  }

  if (((Mode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) &&
      (EFI_IP4_EQUAL (&Mode->StationIp.v4, &DestinationIp) ||
       EFI_IP6_EQUAL (&Mode->StationIp.v6, &DestinationIp)))
  {
    //
    // Matched if the dest address is equal to the station address.
    //
    return TRUE;
  }

  for (Index = 0; Index < Mode->IpFilter.IpCnt; Index++) {
    ASSERT (Index < EFI_PXE_BASE_CODE_MAX_IPCNT);
    if (EFI_IP4_EQUAL (&Mode->IpFilter.IpList[Index].v4, &DestinationIp) ||
        EFI_IP6_EQUAL (&Mode->IpFilter.IpList[Index].v6, &DestinationIp))
    {
      //
      // Matched if the dest address is equal to any of address in the filter list.
      //
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Filter the received packet using the destination Ip.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  DestIp         The pointer to the destination Ip address.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcCheckByDestIp (
  IN     EFI_PXE_BASE_CODE_MODE  *Mode,
  IN     VOID                    *Session,
  IN OUT EFI_IP_ADDRESS          *DestIp,
  IN     UINT16                  OpFlags
  )
{
  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP) != 0) {
    //
    // Copy the destination address from the received packet if accept any.
    //
    if (DestIp != NULL) {
      if (Mode->UsingIpv6) {
        CopyMem (
          DestIp,
          &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress,
          sizeof (EFI_IPv6_ADDRESS)
          );
      } else {
        ZeroMem (DestIp, sizeof (EFI_IP_ADDRESS));
        CopyMem (
          DestIp,
          &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress,
          sizeof (EFI_IPv4_ADDRESS)
          );
      }
    }

    return TRUE;
  } else if ((DestIp != NULL) &&
             (EFI_IP4_EQUAL (DestIp, &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress) ||
              EFI_IP6_EQUAL (DestIp, &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress)))
  {
    //
    // The destination address in the received packet is matched if present.
    //
    return TRUE;
  } else if (EFI_IP4_EQUAL (&Mode->StationIp, &((EFI_UDP4_SESSION_DATA *)Session)->DestinationAddress) ||
             EFI_IP6_EQUAL (&Mode->StationIp, &((EFI_UDP6_SESSION_DATA *)Session)->DestinationAddress))
  {
    //
    // The destination address in the received packet is equal to the host address.
    //
    return TRUE;
  }

  return FALSE;
}

/**
  Check the received packet using the destination port.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  DestPort       The pointer to the destination port.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcCheckByDestPort (
  IN     EFI_PXE_BASE_CODE_MODE  *Mode,
  IN     VOID                    *Session,
  IN OUT UINT16                  *DestPort,
  IN     UINT16                  OpFlags
  )
{
  UINT16  Port;

  if (Mode->UsingIpv6) {
    Port = ((EFI_UDP6_SESSION_DATA *)Session)->DestinationPort;
  } else {
    Port = ((EFI_UDP4_SESSION_DATA *)Session)->DestinationPort;
  }

  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) != 0) {
    //
    // Return the destination port in the received packet if accept any.
    //
    if (DestPort != NULL) {
      *DestPort = Port;
    }

    return TRUE;
  } else if ((DestPort != NULL) && (*DestPort == Port)) {
    //
    // The destination port in the received packet is matched if present.
    //
    return TRUE;
  }

  return FALSE;
}

/**
  Filter the received packet using the source Ip.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  SrcIp          The pointer to the source Ip address.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcFilterBySrcIp (
  IN     EFI_PXE_BASE_CODE_MODE  *Mode,
  IN     VOID                    *Session,
  IN OUT EFI_IP_ADDRESS          *SrcIp,
  IN     UINT16                  OpFlags
  )
{
  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) != 0) {
    //
    // Copy the source address from the received packet if accept any.
    //
    if (SrcIp != NULL) {
      if (Mode->UsingIpv6) {
        CopyMem (
          SrcIp,
          &((EFI_UDP6_SESSION_DATA *)Session)->SourceAddress,
          sizeof (EFI_IPv6_ADDRESS)
          );
      } else {
        ZeroMem (SrcIp, sizeof (EFI_IP_ADDRESS));
        CopyMem (
          SrcIp,
          &((EFI_UDP4_SESSION_DATA *)Session)->SourceAddress,
          sizeof (EFI_IPv4_ADDRESS)
          );
      }
    }

    return TRUE;
  } else if ((SrcIp != NULL) &&
             (EFI_IP4_EQUAL (SrcIp, &((EFI_UDP4_SESSION_DATA *)Session)->SourceAddress) ||
              EFI_IP6_EQUAL (SrcIp, &((EFI_UDP6_SESSION_DATA *)Session)->SourceAddress)))
  {
    //
    // The source address in the received packet is matched if present.
    //
    return TRUE;
  }

  return FALSE;
}

/**
  Filter the received packet using the source port.

  @param[in]       Mode           The pointer to the mode data of PxeBc.
  @param[in]       Session        The pointer to the current UDPv4 session.
  @param[in, out]  SrcPort        The pointer to the source port.
  @param[in]       OpFlags        Operation flag for UdpRead/UdpWrite.

  @retval     TRUE                Passed the IPv4 filter successfully.
  @retval     FALSE               Failed to pass the IPv4 filter.

**/
BOOLEAN
PxeBcFilterBySrcPort (
  IN     EFI_PXE_BASE_CODE_MODE  *Mode,
  IN     VOID                    *Session,
  IN OUT UINT16                  *SrcPort,
  IN     UINT16                  OpFlags
  )
{
  UINT16  Port;

  if (Mode->UsingIpv6) {
    Port = ((EFI_UDP6_SESSION_DATA *)Session)->SourcePort;
  } else {
    Port = ((EFI_UDP4_SESSION_DATA *)Session)->SourcePort;
  }

  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) != 0) {
    //
    // Return the source port in the received packet if accept any.
    //
    if (SrcPort != NULL) {
      *SrcPort = Port;
    }

    return TRUE;
  } else if ((SrcPort != NULL) && (*SrcPort == Port)) {
    //
    // The source port in the received packet is matched if present.
    //
    return TRUE;
  }

  return FALSE;
}

/**
  This function is to receive packet using Udp4Read.

  @param[in]       Udp4                 The pointer to EFI_UDP4_PROTOCOL.
  @param[in]       Token                The pointer to EFI_UDP4_COMPLETION_TOKEN.
  @param[in]       Mode                 The pointer to EFI_PXE_BASE_CODE_MODE.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       OpFlags              The UDP operation flags.
  @param[in]       IsDone               The pointer to the IsDone flag.
  @param[out]      IsMatched            The pointer to the IsMatched flag.
  @param[in, out]  DestIp               The pointer to the destination address.
  @param[in, out]  DestPort             The pointer to the destination port.
  @param[in, out]  SrcIp                The pointer to the source address.
  @param[in, out]  SrcPort              The pointer to the source port.

  @retval          EFI_SUCCESS          Successfully read the data using Udp4.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp4Read (
  IN     EFI_UDP4_PROTOCOL           *Udp4,
  IN     EFI_UDP4_COMPLETION_TOKEN   *Token,
  IN     EFI_PXE_BASE_CODE_MODE      *Mode,
  IN     EFI_EVENT                   TimeoutEvent,
  IN     UINT16                      OpFlags,
  IN     BOOLEAN                     *IsDone,
  OUT BOOLEAN                        *IsMatched,
  IN OUT EFI_IP_ADDRESS              *DestIp      OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *DestPort    OPTIONAL,
  IN OUT EFI_IP_ADDRESS              *SrcIp       OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *SrcPort     OPTIONAL
  )
{
  EFI_UDP4_RECEIVE_DATA  *RxData;
  EFI_UDP4_SESSION_DATA  *Session;
  EFI_STATUS             Status;

  Token->Status = EFI_NOT_READY;
  *IsDone       = FALSE;

  Status = Udp4->Receive (Udp4, Token);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!(*IsDone) &&
         Token->Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
  {
    //
    // Poll the token until reply/ICMPv6 error message received or timeout.
    //
    Udp4->Poll (Udp4);
    if ((Token->Status == EFI_ICMP_ERROR) ||
        (Token->Status == EFI_NETWORK_UNREACHABLE) ||
        (Token->Status == EFI_HOST_UNREACHABLE) ||
        (Token->Status == EFI_PROTOCOL_UNREACHABLE) ||
        (Token->Status == EFI_PORT_UNREACHABLE))
    {
      break;
    }
  }

  Status = (Token->Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token->Status;

  if (!EFI_ERROR (Status)) {
    //
    // check whether this packet matches the filters
    //
    RxData  = Token->Packet.RxData;
    Session = &RxData->UdpSession;

    *IsMatched = PxeBcCheckByIpFilter (Mode, Session, OpFlags);

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestIp (Mode, Session, DestIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestPort (Mode, Session, DestPort, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcIp (Mode, Session, SrcIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcPort (Mode, Session, SrcPort, OpFlags);
    }

    if (!(*IsMatched)) {
      //
      // Recycle the receiving buffer if not matched.
      //
      gBS->SignalEvent (RxData->RecycleSignal);
    }
  }

  return Status;
}

/**
  This function is to receive packets using Udp6Read.

  @param[in]       Udp6                 The pointer to EFI_UDP6_PROTOCOL.
  @param[in]       Token                The pointer to EFI_UDP6_COMPLETION_TOKEN.
  @param[in]       Mode                 The pointer to EFI_PXE_BASE_CODE_MODE.
  @param[in]       TimeoutEvent         The event for timeout.
  @param[in]       OpFlags              The UDP operation flags.
  @param[in]       IsDone               The pointer to the IsDone flag.
  @param[out]      IsMatched            The pointer to the IsMatched flag.
  @param[in, out]  DestIp               The pointer to the destination address.
  @param[in, out]  DestPort             The pointer to the destination port.
  @param[in, out]  SrcIp                The pointer to the source address.
  @param[in, out]  SrcPort              The pointer to the source port.

  @retval          EFI_SUCCESS          Successfully read data using Udp6.
  @retval          Others               Failed to send out data.

**/
EFI_STATUS
PxeBcUdp6Read (
  IN     EFI_UDP6_PROTOCOL           *Udp6,
  IN     EFI_UDP6_COMPLETION_TOKEN   *Token,
  IN     EFI_PXE_BASE_CODE_MODE      *Mode,
  IN     EFI_EVENT                   TimeoutEvent,
  IN     UINT16                      OpFlags,
  IN     BOOLEAN                     *IsDone,
  OUT BOOLEAN                        *IsMatched,
  IN OUT EFI_IP_ADDRESS              *DestIp      OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *DestPort    OPTIONAL,
  IN OUT EFI_IP_ADDRESS              *SrcIp       OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT  *SrcPort     OPTIONAL
  )
{
  EFI_UDP6_RECEIVE_DATA  *RxData;
  EFI_UDP6_SESSION_DATA  *Session;
  EFI_STATUS             Status;

  Token->Status = EFI_NOT_READY;
  *IsDone       = FALSE;

  Status = Udp6->Receive (Udp6, Token);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Poll the UDPv6 read instance if no packet received and no timeout triggered.
  //
  while (!(*IsDone) &&
         Token->Status == EFI_NOT_READY &&
         EFI_ERROR (gBS->CheckEvent (TimeoutEvent)))
  {
    //
    // Poll the token until reply/ICMPv6 error message received or timeout.
    //
    Udp6->Poll (Udp6);
    if ((Token->Status == EFI_ICMP_ERROR) ||
        (Token->Status == EFI_NETWORK_UNREACHABLE) ||
        (Token->Status == EFI_HOST_UNREACHABLE) ||
        (Token->Status == EFI_PROTOCOL_UNREACHABLE) ||
        (Token->Status == EFI_PORT_UNREACHABLE))
    {
      break;
    }
  }

  Status = (Token->Status == EFI_NOT_READY) ? EFI_TIMEOUT : Token->Status;

  if (!EFI_ERROR (Status)) {
    //
    // check whether this packet matches the filters
    //
    RxData  = Token->Packet.RxData;
    Session = &RxData->UdpSession;

    *IsMatched = PxeBcCheckByIpFilter (Mode, Session, OpFlags);

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestIp (Mode, Session, DestIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcCheckByDestPort (Mode, Session, DestPort, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcIp (Mode, Session, SrcIp, OpFlags);
    }

    if (*IsMatched) {
      *IsMatched = PxeBcFilterBySrcPort (Mode, Session, SrcPort, OpFlags);
    }

    if (!(*IsMatched)) {
      //
      // Recycle the receiving buffer if not matched.
      //
      gBS->SignalEvent (RxData->RecycleSignal);
    }
  }

  return Status;
}

/**
  This function is to display the IPv4 address.

  @param[in]  Ip        The pointer to the IPv4 address.

**/
VOID
PxeBcShowIp4Addr (
  IN EFI_IPv4_ADDRESS  *Ip
  )
{
  UINTN  Index;

  for (Index = 0; Index < 4; Index++) {
    AsciiPrint ("%d", Ip->Addr[Index]);
    if (Index < 3) {
      AsciiPrint (".");
    }
  }
}

/**
  This function is to display the IPv6 address.

  @param[in]  Ip        The pointer to the IPv6 address.

**/
VOID
PxeBcShowIp6Addr (
  IN EFI_IPv6_ADDRESS  *Ip
  )
{
  UINTN  Index;

  for (Index = 0; Index < 16; Index++) {
    if (Ip->Addr[Index] != 0) {
      AsciiPrint ("%x", Ip->Addr[Index]);
    }

    Index++;
    if (Index > 15) {
      return;
    }

    if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {
      AsciiPrint ("0");
    }

    AsciiPrint ("%x", Ip->Addr[Index]);
    if (Index < 15) {
      AsciiPrint (":");
    }
  }
}

/**
  This function is to convert UINTN to ASCII string with the required formatting.

  @param[in]  Number         Numeric value to be converted.
  @param[in]  Buffer         The pointer to the buffer for ASCII string.
  @param[in]  Length         The length of the required format.

**/
VOID
PxeBcUintnToAscDecWithFormat (
  IN UINTN  Number,
  IN UINT8  *Buffer,
  IN INTN   Length
  )
{
  UINTN  Remainder;

  for ( ; Length > 0; Length--) {
    Remainder          = Number % 10;
    Number            /= 10;
    Buffer[Length - 1] = (UINT8)('0' + Remainder);
  }
}

/**
  This function is to convert a UINTN to a ASCII string, and return the
  actual length of the buffer.

  @param[in]  Number         Numeric value to be converted.
  @param[in]  Buffer         The pointer to the buffer for ASCII string.
  @param[in]  BufferSize     The maxsize of the buffer.

  @return     Length         The actual length of the ASCII string.

**/
UINTN
PxeBcUintnToAscDec (
  IN UINTN  Number,
  IN UINT8  *Buffer,
  IN UINTN  BufferSize
  )
{
  UINTN  Index;
  UINTN  Length;
  CHAR8  TempStr[64];

  Index          = 63;
  TempStr[Index] = 0;

  do {
    Index--;
    TempStr[Index] = (CHAR8)('0' + (Number % 10));
    Number         = (UINTN)(Number / 10);
  } while (Number != 0);

  AsciiStrCpyS ((CHAR8 *)Buffer, BufferSize, &TempStr[Index]);

  Length = AsciiStrLen ((CHAR8 *)Buffer);

  return Length;
}

/**
  This function is to convert unicode hex number to a UINT8.

  @param[out]  Digit                   The converted UINT8 for output.
  @param[in]   Char                    The unicode hex number to be converted.

  @retval      EFI_SUCCESS             Successfully converted the unicode hex.
  @retval      EFI_INVALID_PARAMETER   Failed to convert the unicode hex.

**/
EFI_STATUS
PxeBcUniHexToUint8 (
  OUT UINT8   *Digit,
  IN  CHAR16  Char
  )
{
  if ((Char >= L'0') && (Char <= L'9')) {
    *Digit = (UINT8)(Char - L'0');
    return EFI_SUCCESS;
  }

  if ((Char >= L'A') && (Char <= L'F')) {
    *Digit = (UINT8)(Char - L'A' + 0x0A);
    return EFI_SUCCESS;
  }

  if ((Char >= L'a') && (Char <= L'f')) {
    *Digit = (UINT8)(Char - L'a' + 0x0A);
    return EFI_SUCCESS;
  }

  return EFI_INVALID_PARAMETER;
}

/**
  Calculate the elapsed time.

  @param[in]      Private      The pointer to PXE private data

**/
VOID
CalcElapsedTime (
  IN     PXEBC_PRIVATE_DATA  *Private
  )
{
  EFI_TIME  Time;
  UINT64    CurrentStamp;
  UINT64    ElapsedTimeValue;

  //
  // Generate a time stamp of the centiseconds from 1900/1/1, assume 30day/month.
  //
  ZeroMem (&Time, sizeof (EFI_TIME));
  gRT->GetTime (&Time, NULL);
  CurrentStamp = MultU64x32 (
                   ((((UINT32)(Time.Year - 1900) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) * 60 + Time.Second,
                   100
                   ) +
                 DivU64x32 (
                   Time.Nanosecond,
                   10000000
                   );

  //
  // Sentinel value of 0 means that this is the first DHCP packet that we are
  // sending and that we need to initialize the value.  First DHCP Solicit
  // gets 0 elapsed-time.  Otherwise, calculate based on StartTime.
  //
  if (Private->ElapsedTime == 0) {
    Private->ElapsedTime = CurrentStamp;
  } else {
    ElapsedTimeValue = CurrentStamp - Private->ElapsedTime;

    //
    // If elapsed time cannot fit in two bytes, set it to 0xffff.
    //
    if (ElapsedTimeValue > 0xffff) {
      ElapsedTimeValue = 0xffff;
    }

    //
    // Save the elapsed time
    //
    Private->ElapsedTime = ElapsedTimeValue;
  }
}
