/** @file
  EFI DHCP protocol implementation.

Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Dhcp4Impl.h"

UINT32  mDhcp4DefaultTimeout[4] = { 4, 8, 16, 32 };

/**
  Send an initial DISCOVER or REQUEST message according to the
  DHCP service's current state.

  @param[in]  DhcpSb                The DHCP service instance

  @retval EFI_SUCCESS           The request has been sent
  @retval other                 Some error occurs when sending the request.

**/
EFI_STATUS
DhcpInitRequest (
  IN DHCP_SERVICE  *DhcpSb
  )
{
  EFI_STATUS  Status;

  ASSERT ((DhcpSb->DhcpState == Dhcp4Init) || (DhcpSb->DhcpState == Dhcp4InitReboot));

  //
  // Clear initial time to make sure that elapsed-time is set to 0 for first Discover or REQUEST message.
  //
  DhcpSb->ActiveChild->ElaspedTime = 0;

  if (DhcpSb->DhcpState == Dhcp4Init) {
    DhcpSetState (DhcpSb, Dhcp4Selecting, FALSE);
    Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_DISCOVER, NULL);

    if (EFI_ERROR (Status)) {
      DhcpSb->DhcpState = Dhcp4Init;
      return Status;
    }
  } else {
    DhcpSetState (DhcpSb, Dhcp4Rebooting, FALSE);
    Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_REQUEST, NULL);

    if (EFI_ERROR (Status)) {
      DhcpSb->DhcpState = Dhcp4InitReboot;
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Call user provided callback function, and return the value the
  function returns. If the user doesn't provide a callback, a
  proper return value is selected to let the caller continue the
  normal process.

  @param[in]  DhcpSb                The DHCP service instance
  @param[in]  Event                 The event as defined in the spec
  @param[in]  Packet                The current packet trigger the event
  @param[out] NewPacket             The user's return new packet

  @retval EFI_NOT_READY         Direct the caller to continue collecting the offer.
  @retval EFI_SUCCESS           The user function returns success.
  @retval EFI_ABORTED           The user function ask it to abort.

**/
EFI_STATUS
DhcpCallUser (
  IN  DHCP_SERVICE      *DhcpSb,
  IN  EFI_DHCP4_EVENT   Event,
  IN  EFI_DHCP4_PACKET  *Packet       OPTIONAL,
  OUT EFI_DHCP4_PACKET  **NewPacket   OPTIONAL
  )
{
  EFI_DHCP4_CONFIG_DATA  *Config;
  EFI_STATUS             Status;

  if (NewPacket != NULL) {
    *NewPacket = NULL;
  }

  //
  // If user doesn't provide the call back function, return the value
  // that directs the client to continue the normal process.
  // In Dhcp4Selecting EFI_SUCCESS tells the client to stop collecting
  // the offers and select a offer, EFI_NOT_READY tells the client to
  // collect more offers.
  //
  Config = &DhcpSb->ActiveConfig;

  if (Config->Dhcp4Callback == NULL) {
    if (Event == Dhcp4RcvdOffer) {
      return EFI_NOT_READY;
    }

    return EFI_SUCCESS;
  }

  Status = Config->Dhcp4Callback (
                     &DhcpSb->ActiveChild->Dhcp4Protocol,
                     Config->CallbackContext,
                     (EFI_DHCP4_STATE)DhcpSb->DhcpState,
                     Event,
                     Packet,
                     NewPacket
                     );

  //
  // User's callback should only return EFI_SUCCESS, EFI_NOT_READY,
  // and EFI_ABORTED. If it returns values other than those, assume
  // it to be EFI_ABORTED.
  //
  if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_READY)) {
    return Status;
  }

  return EFI_ABORTED;
}

/**
  Notify the user about the operation result.

  @param  DhcpSb                DHCP service instance
  @param  Which                 Which notify function to signal

**/
VOID
DhcpNotifyUser (
  IN DHCP_SERVICE  *DhcpSb,
  IN INTN          Which
  )
{
  DHCP_PROTOCOL  *Child;

  if ((Child = DhcpSb->ActiveChild) == NULL) {
    return;
  }

  if ((Child->CompletionEvent != NULL) &&
      ((Which == DHCP_NOTIFY_COMPLETION) || (Which == DHCP_NOTIFY_ALL))
      )
  {
    gBS->SignalEvent (Child->CompletionEvent);
    Child->CompletionEvent = NULL;
  }

  if ((Child->RenewRebindEvent != NULL) &&
      ((Which == DHCP_NOTIFY_RENEWREBIND) || (Which == DHCP_NOTIFY_ALL))
      )
  {
    gBS->SignalEvent (Child->RenewRebindEvent);
    Child->RenewRebindEvent = NULL;
  }
}

