/** @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;
  }
}