/**
  Set the DHCP state. If CallUser is true, it will try to notify
  the user before change the state by DhcpNotifyUser. It returns
  EFI_ABORTED if the user return EFI_ABORTED, otherwise, it returns
  EFI_SUCCESS. If CallUser is FALSE, it isn't necessary to test
  the return value of this function.

  @param  DhcpSb                The DHCP service instance
  @param  State                 The new DHCP state to change to
  @param  CallUser              Whether we need to call user

  @retval EFI_SUCCESS           The state is changed
  @retval EFI_ABORTED           The user asks to abort the DHCP process.

**/
EFI_STATUS
DhcpSetState (
  IN OUT DHCP_SERVICE  *DhcpSb,
  IN     INTN          State,
  IN     BOOLEAN       CallUser
  )
{
  EFI_STATUS  Status;

  if (CallUser) {
    Status = EFI_SUCCESS;

    if (State == Dhcp4Renewing) {
      Status = DhcpCallUser (DhcpSb, Dhcp4EnterRenewing, NULL, NULL);
    } else if (State == Dhcp4Rebinding) {
      Status = DhcpCallUser (DhcpSb, Dhcp4EnterRebinding, NULL, NULL);
    } else if (State == Dhcp4Bound) {
      Status = DhcpCallUser (DhcpSb, Dhcp4BoundCompleted, NULL, NULL);
    }

    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Update the retransmission timer during the state transition.
  // This will clear the retry count. This is also why the rule
  // first transit the state, then send packets.
  //
  if (State == Dhcp4Selecting) {
    DhcpSb->MaxRetries = DhcpSb->ActiveConfig.DiscoverTryCount;
  } else {
    DhcpSb->MaxRetries = DhcpSb->ActiveConfig.RequestTryCount;
  }

  if (DhcpSb->MaxRetries == 0) {
    DhcpSb->MaxRetries = 4;
  }

  DhcpSb->CurRetry     = 0;
  DhcpSb->PacketToLive = 0;
  DhcpSb->LastTimeout  = 0;
  DhcpSb->DhcpState    = State;
  return EFI_SUCCESS;
}

/**
  Set the retransmit timer for the packet. It will select from either
  the discover timeouts/request timeouts or the default timeout values.

  @param  DhcpSb                The DHCP service instance.

**/
VOID
DhcpSetTransmitTimer (
  IN OUT DHCP_SERVICE  *DhcpSb
  )
{
  UINT32  *Times;

  ASSERT (DhcpSb->MaxRetries > DhcpSb->CurRetry);

  if (DhcpSb->DhcpState == Dhcp4Selecting) {
    Times = DhcpSb->ActiveConfig.DiscoverTimeout;
  } else {
    Times = DhcpSb->ActiveConfig.RequestTimeout;
  }

  if (Times == NULL) {
    Times = mDhcp4DefaultTimeout;
  }

  DhcpSb->PacketToLive = Times[DhcpSb->CurRetry];
  DhcpSb->LastTimeout  = DhcpSb->PacketToLive;

  return;
}

/**
  Compute the lease. If the server grants a permanent lease, just
  process it as a normal timeout value since the lease will last
  more than 100 years.

  @param  DhcpSb                The DHCP service instance
  @param  Para                  The DHCP parameter extracted from the server's
                                response.
**/
VOID
DhcpComputeLease (
  IN OUT DHCP_SERVICE    *DhcpSb,
  IN     DHCP_PARAMETER  *Para
  )
{
  ASSERT (Para != NULL);

  DhcpSb->Lease = Para->Lease;
  DhcpSb->T2    = Para->T2;
  DhcpSb->T1    = Para->T1;

  if (DhcpSb->Lease == 0) {
    DhcpSb->Lease = DHCP_DEFAULT_LEASE;
  }

  if ((DhcpSb->T2 == 0) || (DhcpSb->T2 >= Para->Lease)) {
    DhcpSb->T2 = Para->Lease - (Para->Lease >> 3);
  }

  if ((DhcpSb->T1 == 0) || (DhcpSb->T1 >= Para->T2)) {
    DhcpSb->T1 = DhcpSb->Lease >> 1;
  }
}

/**
  Configure a UDP IO port to use the acquired lease address.
  DHCP driver needs this port to unicast packet to the server
  such as DHCP release.

  @param[in]  UdpIo                 The UDP IO to configure
  @param[in]  Context               Dhcp service instance.

  @retval EFI_SUCCESS           The UDP IO port is successfully configured.
  @retval Others                It failed to configure the port.

**/
EFI_STATUS
EFIAPI
DhcpConfigLeaseIoPort (
  IN UDP_IO  *UdpIo,
  IN VOID    *Context
  )
{
  EFI_UDP4_CONFIG_DATA  UdpConfigData;
  EFI_IPv4_ADDRESS      Subnet;
  EFI_IPv4_ADDRESS      Gateway;
  DHCP_SERVICE          *DhcpSb;
  EFI_STATUS            Status;
  IP4_ADDR              Ip;

  DhcpSb = (DHCP_SERVICE *)Context;

  UdpConfigData.AcceptBroadcast    = FALSE;
  UdpConfigData.AcceptPromiscuous  = FALSE;
  UdpConfigData.AcceptAnyPort      = FALSE;
  UdpConfigData.AllowDuplicatePort = TRUE;
  UdpConfigData.TypeOfService      = 0;
  UdpConfigData.TimeToLive         = 64;
  UdpConfigData.DoNotFragment      = FALSE;
  UdpConfigData.ReceiveTimeout     = 1;
  UdpConfigData.TransmitTimeout    = 0;

  UdpConfigData.UseDefaultAddress = FALSE;
  UdpConfigData.StationPort       = DHCP_CLIENT_PORT;
  UdpConfigData.RemotePort        = DHCP_SERVER_PORT;

  Ip = HTONL (DhcpSb->ClientAddr);
  CopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));

  Ip = HTONL (DhcpSb->Netmask);
  CopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));

  ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));

  Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Add a default route if received from the server.
  //
  if ((DhcpSb->Para != NULL) && (DhcpSb->Para->Router != 0)) {
    ZeroMem (&Subnet, sizeof (EFI_IPv4_ADDRESS));

    Ip = HTONL (DhcpSb->Para->Router);
    CopyMem (&Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS));

    UdpIo->Protocol.Udp4->Routes (UdpIo->Protocol.Udp4, FALSE, &Subnet, &Subnet, &Gateway);
  }

  return EFI_SUCCESS;
}

/**
  Update the lease states when a new lease is acquired. It will not only
  save the acquired the address and lease time, it will also create a UDP
  child to provide address resolution for the address.

  @param  DhcpSb                The DHCP service instance

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resources.
  @retval EFI_SUCCESS           The lease is recorded.

**/
EFI_STATUS
DhcpLeaseAcquired (
  IN OUT DHCP_SERVICE  *DhcpSb
  )
{
  DhcpSb->ClientAddr = EFI_NTOHL (DhcpSb->Selected->Dhcp4.Header.YourAddr);

  if (DhcpSb->Para != NULL) {
    DhcpSb->Netmask    = DhcpSb->Para->NetMask;
    DhcpSb->ServerAddr = DhcpSb->Para->ServerId;
  }

  if (DhcpSb->Netmask == 0) {
    return EFI_ABORTED;
  }

  if (DhcpSb->LeaseIoPort != NULL) {
    UdpIoFreeIo (DhcpSb->LeaseIoPort);
  }

  //
  // Create a UDP/IP child to provide ARP service for the Leased IP,
  // and transmit unicast packet with it as source address. Don't
  // start receive on this port, the queued packet will be timeout.
  //
  DhcpSb->LeaseIoPort = UdpIoCreateIo (
                          DhcpSb->Controller,
                          DhcpSb->Image,
                          DhcpConfigLeaseIoPort,
                          UDP_IO_UDP4_VERSION,
                          DhcpSb
                          );

  if (DhcpSb->LeaseIoPort == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (!DHCP_IS_BOOTP (DhcpSb->Para)) {
    DhcpComputeLease (DhcpSb, DhcpSb->Para);
  }

  return DhcpSetState (DhcpSb, Dhcp4Bound, TRUE);
}

/**
  Clean up the DHCP related states, IoStatus isn't reset.

  @param  DhcpSb                The DHCP instance service.

**/
VOID
DhcpCleanLease (
  IN DHCP_SERVICE  *DhcpSb
  )
{
  DhcpSb->DhcpState  = Dhcp4Init;
  DhcpSb->Xid        = DhcpSb->Xid + 1;
  DhcpSb->ClientAddr = 0;
  DhcpSb->Netmask    = 0;
  DhcpSb->ServerAddr = 0;

  if (DhcpSb->LastOffer != NULL) {
    FreePool (DhcpSb->LastOffer);
    DhcpSb->LastOffer = NULL;
  }

  if (DhcpSb->Selected != NULL) {
    FreePool (DhcpSb->Selected);
    DhcpSb->Selected = NULL;
  }

  if (DhcpSb->Para != NULL) {
    FreePool (DhcpSb->Para);
    DhcpSb->Para = NULL;
  }

  DhcpSb->Lease        = 0;
  DhcpSb->T1           = 0;
  DhcpSb->T2           = 0;
  DhcpSb->ExtraRefresh = FALSE;

  if (DhcpSb->LeaseIoPort != NULL) {
    UdpIoFreeIo (DhcpSb->LeaseIoPort);
    DhcpSb->LeaseIoPort = NULL;
  }

  if (DhcpSb->LastPacket != NULL) {
    FreePool (DhcpSb->LastPacket);
    DhcpSb->LastPacket = NULL;
  }

  DhcpSb->PacketToLive = 0;
  DhcpSb->LastTimeout  = 0;
  DhcpSb->CurRetry     = 0;
  DhcpSb->MaxRetries   = 0;
  DhcpSb->LeaseLife    = 0;

  //
  // Clean active config data.
  //
  DhcpCleanConfigure (&DhcpSb->ActiveConfig);
}

/**
  Select a offer among all the offers collected. If the offer selected is
  of BOOTP, the lease is recorded and user notified. If the offer is of
  DHCP, it will request the offer from the server.

  @param[in]  DhcpSb                The DHCP service instance.

  @retval EFI_SUCCESS           One of the offer is selected.

**/
EFI_STATUS
DhcpChooseOffer (
  IN DHCP_SERVICE  *DhcpSb
  )
{
  EFI_DHCP4_PACKET  *Selected;
  EFI_DHCP4_PACKET  *NewPacket;
  EFI_DHCP4_PACKET  *TempPacket;
  EFI_STATUS        Status;

  ASSERT (DhcpSb->LastOffer != NULL);

  //
  // User will cache previous offers if he wants to select
  // from multiple offers. If user provides an invalid packet,
  // use the last offer, otherwise use the provided packet.
  //
  NewPacket = NULL;
  Status    = DhcpCallUser (DhcpSb, Dhcp4SelectOffer, DhcpSb->LastOffer, &NewPacket);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Selected = DhcpSb->LastOffer;

  if ((NewPacket != NULL) && !EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) {
    TempPacket = (EFI_DHCP4_PACKET *)AllocatePool (NewPacket->Size);
    if (TempPacket != NULL) {
      CopyMem (TempPacket, NewPacket, NewPacket->Size);
      FreePool (Selected);
      Selected = TempPacket;
    }
  }

  DhcpSb->Selected  = Selected;
  DhcpSb->LastOffer = NULL;
  DhcpSb->Para      = NULL;
  DhcpValidateOptions (Selected, &DhcpSb->Para);

  //
  // A bootp offer has been selected, save the lease status,
  // enter bound state then notify the user.
  //
  if (DHCP_IS_BOOTP (DhcpSb->Para)) {
    Status = DhcpLeaseAcquired (DhcpSb);

    if (EFI_ERROR (Status)) {
      return Status;
    }

    DhcpSb->IoStatus = EFI_SUCCESS;
    DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_ALL);
    return EFI_SUCCESS;
  }

  //
  // Send a DHCP requests
  //
  Status = DhcpSetState (DhcpSb, Dhcp4Requesting, TRUE);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  return DhcpSendMessage (DhcpSb, Selected, DhcpSb->Para, DHCP_MSG_REQUEST, NULL);
}

/**
  Terminate the current address acquire. All the allocated resources
  are released. Be careful when calling this function. A rule related
  to this is: only call DhcpEndSession at the highest level, such as
  DhcpInput, DhcpOnTimerTick...At the other level, just return error.

  @param[in]  DhcpSb                The DHCP service instance
  @param[in]  Status                The result of the DHCP process.

**/
VOID
DhcpEndSession (
  IN DHCP_SERVICE  *DhcpSb,
  IN EFI_STATUS    Status
  )
{
  if (DHCP_CONNECTED (DhcpSb->DhcpState)) {
    DhcpCallUser (DhcpSb, Dhcp4AddressLost, NULL, NULL);
  } else {
    DhcpCallUser (DhcpSb, Dhcp4Fail, NULL, NULL);
  }

  DhcpCleanLease (DhcpSb);

  DhcpSb->IoStatus = Status;
  DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_ALL);
}

/**
  Handle packets in DHCP select state.

  @param[in]  DhcpSb                The DHCP service instance
  @param[in]  Packet                The DHCP packet received
  @param[in]  Para                  The DHCP parameter extracted from the packet. That
                                    is, all the option value that we care.

  @retval EFI_SUCCESS           The packet is successfully processed.
  @retval Others                Some error occurred.

**/
EFI_STATUS
DhcpHandleSelect (
  IN DHCP_SERVICE      *DhcpSb,
  IN EFI_DHCP4_PACKET  *Packet,
  IN DHCP_PARAMETER    *Para
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  //
  // First validate the message:
  // 1. the offer is a unicast
  // 2. if it is a DHCP message, it must contains a server ID.
  // Don't return a error for these two case otherwise the session is ended.
  //
  if (!DHCP_IS_BOOTP (Para) &&
      ((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))
      )
  {
    goto ON_EXIT;
  }

  //
  // Call the user's callback. The action according to the return is as:
  // 1. EFI_SUCCESS: stop waiting for more offers, select the offer now
  // 2. EFI_NOT_READY: wait for more offers
  // 3. EFI_ABORTED: abort the address acquiring.
  //
  Status = DhcpCallUser (DhcpSb, Dhcp4RcvdOffer, Packet, NULL);

  if (Status == EFI_SUCCESS) {
    if (DhcpSb->LastOffer != NULL) {
      FreePool (DhcpSb->LastOffer);
    }

    DhcpSb->LastOffer = Packet;

    return DhcpChooseOffer (DhcpSb);
  } else if (Status == EFI_NOT_READY) {
    if (DhcpSb->LastOffer != NULL) {
      FreePool (DhcpSb->LastOffer);
    }

    DhcpSb->LastOffer = Packet;
  } else if (Status == EFI_ABORTED) {
    //
    // DhcpInput will end the session upon error return. Remember
    // only to call DhcpEndSession at the top level call.
    //
    goto ON_EXIT;
  }

  return EFI_SUCCESS;

ON_EXIT:
  FreePool (Packet);
  return Status;
}

/**
  Handle packets in DHCP request state.

  @param[in]  DhcpSb                The DHCP service instance
  @param[in]  Packet                The DHCP packet received
  @param[in]  Para                  The DHCP parameter extracted from the packet. That
                                    is, all the option value that we care.

  @retval EFI_SUCCESS           The packet is successfully processed.
  @retval Others                Some error occurred.

**/
EFI_STATUS
DhcpHandleRequest (
  IN DHCP_SERVICE      *DhcpSb,
  IN EFI_DHCP4_PACKET  *Packet,
  IN DHCP_PARAMETER    *Para
  )
{
  EFI_DHCP4_HEADER  *Head;
  EFI_DHCP4_HEADER  *Selected;
  EFI_STATUS        Status;
  UINT8             *Message;

  ASSERT (!DHCP_IS_BOOTP (DhcpSb->Para));

  Head     = &Packet->Dhcp4.Header;
  Selected = &DhcpSb->Selected->Dhcp4.Header;

  //
  // Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK.
  //
  if (DHCP_IS_BOOTP (Para) ||
      (Para->ServerId != DhcpSb->Para->ServerId) ||
      ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))
      )
  {
    Status = EFI_SUCCESS;
    goto ON_EXIT;
  }

  //
  // Received a NAK, end the session no matter what the user returns
  //
  Status = EFI_DEVICE_ERROR;

  if (Para->DhcpType == DHCP_MSG_NAK) {
    DhcpCallUser (DhcpSb, Dhcp4RcvdNak, Packet, NULL);
    goto ON_EXIT;
  }

  //
  // Check whether the ACK matches the selected offer
  //
  Message = NULL;

  if (!EFI_IP4_EQUAL (&Head->YourAddr, &Selected->YourAddr)) {
    Message = (UINT8 *)"Lease confirmed isn't the same as that in the offer";
    goto REJECT;
  }

  Status = DhcpCallUser (DhcpSb, Dhcp4RcvdAck, Packet, NULL);

  if (EFI_ERROR (Status)) {
    Message = (UINT8 *)"Lease is denied upon received ACK";
    goto REJECT;
  }

  //
  // Record the lease, transit to BOUND state, then notify the user
  //
  Status = DhcpLeaseAcquired (DhcpSb);

  if (EFI_ERROR (Status)) {
    Message = (UINT8 *)"Lease is denied upon entering bound";
    goto REJECT;
  }

  DhcpSb->IoStatus = EFI_SUCCESS;
  DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_COMPLETION);

  FreePool (Packet);
  return EFI_SUCCESS;

REJECT:
  DhcpSendMessage (DhcpSb, DhcpSb->Selected, DhcpSb->Para, DHCP_MSG_DECLINE, Message);

ON_EXIT:
  FreePool (Packet);
  return Status;
}

/**
  Handle packets in DHCP renew/rebound state.

  @param[in]  DhcpSb                The DHCP service instance
  @param[in]  Packet                The DHCP packet received
  @param[in]  Para                  The DHCP parameter extracted from the packet. That
                                    is, all the option value that we care.

  @retval EFI_SUCCESS           The packet is successfully processed.
  @retval Others                Some error occurred.

**/
EFI_STATUS
DhcpHandleRenewRebind (
  IN DHCP_SERVICE      *DhcpSb,
  IN EFI_DHCP4_PACKET  *Packet,
  IN DHCP_PARAMETER    *Para
  )
{
  EFI_DHCP4_HEADER  *Head;
  EFI_DHCP4_HEADER  *Selected;
  EFI_STATUS        Status;

  ASSERT (!DHCP_IS_BOOTP (DhcpSb->Para));

  Head     = &Packet->Dhcp4.Header;
  Selected = &DhcpSb->Selected->Dhcp4.Header;

  //
  // Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK
  //
  if (DHCP_IS_BOOTP (Para) ||
      (Para->ServerId != DhcpSb->Para->ServerId) ||
      ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))
      )
  {
    Status = EFI_SUCCESS;
    goto ON_EXIT;
  }

  //
  // Received a NAK, ignore the user's return then terminate the process
  //
  Status = EFI_DEVICE_ERROR;

  if (Para->DhcpType == DHCP_MSG_NAK) {
    DhcpCallUser (DhcpSb, Dhcp4RcvdNak, Packet, NULL);
    goto ON_EXIT;
  }

  //
  // The lease is different from the selected. Don't send a DECLINE
  // since it isn't existed in the client's FSM.
  //
  if (!EFI_IP4_EQUAL (&Head->YourAddr, &Selected->YourAddr)) {
    goto ON_EXIT;
  }

  Status = DhcpCallUser (DhcpSb, Dhcp4RcvdAck, Packet, NULL);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Record the lease, start timer for T1 and T2,
  //
  DhcpComputeLease (DhcpSb, Para);
  DhcpSb->LeaseLife = 0;
  DhcpSetState (DhcpSb, Dhcp4Bound, TRUE);

  if (DhcpSb->ExtraRefresh != 0) {
    DhcpSb->ExtraRefresh = FALSE;

    DhcpSb->IoStatus = EFI_SUCCESS;
    DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_RENEWREBIND);
  }

ON_EXIT:
  FreePool (Packet);
  return Status;
}

/**
  Handle packets in DHCP reboot state.

  @param[in]  DhcpSb                The DHCP service instance
  @param[in]  Packet                The DHCP packet received
  @param[in]  Para                  The DHCP parameter extracted from the packet. That
                                    is, all the option value that we care.

  @retval EFI_SUCCESS           The packet is successfully processed.
  @retval Others                Some error occurred.

**/
EFI_STATUS
DhcpHandleReboot (
  IN DHCP_SERVICE      *DhcpSb,
  IN EFI_DHCP4_PACKET  *Packet,
  IN DHCP_PARAMETER    *Para
  )
{
  EFI_DHCP4_HEADER  *Head;
  EFI_STATUS        Status;

  Head = &Packet->Dhcp4.Header;

  //
  // Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK
  //
  if (DHCP_IS_BOOTP (Para) ||
      ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))
      )
  {
    Status = EFI_SUCCESS;
    goto ON_EXIT;
  }

  //
  // If a NAK is received, transit to INIT and try again.
  //
  if (Para->DhcpType == DHCP_MSG_NAK) {
    DhcpCallUser (DhcpSb, Dhcp4RcvdNak, Packet, NULL);

    DhcpSb->ClientAddr = 0;
    DhcpSb->DhcpState  = Dhcp4Init;

    Status = DhcpInitRequest (DhcpSb);
    goto ON_EXIT;
  }

  //
  // Check whether the ACK matches the selected offer
  //
  if (EFI_NTOHL (Head->YourAddr) != DhcpSb->ClientAddr) {
    Status = EFI_DEVICE_ERROR;
    goto ON_EXIT;
  }

  Status = DhcpCallUser (DhcpSb, Dhcp4RcvdAck, Packet, NULL);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // OK, get the parameter from server, record the lease
  //
  DhcpSb->Para = AllocateCopyPool (sizeof (DHCP_PARAMETER), Para);
  if (DhcpSb->Para == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  DhcpSb->Selected = Packet;
  Status           = DhcpLeaseAcquired (DhcpSb);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  DhcpSb->IoStatus = EFI_SUCCESS;
  DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_COMPLETION);
  return EFI_SUCCESS;

ON_EXIT:
  FreePool (Packet);
  return Status;
}

/**
  Handle the received DHCP packets. This function drives the DHCP
  state machine.

  @param  UdpPacket             The UDP packets received.
  @param  EndPoint              The local/remote UDP access point
  @param  IoStatus              The status of the UDP receive
  @param  Context               The opaque parameter to the function.

**/
VOID
EFIAPI
DhcpInput (
  NET_BUF        *UdpPacket,
  UDP_END_POINT  *EndPoint,
  EFI_STATUS     IoStatus,
  VOID           *Context
  )
{
  DHCP_SERVICE      *DhcpSb;
  EFI_DHCP4_HEADER  *Head;
  EFI_DHCP4_PACKET  *Packet;
  DHCP_PARAMETER    *Para;
  EFI_STATUS        Status;
  UINT32            Len;

  Packet = NULL;
  DhcpSb = (DHCP_SERVICE *)Context;

  //
  // Don't restart receive if error occurs or DHCP is destroyed.
  //
  if (EFI_ERROR (IoStatus)) {
    return;
  } else if (DhcpSb->ServiceState == DHCP_DESTROY) {
    NetbufFree (UdpPacket);
    return;
  }

  ASSERT (UdpPacket != NULL);

  if (DhcpSb->DhcpState == Dhcp4Stopped) {
    goto RESTART;
  }

  //
  // Validate the packet received
  //
  if (UdpPacket->TotalSize < sizeof (EFI_DHCP4_HEADER)) {
    goto RESTART;
  }

  //
  // Copy the DHCP message to a continuous memory block
  //
  Len    = sizeof (EFI_DHCP4_PACKET) + UdpPacket->TotalSize - sizeof (EFI_DHCP4_HEADER);
  Packet = (EFI_DHCP4_PACKET *)AllocatePool (Len);

  if (Packet == NULL) {
    goto RESTART;
  }

  Packet->Size   = Len;
  Head           = &Packet->Dhcp4.Header;
  Packet->Length = NetbufCopy (UdpPacket, 0, UdpPacket->TotalSize, (UINT8 *)Head);

  if (Packet->Length != UdpPacket->TotalSize) {
    goto RESTART;
  }

  //
  // Is this packet the answer to our packet?
  //
  if ((Head->OpCode != BOOTP_REPLY) ||
      (NTOHL (Head->Xid) != DhcpSb->Xid) ||
      (CompareMem (DhcpSb->ClientAddressSendOut, Head->ClientHwAddr, Head->HwAddrLen) != 0))
  {
    goto RESTART;
  }

  //
  // Validate the options and retrieve the interested options
  //
  Para = NULL;
  if ((Packet->Length > sizeof (EFI_DHCP4_HEADER) + sizeof (UINT32)) &&
      (Packet->Dhcp4.Magik == DHCP_OPTION_MAGIC) &&
      EFI_ERROR (DhcpValidateOptions (Packet, &Para)))
  {
    goto RESTART;
  }

  //
  // Call the handler for each state. The handler should return
  // EFI_SUCCESS if the process can go on no matter whether the
  // packet is ignored or not. If the return is EFI_ERROR, the
  // session will be terminated. Packet's ownership is handled
  // over to the handlers. If operation succeeds, the handler
  // must notify the user. It isn't necessary to do if EFI_ERROR
  // is returned because the DhcpEndSession will notify the user.
  //
  Status = EFI_SUCCESS;

  switch (DhcpSb->DhcpState) {
    case Dhcp4Selecting:
      Status = DhcpHandleSelect (DhcpSb, Packet, Para);
      break;

    case Dhcp4Requesting:
      Status = DhcpHandleRequest (DhcpSb, Packet, Para);
      break;

    case Dhcp4InitReboot:
    case Dhcp4Init:
    case Dhcp4Bound:
      //
      // Ignore the packet in INITREBOOT, INIT and BOUND states
      //
      FreePool (Packet);
      Status = EFI_SUCCESS;
      break;

    case Dhcp4Renewing:
    case Dhcp4Rebinding:
      Status = DhcpHandleRenewRebind (DhcpSb, Packet, Para);
      break;

    case Dhcp4Rebooting:
      Status = DhcpHandleReboot (DhcpSb, Packet, Para);
      break;
  }

  if (Para != NULL) {
    FreePool (Para);
  }

  Packet = NULL;

  if (EFI_ERROR (Status)) {
    NetbufFree (UdpPacket);
    UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);
    DhcpEndSession (DhcpSb, Status);
    return;
  }

RESTART:
  NetbufFree (UdpPacket);

  if (Packet != NULL) {
    FreePool (Packet);
  }

  Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);

  if (EFI_ERROR (Status)) {
    DhcpEndSession (DhcpSb, EFI_DEVICE_ERROR);
  }
}

/**
  Release the net buffer when packet is sent.

  @param  UdpPacket             The UDP packets received.
  @param  EndPoint              The local/remote UDP access point
  @param  IoStatus              The status of the UDP receive
  @param  Context               The opaque parameter to the function.

**/
VOID
EFIAPI
DhcpOnPacketSent (
  NET_BUF        *Packet,
  UDP_END_POINT  *EndPoint,
  EFI_STATUS     IoStatus,
  VOID           *Context
  )
{
  NetbufFree (Packet);
}

/**
  Build and transmit a DHCP message according to the current states.
  This function implement the Table 5. of RFC 2131. Always transits
  the state (as defined in Figure 5. of the same RFC) before sending
  a DHCP message. The table is adjusted accordingly.

  @param[in]  DhcpSb                The DHCP service instance
  @param[in]  Seed                  The seed packet which the new packet is based on
  @param[in]  Para                  The DHCP parameter of the Seed packet
  @param[in]  Type                  The message type to send
  @param[in]  Msg                   The human readable message to include in the packet
                                    sent.

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resources for the packet
  @retval EFI_ACCESS_DENIED     Failed to transmit the packet through UDP
  @retval EFI_SUCCESS           The message is sent
  @retval other                 Other error occurs

**/
EFI_STATUS
DhcpSendMessage (
  IN DHCP_SERVICE      *DhcpSb,
  IN EFI_DHCP4_PACKET  *Seed,
  IN DHCP_PARAMETER    *Para,
  IN UINT8             Type,
  IN UINT8             *Msg
  )
{
  EFI_DHCP4_CONFIG_DATA  *Config;
  EFI_DHCP4_PACKET       *Packet;
  EFI_DHCP4_PACKET       *NewPacket;
  EFI_DHCP4_HEADER       *Head;
  EFI_DHCP4_HEADER       *SeedHead;
  UDP_IO                 *UdpIo;
  UDP_END_POINT          EndPoint;
  NET_BUF                *Wrap;
  NET_FRAGMENT           Frag;
  EFI_STATUS             Status;
  IP4_ADDR               IpAddr;
  UINT8                  *Buf;
  UINT16                 MaxMsg;
  UINT32                 Len;
  UINT32                 Index;

  //
  // Allocate a big enough memory block to hold the DHCP packet
  //
  Len = sizeof (EFI_DHCP4_PACKET) + 128 + DhcpSb->UserOptionLen;

  if (Msg != NULL) {
    Len += (UINT32)AsciiStrLen ((CHAR8 *)Msg);
  }

  Packet = AllocatePool (Len);

  if (Packet == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet->Size   = Len;
  Packet->Length = sizeof (EFI_DHCP4_HEADER) + sizeof (UINT32);

  //
  // Fill in the DHCP header fields
  //
  Config   = &DhcpSb->ActiveConfig;
  SeedHead = NULL;

  if (Seed != NULL) {
    SeedHead = &Seed->Dhcp4.Header;
  }

  Head = &Packet->Dhcp4.Header;
  ZeroMem (Head, sizeof (EFI_DHCP4_HEADER));

  Head->OpCode    = BOOTP_REQUEST;
  Head->HwType    = DhcpSb->HwType;
  Head->HwAddrLen = DhcpSb->HwLen;
  Head->Xid       = HTONL (DhcpSb->Xid);
  Head->Reserved  = HTONS (0x8000);     // Server, broadcast the message please.

  EFI_IP4 (Head->ClientAddr) = HTONL (DhcpSb->ClientAddr);
  CopyMem (Head->ClientHwAddr, DhcpSb->Mac.Addr, DhcpSb->HwLen);

  if ((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) {
    Head->Seconds = 0;
  } else if ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting)) {
    //
    // Use the same value as the original DHCPDISCOVER message.
    //
    Head->Seconds = DhcpSb->LastPacket->Dhcp4.Header.Seconds;
  } else {
    SetElapsedTime (&Head->Seconds, DhcpSb->ActiveChild);
  }

  //
  // Append the DHCP message type
  //
  Packet->Dhcp4.Magik = DHCP_OPTION_MAGIC;
  Buf                 = Packet->Dhcp4.Option;
  Buf                 = DhcpAppendOption (Buf, DHCP4_TAG_MSG_TYPE, 1, &Type);

  //
  // Append the serverid option if necessary:
  //   1. DHCP decline message
  //   2. DHCP release message
  //   3. DHCP request to confirm one lease.
  //
  if ((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE) ||
      ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting))
      )
  {
    ASSERT ((Para != NULL) && (Para->ServerId != 0));

    IpAddr = HTONL (Para->ServerId);
    Buf    = DhcpAppendOption (Buf, DHCP4_TAG_SERVER_ID, 4, (UINT8 *)&IpAddr);
  }

  //
  // Append the requested IP option if necessary:
  //   1. DHCP request to use the previously allocated address
  //   2. DHCP request to confirm one lease
  //   3. DHCP decline to decline one lease
  //
  IpAddr = 0;

  if (Type == DHCP_MSG_REQUEST) {
    if (DhcpSb->DhcpState == Dhcp4Rebooting) {
      IpAddr = EFI_IP4 (Config->ClientAddress);
    } else if (DhcpSb->DhcpState == Dhcp4Requesting) {
      ASSERT (SeedHead != NULL);
      IpAddr = EFI_IP4 (SeedHead->YourAddr);
    }
  } else if (Type == DHCP_MSG_DECLINE) {
    ASSERT (SeedHead != NULL);
    IpAddr = EFI_IP4 (SeedHead->YourAddr);
  }

  if (IpAddr != 0) {
    Buf = DhcpAppendOption (Buf, DHCP4_TAG_REQUEST_IP, 4, (UINT8 *)&IpAddr);
  }

  //
  // Append the Max Message Length option if it isn't a DECLINE
  // or RELEASE to direct the server use large messages instead of
  // override the BOOTFILE and SERVER fields in the message head.
  //
  if ((Type != DHCP_MSG_DECLINE) && (Type != DHCP_MSG_RELEASE)) {
    MaxMsg = HTONS (0xFF00);
    Buf    = DhcpAppendOption (Buf, DHCP4_TAG_MAXMSG, 2, (UINT8 *)&MaxMsg);
  }

  //
  // Append the user's message if it isn't NULL
  //
  if (Msg != NULL) {
    Len = MIN ((UINT32)AsciiStrLen ((CHAR8 *)Msg), 255);
    Buf = DhcpAppendOption (Buf, DHCP4_TAG_MESSAGE, (UINT16)Len, Msg);
  }

  //
  // Append the user configured options
  //
  if (DhcpSb->UserOptionLen != 0) {
    for (Index = 0; Index < Config->OptionCount; Index++) {
      //
      // We can't use any option other than the client ID from user
      // if it is a DHCP decline or DHCP release .
      //
      if (((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) &&
          (Config->OptionList[Index]->OpCode != DHCP4_TAG_CLIENT_ID))
      {
        continue;
      }

      Buf = DhcpAppendOption (
              Buf,
              Config->OptionList[Index]->OpCode,
              Config->OptionList[Index]->Length,
              Config->OptionList[Index]->Data
              );
    }
  }

  *(Buf++)        = DHCP4_TAG_EOP;
  Packet->Length += (UINT32)(Buf - Packet->Dhcp4.Option);

  //
  // OK, the message is built, call the user to override it.
  //
  Status    = EFI_SUCCESS;
  NewPacket = NULL;

  if (Type == DHCP_MSG_DISCOVER) {
    Status = DhcpCallUser (DhcpSb, Dhcp4SendDiscover, Packet, &NewPacket);
  } else if (Type == DHCP_MSG_REQUEST) {
    Status = DhcpCallUser (DhcpSb, Dhcp4SendRequest, Packet, &NewPacket);
  } else if (Type == DHCP_MSG_DECLINE) {
    Status = DhcpCallUser (DhcpSb, Dhcp4SendDecline, Packet, &NewPacket);
  }

  if (EFI_ERROR (Status)) {
    FreePool (Packet);
    return Status;
  }

  if (NewPacket != NULL) {
    FreePool (Packet);
    Packet = NewPacket;
  }

  //
  // Save the Client Address will be sent out
  //
  CopyMem (
    &DhcpSb->ClientAddressSendOut[0],
    &Packet->Dhcp4.Header.ClientHwAddr[0],
    Packet->Dhcp4.Header.HwAddrLen
    );

  //
  // Wrap it into a netbuf then send it.
  //
  Frag.Bulk = (UINT8 *)&Packet->Dhcp4.Header;
  Frag.Len  = Packet->Length;
  Wrap      = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL);

  if (Wrap == NULL) {
    FreePool (Packet);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Save it as the last sent packet for retransmission
  //
  if (DhcpSb->LastPacket != NULL) {
    FreePool (DhcpSb->LastPacket);
  }

  DhcpSb->LastPacket = Packet;
  DhcpSetTransmitTimer (DhcpSb);

  //
  // Broadcast the message, unless we know the server address.
  // Use the lease UdpIo port to send the unicast packet.
  //
  EndPoint.RemoteAddr.Addr[0] = 0xffffffff;
  EndPoint.LocalAddr.Addr[0]  = 0;
  EndPoint.RemotePort         = DHCP_SERVER_PORT;
  EndPoint.LocalPort          = DHCP_CLIENT_PORT;
  UdpIo                       = DhcpSb->UdpIo;

  if ((DhcpSb->DhcpState == Dhcp4Renewing) || (Type == DHCP_MSG_RELEASE)) {
    EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr;
    EndPoint.LocalAddr.Addr[0]  = DhcpSb->ClientAddr;
    UdpIo                       = DhcpSb->LeaseIoPort;
  }

  ASSERT (UdpIo != NULL);

  Status = UdpIoSendDatagram (
             UdpIo,
             Wrap,
             &EndPoint,
             NULL,
             DhcpOnPacketSent,
             DhcpSb
             );

  if (EFI_ERROR (Status)) {
    NetbufFree (Wrap);
    return EFI_ACCESS_DENIED;
  }

  return EFI_SUCCESS;
}

/**
  Retransmit a saved packet. Only DISCOVER and REQUEST messages
  will be retransmitted.

  @param[in]  DhcpSb                The DHCP service instance

  @retval EFI_ACCESS_DENIED     Failed to transmit packet through UDP port
  @retval EFI_SUCCESS           The packet is retransmitted.

**/
EFI_STATUS
DhcpRetransmit (
  IN DHCP_SERVICE  *DhcpSb
  )
{
  UDP_IO         *UdpIo;
  UDP_END_POINT  EndPoint;
  NET_BUF        *Wrap;
  NET_FRAGMENT   Frag;
  EFI_STATUS     Status;

  ASSERT (DhcpSb->LastPacket != NULL);

  //
  // For REQUEST message in Dhcp4Requesting state, do not change the secs fields.
  //
  if (DhcpSb->DhcpState != Dhcp4Requesting) {
    SetElapsedTime (&DhcpSb->LastPacket->Dhcp4.Header.Seconds, DhcpSb->ActiveChild);
  }

  //
  // Wrap it into a netbuf then send it.
  //
  Frag.Bulk = (UINT8 *)&DhcpSb->LastPacket->Dhcp4.Header;
  Frag.Len  = DhcpSb->LastPacket->Length;
  Wrap      = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL);

  if (Wrap == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Broadcast the message, unless we know the server address.
  //
  EndPoint.RemotePort         = DHCP_SERVER_PORT;
  EndPoint.LocalPort          = DHCP_CLIENT_PORT;
  EndPoint.RemoteAddr.Addr[0] = 0xffffffff;
  EndPoint.LocalAddr.Addr[0]  = 0;
  UdpIo                       = DhcpSb->UdpIo;

  if (DhcpSb->DhcpState == Dhcp4Renewing) {
    EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr;
    EndPoint.LocalAddr.Addr[0]  = DhcpSb->ClientAddr;
    UdpIo                       = DhcpSb->LeaseIoPort;
  }

  ASSERT (UdpIo != NULL);

  Status = UdpIoSendDatagram (
             UdpIo,
             Wrap,
             &EndPoint,
             NULL,
             DhcpOnPacketSent,
             DhcpSb
             );

  if (EFI_ERROR (Status)) {
    NetbufFree (Wrap);
    return EFI_ACCESS_DENIED;
  }

  return EFI_SUCCESS;
}

/**
  Each DHCP service has three timer. Two of them are count down timer.
  One for the packet retransmission. The other is to collect the offers.
  The third timer increments the lease life which is compared to T1, T2,
  and lease to determine the time to renew and rebind the lease.
  DhcpOnTimerTick will be called once every second.

  @param[in]  Event                 The timer event
  @param[in]  Context               The context, which is the DHCP service instance.

**/
VOID
EFIAPI
DhcpOnTimerTick (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  LIST_ENTRY     *Entry;
  LIST_ENTRY     *Next;
  DHCP_SERVICE   *DhcpSb;
  DHCP_PROTOCOL  *Instance;
  EFI_STATUS     Status;

  DhcpSb   = (DHCP_SERVICE *)Context;
  Instance = DhcpSb->ActiveChild;

  //
  // 0xffff is the maximum supported value for elapsed time according to RFC.
  //
  if ((Instance != NULL) && (Instance->ElaspedTime < 0xffff)) {
    Instance->ElaspedTime++;
  }

  //
  // Check the retransmit timer
  //
  if ((DhcpSb->PacketToLive > 0) && (--DhcpSb->PacketToLive == 0)) {
    //
    // Select offer at each timeout if any offer received.
    //
    if ((DhcpSb->DhcpState == Dhcp4Selecting) && (DhcpSb->LastOffer != NULL)) {
      Status = DhcpChooseOffer (DhcpSb);

      if (EFI_ERROR (Status)) {
        if (DhcpSb->LastOffer != NULL) {
          FreePool (DhcpSb->LastOffer);
          DhcpSb->LastOffer = NULL;
        }
      } else {
        goto ON_EXIT;
      }
    }

    if (++DhcpSb->CurRetry < DhcpSb->MaxRetries) {
      //
      // Still has another try
      //
      DhcpRetransmit (DhcpSb);
      DhcpSetTransmitTimer (DhcpSb);
    } else if (DHCP_CONNECTED (DhcpSb->DhcpState)) {
      //
      // Retransmission failed, if the DHCP request is initiated by
      // user, adjust the current state according to the lease life.
      // Otherwise do nothing to wait the lease to timeout
      //
      if (DhcpSb->ExtraRefresh != 0) {
        Status = EFI_SUCCESS;

        if (DhcpSb->LeaseLife < DhcpSb->T1) {
          Status = DhcpSetState (DhcpSb, Dhcp4Bound, FALSE);
        } else if (DhcpSb->LeaseLife < DhcpSb->T2) {
          Status = DhcpSetState (DhcpSb, Dhcp4Renewing, FALSE);
        } else if (DhcpSb->LeaseLife < DhcpSb->Lease) {
          Status = DhcpSetState (DhcpSb, Dhcp4Rebinding, FALSE);
        } else {
          goto END_SESSION;
        }

        DhcpSb->IoStatus = EFI_TIMEOUT;
        DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_RENEWREBIND);
      }
    } else {
      goto END_SESSION;
    }
  }

  //
  // If an address has been acquired, check whether need to
  // refresh or whether it has expired.
  //
  if (DHCP_CONNECTED (DhcpSb->DhcpState)) {
    DhcpSb->LeaseLife++;

    //
    // Don't timeout the lease, only count the life if user is
    // requesting extra renew/rebind. Adjust the state after that.
    //
    if (DhcpSb->ExtraRefresh != 0) {
      return;
    }

    if (DhcpSb->LeaseLife == DhcpSb->Lease) {
      //
      // Lease expires, end the session
      //
      goto END_SESSION;
    } else if (DhcpSb->LeaseLife == DhcpSb->T2) {
      //
      // T2 expires, transit to rebinding then send a REQUEST to any server
      //
      if (EFI_ERROR (DhcpSetState (DhcpSb, Dhcp4Rebinding, TRUE))) {
        goto END_SESSION;
      }

      if (Instance != NULL) {
        Instance->ElaspedTime = 0;
      }

      Status = DhcpSendMessage (
                 DhcpSb,
                 DhcpSb->Selected,
                 DhcpSb->Para,
                 DHCP_MSG_REQUEST,
                 NULL
                 );

      if (EFI_ERROR (Status)) {
        goto END_SESSION;
      }
    } else if (DhcpSb->LeaseLife == DhcpSb->T1) {
      //
      // T1 expires, transit to renewing, then send a REQUEST to the server
      //
      if (EFI_ERROR (DhcpSetState (DhcpSb, Dhcp4Renewing, TRUE))) {
        goto END_SESSION;
      }

      if (Instance != NULL) {
        Instance->ElaspedTime = 0;
      }

      Status = DhcpSendMessage (
                 DhcpSb,
                 DhcpSb->Selected,
                 DhcpSb->Para,
                 DHCP_MSG_REQUEST,
                 NULL
                 );

      if (EFI_ERROR (Status)) {
        goto END_SESSION;
      }
    }
  }

ON_EXIT:
  //
  // Iterate through all the DhcpSb Children.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &DhcpSb->Children) {
    Instance = NET_LIST_USER_STRUCT (Entry, DHCP_PROTOCOL, Link);
    Instance->Timeout--;
    if ((Instance->Timeout == 0) && (Instance->Token != NULL)) {
      PxeDhcpDone (Instance);
    }
  }

  return;

END_SESSION:
  DhcpEndSession (DhcpSb, EFI_TIMEOUT);

  return;
}
