]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Dhcp4Dxe / Dhcp4Io.c
index d021d1c02e1d0d06d37209c08ea37eb27dcbab01..4728b94c5803110d05bb2209032ef28643183841 100644 (file)
@@ -1,22 +1,8 @@
 /** @file\r
+  EFI DHCP protocol implementation.\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
-  Dhcp4Io.c\r
-\r
-Abstract:\r
-\r
-  EFI DHCP protocol implementation\r
-\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -30,9 +16,10 @@ UINT32  mDhcp4DefaultTimeout[4] = { 4, 8, 16, 32 };
   Send an initial DISCOVER or REQUEST message according to the\r
   DHCP service's current state.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
+  @param[in]  DhcpSb                The DHCP service instance\r
 \r
   @retval EFI_SUCCESS           The request has been sent\r
+  @retval other                 Some error occurs when sending the request.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -44,6 +31,11 @@ DhcpInitRequest (
 \r
   ASSERT ((DhcpSb->DhcpState == Dhcp4Init) || (DhcpSb->DhcpState == Dhcp4InitReboot));\r
 \r
+  //\r
+  // Clear initial time to make sure that elapsed-time is set to 0 for first Discover or REQUEST message.\r
+  //\r
+  DhcpSb->ActiveChild->ElaspedTime= 0;\r
+\r
   if (DhcpSb->DhcpState == Dhcp4Init) {\r
     DhcpSetState (DhcpSb, Dhcp4Selecting, FALSE);\r
     Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_DISCOVER, NULL);\r
@@ -72,17 +64,16 @@ DhcpInitRequest (
   proper return value is selected to let the caller continue the\r
   normal process.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
-  @param  Event                 The event as defined in the spec\r
-  @param  Packet                The current packet trigger the event\r
-  @param  NewPacket             The user's return new packet\r
+  @param[in]  DhcpSb                The DHCP service instance\r
+  @param[in]  Event                 The event as defined in the spec\r
+  @param[in]  Packet                The current packet trigger the event\r
+  @param[out] NewPacket             The user's return new packet\r
 \r
   @retval EFI_NOT_READY         Direct the caller to continue collecting the offer.\r
   @retval EFI_SUCCESS           The user function returns success.\r
   @retval EFI_ABORTED           The user function ask it to abort.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 DhcpCallUser (\r
   IN  DHCP_SERVICE          *DhcpSb,\r
@@ -141,9 +132,7 @@ DhcpCallUser (
   Notify the user about the operation result.\r
 \r
   @param  DhcpSb                DHCP service instance\r
-  @param  Which                 which notify function to signal\r
-\r
-  @return None\r
+  @param  Which                 Which notify function to signal\r
 \r
 **/\r
 VOID\r
@@ -159,14 +148,16 @@ DhcpNotifyUser (
   }\r
 \r
   if ((Child->CompletionEvent != NULL) &&\r
-     ((Which == DHCP_NOTIFY_COMPLETION) || (Which == DHCP_NOTIFY_ALL))) {\r
+      ((Which == DHCP_NOTIFY_COMPLETION) || (Which == DHCP_NOTIFY_ALL))\r
+      ) {\r
 \r
     gBS->SignalEvent (Child->CompletionEvent);\r
     Child->CompletionEvent = NULL;\r
   }\r
 \r
   if ((Child->RenewRebindEvent != NULL) &&\r
-     ((Which == DHCP_NOTIFY_RENEWREBIND) || (Which == DHCP_NOTIFY_ALL))) {\r
+      ((Which == DHCP_NOTIFY_RENEWREBIND) || (Which == DHCP_NOTIFY_ALL))\r
+      ) {\r
 \r
     gBS->SignalEvent (Child->RenewRebindEvent);\r
     Child->RenewRebindEvent = NULL;\r
@@ -192,9 +183,9 @@ DhcpNotifyUser (
 **/\r
 EFI_STATUS\r
 DhcpSetState (\r
-  IN DHCP_SERVICE           *DhcpSb,\r
-  IN INTN                   State,\r
-  IN BOOLEAN                CallUser\r
+  IN OUT DHCP_SERVICE           *DhcpSb,\r
+  IN     INTN                   State,\r
+  IN     BOOLEAN                CallUser\r
   )\r
 {\r
   EFI_STATUS                Status;\r
@@ -235,7 +226,7 @@ DhcpSetState (
 \r
   DhcpSb->CurRetry      = 0;\r
   DhcpSb->PacketToLive  = 0;\r
-\r
+  DhcpSb->LastTimeout   = 0;\r
   DhcpSb->DhcpState     = State;\r
   return EFI_SUCCESS;\r
 }\r
@@ -247,13 +238,10 @@ DhcpSetState (
 \r
   @param  DhcpSb                The DHCP service instance.\r
 \r
-  @return None\r
-\r
 **/\r
-STATIC\r
 VOID\r
 DhcpSetTransmitTimer (\r
-  IN DHCP_SERVICE           *DhcpSb\r
+  IN OUT DHCP_SERVICE           *DhcpSb\r
   )\r
 {\r
   UINT32                    *Times;\r
@@ -271,10 +259,9 @@ DhcpSetTransmitTimer (
   }\r
 \r
   DhcpSb->PacketToLive = Times[DhcpSb->CurRetry];\r
+  DhcpSb->LastTimeout  = DhcpSb->PacketToLive;\r
 \r
-  if (DhcpSb->DhcpState == Dhcp4Selecting) {\r
-    DhcpSb->WaitOffer = DhcpSb->PacketToLive;\r
-  }\r
+  return;\r
 }\r
 \r
 /**\r
@@ -285,15 +272,11 @@ DhcpSetTransmitTimer (
   @param  DhcpSb                The DHCP service instance\r
   @param  Para                  The DHCP parameter extracted from the server's\r
                                 response.\r
-\r
-  @return None\r
-\r
 **/\r
-STATIC\r
 VOID\r
 DhcpComputeLease (\r
-  IN DHCP_SERVICE           *DhcpSb,\r
-  IN DHCP_PARAMETER         *Para\r
+  IN OUT DHCP_SERVICE           *DhcpSb,\r
+  IN     DHCP_PARAMETER         *Para\r
   )\r
 {\r
   ASSERT (Para != NULL);\r
@@ -321,16 +304,17 @@ DhcpComputeLease (
   DHCP driver needs this port to unicast packet to the server\r
   such as DHCP release.\r
 \r
-  @param  UdpIo                 The UDP IO port to configure\r
-  @param  Context               The opaque parameter to the function.\r
+  @param[in]  UdpIo                 The UDP IO to configure\r
+  @param[in]  Context               Dhcp service instance.\r
 \r
   @retval EFI_SUCCESS           The UDP IO port is successfully configured.\r
   @retval Others                It failed to configure the port.\r
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 DhcpConfigLeaseIoPort (\r
-  IN UDP_IO_PORT            *UdpIo,\r
+  IN UDP_IO                 *UdpIo,\r
   IN VOID                   *Context\r
   )\r
 {\r
@@ -358,14 +342,14 @@ DhcpConfigLeaseIoPort (
   UdpConfigData.RemotePort          = DHCP_SERVER_PORT;\r
 \r
   Ip = HTONL (DhcpSb->ClientAddr);\r
-  NetCopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
 \r
   Ip = HTONL (DhcpSb->Netmask);\r
-  NetCopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+  CopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-  NetZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));\r
+  ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-  Status = UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfigData);\r
+  Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData);\r
 \r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -375,12 +359,12 @@ DhcpConfigLeaseIoPort (
   // Add a default route if received from the server.\r
   //\r
   if ((DhcpSb->Para != NULL) && (DhcpSb->Para->Router != 0)) {\r
-    NetZeroMem (&Subnet, sizeof (EFI_IPv4_ADDRESS));\r
+    ZeroMem (&Subnet, sizeof (EFI_IPv4_ADDRESS));\r
 \r
     Ip = HTONL (DhcpSb->Para->Router);\r
-    NetCopyMem (&Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+    CopyMem (&Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-    UdpIo->Udp->Routes (UdpIo->Udp, FALSE, &Subnet, &Subnet, &Gateway);\r
+    UdpIo->Protocol.Udp4->Routes (UdpIo->Protocol.Udp4, FALSE, &Subnet, &Subnet, &Gateway);\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -398,14 +382,11 @@ DhcpConfigLeaseIoPort (
   @retval EFI_SUCCESS           The lease is recorded.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 DhcpLeaseAcquired (\r
-  IN DHCP_SERVICE           *DhcpSb\r
+  IN OUT DHCP_SERVICE           *DhcpSb\r
   )\r
 {\r
-  INTN                      Class;\r
-\r
   DhcpSb->ClientAddr = EFI_NTOHL (DhcpSb->Selected->Dhcp4.Header.YourAddr);\r
 \r
   if (DhcpSb->Para != NULL) {\r
@@ -414,12 +395,11 @@ DhcpLeaseAcquired (
   }\r
 \r
   if (DhcpSb->Netmask == 0) {\r
-    Class           = NetGetIpClass (DhcpSb->ClientAddr);\r
-    DhcpSb->Netmask = mIp4AllMasks[Class << 3];\r
+    return EFI_ABORTED;\r
   }\r
 \r
   if (DhcpSb->LeaseIoPort != NULL) {\r
-    UdpIoFreePort (DhcpSb->LeaseIoPort);\r
+    UdpIoFreeIo (DhcpSb->LeaseIoPort);\r
   }\r
 \r
   //\r
@@ -427,10 +407,11 @@ DhcpLeaseAcquired (
   // and transmit unicast packet with it as source address. Don't\r
   // start receive on this port, the queued packet will be timeout.\r
   //\r
-  DhcpSb->LeaseIoPort = UdpIoCreatePort (\r
+  DhcpSb->LeaseIoPort = UdpIoCreateIo (\r
                           DhcpSb->Controller,\r
                           DhcpSb->Image,\r
                           DhcpConfigLeaseIoPort,\r
+                          UDP_IO_UDP4_VERSION,\r
                           DhcpSb\r
                           );\r
 \r
@@ -451,8 +432,6 @@ DhcpLeaseAcquired (
 \r
   @param  DhcpSb                The DHCP instance service.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
 DhcpCleanLease (\r
@@ -462,20 +441,21 @@ DhcpCleanLease (
   DhcpSb->DhcpState   = Dhcp4Init;\r
   DhcpSb->Xid         = DhcpSb->Xid + 1;\r
   DhcpSb->ClientAddr  = 0;\r
+  DhcpSb->Netmask     = 0;\r
   DhcpSb->ServerAddr  = 0;\r
 \r
   if (DhcpSb->LastOffer != NULL) {\r
-    NetFreePool (DhcpSb->LastOffer);\r
+    FreePool (DhcpSb->LastOffer);\r
     DhcpSb->LastOffer = NULL;\r
   }\r
 \r
   if (DhcpSb->Selected != NULL) {\r
-    NetFreePool (DhcpSb->Selected);\r
+    FreePool (DhcpSb->Selected);\r
     DhcpSb->Selected = NULL;\r
   }\r
 \r
   if (DhcpSb->Para != NULL) {\r
-    NetFreePool (DhcpSb->Para);\r
+    FreePool (DhcpSb->Para);\r
     DhcpSb->Para = NULL;\r
   }\r
 \r
@@ -485,20 +465,25 @@ DhcpCleanLease (
   DhcpSb->ExtraRefresh  = FALSE;\r
 \r
   if (DhcpSb->LeaseIoPort != NULL) {\r
-    UdpIoFreePort (DhcpSb->LeaseIoPort);\r
+    UdpIoFreeIo (DhcpSb->LeaseIoPort);\r
     DhcpSb->LeaseIoPort = NULL;\r
   }\r
 \r
   if (DhcpSb->LastPacket != NULL) {\r
-    NetbufFree (DhcpSb->LastPacket);\r
+    FreePool (DhcpSb->LastPacket);\r
     DhcpSb->LastPacket = NULL;\r
   }\r
 \r
   DhcpSb->PacketToLive  = 0;\r
+  DhcpSb->LastTimeout   = 0;\r
   DhcpSb->CurRetry      = 0;\r
   DhcpSb->MaxRetries    = 0;\r
-  DhcpSb->WaitOffer     = 0;\r
   DhcpSb->LeaseLife     = 0;\r
+\r
+  //\r
+  // Clean active config data.\r
+  //\r
+  DhcpCleanConfigure (&DhcpSb->ActiveConfig);\r
 }\r
 \r
 \r
@@ -507,12 +492,11 @@ DhcpCleanLease (
   of BOOTP, the lease is recorded and user notified. If the offer is of\r
   DHCP, it will request the offer from the server.\r
 \r
-  @param  DhcpSb                The DHCP service instance.\r
+  @param[in]  DhcpSb                The DHCP service instance.\r
 \r
   @retval EFI_SUCCESS           One of the offer is selected.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 DhcpChooseOffer (\r
   IN DHCP_SERVICE           *DhcpSb\r
@@ -525,11 +509,6 @@ DhcpChooseOffer (
 \r
   ASSERT (DhcpSb->LastOffer != NULL);\r
 \r
-  //\r
-  // Stop waiting more offers\r
-  //\r
-  DhcpSb->WaitOffer = 0;\r
-\r
   //\r
   // User will cache previous offers if he wants to select\r
   // from multiple offers. If user provides an invalid packet,\r
@@ -545,10 +524,10 @@ DhcpChooseOffer (
   Selected = DhcpSb->LastOffer;\r
 \r
   if ((NewPacket != NULL) && !EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) {\r
-    TempPacket = (EFI_DHCP4_PACKET *) NetAllocatePool (NewPacket->Size);\r
+    TempPacket = (EFI_DHCP4_PACKET *) AllocatePool (NewPacket->Size);\r
     if (TempPacket != NULL) {\r
-      NetCopyMem (TempPacket, NewPacket, NewPacket->Size);\r
-      NetFreePool (Selected);\r
+      CopyMem (TempPacket, NewPacket, NewPacket->Size);\r
+      FreePool (Selected);\r
       Selected = TempPacket;\r
     }\r
   }\r
@@ -593,13 +572,10 @@ DhcpChooseOffer (
   to this is: only call DhcpEndSession at the highest level, such as\r
   DhcpInput, DhcpOnTimerTick...At the other level, just return error.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
-  @param  Status                The result of the DHCP process.\r
-\r
-  @return None\r
+  @param[in]  DhcpSb                The DHCP service instance\r
+  @param[in]  Status                The result of the DHCP process.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 DhcpEndSession (\r
   IN DHCP_SERVICE           *DhcpSb,\r
@@ -622,16 +598,15 @@ DhcpEndSession (
 /**\r
   Handle packets in DHCP select state.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
-  @param  Packet                The DHCP packet received\r
-  @param  Para                  The DHCP parameter extracted from the packet. That\r
-                                is, all the option value that we care.\r
+  @param[in]  DhcpSb                The DHCP service instance\r
+  @param[in]  Packet                The DHCP packet received\r
+  @param[in]  Para                  The DHCP parameter extracted from the packet. That\r
+                                    is, all the option value that we care.\r
 \r
   @retval EFI_SUCCESS           The packet is successfully processed.\r
   @retval Others                Some error occured.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 DhcpHandleSelect (\r
   IN DHCP_SERVICE           *DhcpSb,\r
@@ -650,7 +625,8 @@ DhcpHandleSelect (
   // Don't return a error for these two case otherwise the session is ended.\r
   //\r
   if (!DHCP_IS_BOOTP (Para) &&\r
-     ((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))) {\r
+      ((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))\r
+      ) {\r
     goto ON_EXIT;\r
   }\r
 \r
@@ -664,7 +640,7 @@ DhcpHandleSelect (
 \r
   if (Status == EFI_SUCCESS) {\r
     if (DhcpSb->LastOffer != NULL) {\r
-      NetFreePool (DhcpSb->LastOffer);\r
+      FreePool (DhcpSb->LastOffer);\r
     }\r
 \r
     DhcpSb->LastOffer = Packet;\r
@@ -673,7 +649,7 @@ DhcpHandleSelect (
 \r
   } else if (Status == EFI_NOT_READY) {\r
     if (DhcpSb->LastOffer != NULL) {\r
-      NetFreePool (DhcpSb->LastOffer);\r
+      FreePool (DhcpSb->LastOffer);\r
     }\r
 \r
     DhcpSb->LastOffer = Packet;\r
@@ -689,7 +665,7 @@ DhcpHandleSelect (
   return EFI_SUCCESS;\r
 \r
 ON_EXIT:\r
-  NetFreePool (Packet);\r
+  FreePool (Packet);\r
   return Status;\r
 }\r
 \r
@@ -697,16 +673,15 @@ ON_EXIT:
 /**\r
   Handle packets in DHCP request state.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
-  @param  Packet                The DHCP packet received\r
-  @param  Para                  The DHCP parameter extracted from the packet. That\r
-                                is, all the option value that we care.\r
+  @param[in]  DhcpSb                The DHCP service instance\r
+  @param[in]  Packet                The DHCP packet received\r
+  @param[in]  Para                  The DHCP parameter extracted from the packet. That\r
+                                    is, all the option value that we care.\r
 \r
   @retval EFI_SUCCESS           The packet is successfully processed.\r
   @retval Others                Some error occured.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 DhcpHandleRequest (\r
   IN DHCP_SERVICE           *DhcpSb,\r
@@ -728,8 +703,9 @@ DhcpHandleRequest (
   // Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK.\r
   //\r
   if (DHCP_IS_BOOTP (Para) ||\r
-     (Para->ServerId != DhcpSb->Para->ServerId) ||\r
-     ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))) {\r
+      (Para->ServerId != DhcpSb->Para->ServerId) ||\r
+      ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))\r
+      ) {\r
 \r
     Status = EFI_SUCCESS;\r
     goto ON_EXIT;\r
@@ -775,14 +751,14 @@ DhcpHandleRequest (
   DhcpSb->IoStatus = EFI_SUCCESS;\r
   DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_COMPLETION);\r
 \r
-  NetFreePool (Packet);\r
+  FreePool (Packet);\r
   return EFI_SUCCESS;\r
 \r
 REJECT:\r
   DhcpSendMessage (DhcpSb, DhcpSb->Selected, DhcpSb->Para, DHCP_MSG_DECLINE, Message);\r
 \r
 ON_EXIT:\r
-  NetFreePool (Packet);\r
+  FreePool (Packet);\r
   return Status;\r
 }\r
 \r
@@ -790,16 +766,15 @@ ON_EXIT:
 /**\r
   Handle packets in DHCP renew/rebound state.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
-  @param  Packet                The DHCP packet received\r
-  @param  Para                  The DHCP parameter extracted from the packet. That\r
-                                is, all the option value that we care.\r
+  @param[in]  DhcpSb                The DHCP service instance\r
+  @param[in]  Packet                The DHCP packet received\r
+  @param[in]  Para                  The DHCP parameter extracted from the packet. That\r
+                                    is, all the option value that we care.\r
 \r
   @retval EFI_SUCCESS           The packet is successfully processed.\r
   @retval Others                Some error occured.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 DhcpHandleRenewRebind (\r
   IN DHCP_SERVICE           *DhcpSb,\r
@@ -820,8 +795,9 @@ DhcpHandleRenewRebind (
   // Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK\r
   //\r
   if (DHCP_IS_BOOTP (Para) ||\r
-     (Para->ServerId != DhcpSb->Para->ServerId) ||\r
-     ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))) {\r
+      (Para->ServerId != DhcpSb->Para->ServerId) ||\r
+      ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))\r
+      ) {\r
 \r
     Status = EFI_SUCCESS;\r
     goto ON_EXIT;\r
@@ -858,7 +834,7 @@ DhcpHandleRenewRebind (
   DhcpSb->LeaseLife = 0;\r
   DhcpSetState (DhcpSb, Dhcp4Bound, TRUE);\r
 \r
-  if (DhcpSb->ExtraRefresh) {\r
+  if (DhcpSb->ExtraRefresh != 0) {\r
     DhcpSb->ExtraRefresh  = FALSE;\r
 \r
     DhcpSb->IoStatus      = EFI_SUCCESS;\r
@@ -866,7 +842,7 @@ DhcpHandleRenewRebind (
   }\r
 \r
 ON_EXIT:\r
-  NetFreePool (Packet);\r
+  FreePool (Packet);\r
   return Status;\r
 }\r
 \r
@@ -874,16 +850,15 @@ ON_EXIT:
 /**\r
   Handle packets in DHCP reboot state.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
-  @param  Packet                The DHCP packet received\r
-  @param  Para                  The DHCP parameter extracted from the packet. That\r
-                                is, all the option value that we care.\r
+  @param[in]  DhcpSb                The DHCP service instance\r
+  @param[in]  Packet                The DHCP packet received\r
+  @param[in]  Para                  The DHCP parameter extracted from the packet. That\r
+                                    is, all the option value that we care.\r
 \r
   @retval EFI_SUCCESS           The packet is successfully processed.\r
   @retval Others                Some error occured.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 DhcpHandleReboot (\r
   IN DHCP_SERVICE           *DhcpSb,\r
@@ -900,7 +875,8 @@ DhcpHandleReboot (
   // Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK\r
   //\r
   if (DHCP_IS_BOOTP (Para) ||\r
-     ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))) {\r
+      ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))\r
+      ) {\r
 \r
     Status = EFI_SUCCESS;\r
     goto ON_EXIT;\r
@@ -935,18 +911,14 @@ DhcpHandleReboot (
   //\r
   // OK, get the parameter from server, record the lease\r
   //\r
-  DhcpSb->Para = NetAllocatePool (sizeof (DHCP_PARAMETER));\r
-\r
+  DhcpSb->Para = AllocateCopyPool (sizeof (DHCP_PARAMETER), Para);\r
   if (DhcpSb->Para == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
   }\r
 \r
   DhcpSb->Selected  = Packet;\r
-  CopyMem (DhcpSb->Para, Para, sizeof (*DhcpSb->Para));\r
-\r
   Status            = DhcpLeaseAcquired (DhcpSb);\r
-\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -956,27 +928,26 @@ DhcpHandleReboot (
   return EFI_SUCCESS;\r
 \r
 ON_EXIT:\r
-  NetFreePool (Packet);\r
+  FreePool (Packet);\r
   return Status;\r
 }\r
 \r
 \r
 /**\r
-  Handle the received DHCP packets. This function drivers the DHCP\r
+  Handle the received DHCP packets. This function drives the DHCP\r
   state machine.\r
 \r
   @param  UdpPacket             The UDP packets received.\r
-  @param  Points                The local/remote UDP access points\r
+  @param  EndPoint              The local/remote UDP access point\r
   @param  IoStatus              The status of the UDP receive\r
   @param  Context               The opaque parameter to the function.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
+EFIAPI\r
 DhcpInput (\r
   NET_BUF                   *UdpPacket,\r
-  UDP_POINTS                *Points,\r
+  UDP_END_POINT             *EndPoint,\r
   EFI_STATUS                IoStatus,\r
   VOID                      *Context\r
   )\r
@@ -992,11 +963,11 @@ DhcpInput (
   DhcpSb  = (DHCP_SERVICE *) Context;\r
 \r
   //\r
-  // Don't restart receive if error occurs or DHCP is destoried.\r
+  // Don't restart receive if error occurs or DHCP is destroyed.\r
   //\r
   if (EFI_ERROR (IoStatus)) {\r
     return ;\r
-  } else if (DhcpSb->ServiceState == DHCP_DESTORY) {\r
+  } else if (DhcpSb->ServiceState == DHCP_DESTROY) {\r
     NetbufFree (UdpPacket);\r
     return ;\r
   }\r
@@ -1018,7 +989,7 @@ DhcpInput (
   // Copy the DHCP message to a continuous memory block\r
   //\r
   Len     = sizeof (EFI_DHCP4_PACKET) + UdpPacket->TotalSize - sizeof (EFI_DHCP4_HEADER);\r
-  Packet  = (EFI_DHCP4_PACKET *) NetAllocatePool (Len);\r
+  Packet  = (EFI_DHCP4_PACKET *) AllocatePool (Len);\r
 \r
   if (Packet == NULL) {\r
     goto RESTART;\r
@@ -1037,7 +1008,7 @@ DhcpInput (
   //\r
   if ((Head->OpCode != BOOTP_REPLY) ||\r
       (NTOHL (Head->Xid) != DhcpSb->Xid) ||\r
-      !NET_MAC_EQUAL (&DhcpSb->Mac, Head->ClientHwAddr, DhcpSb->HwLen)) {\r
+      (CompareMem (DhcpSb->ClientAddressSendOut, Head->ClientHwAddr, Head->HwAddrLen) != 0)) {\r
     goto RESTART;\r
   }\r
 \r
@@ -1078,7 +1049,7 @@ DhcpInput (
     //\r
     // Ignore the packet in INITREBOOT, INIT and BOUND states\r
     //\r
-    NetFreePool (Packet);\r
+    FreePool (Packet);\r
     Status = EFI_SUCCESS;\r
     break;\r
 \r
@@ -1093,13 +1064,14 @@ DhcpInput (
   }\r
 \r
   if (Para != NULL) {\r
-    NetFreePool (Para);\r
+    FreePool (Para);\r
   }\r
 \r
   Packet = NULL;\r
 \r
   if (EFI_ERROR (Status)) {\r
     NetbufFree (UdpPacket);\r
+    UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);\r
     DhcpEndSession (DhcpSb, Status);\r
     return ;\r
   }\r
@@ -1108,7 +1080,7 @@ RESTART:
   NetbufFree (UdpPacket);\r
 \r
   if (Packet != NULL) {\r
-    NetFreePool (Packet);\r
+    FreePool (Packet);\r
   }\r
 \r
   Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);\r
@@ -1118,39 +1090,20 @@ RESTART:
   }\r
 }\r
 \r
-\r
-/**\r
-  Release the packet.\r
-\r
-  @param  Arg                   The packet to release\r
-\r
-  @return None\r
-\r
-**/\r
-VOID\r
-DhcpReleasePacket (\r
-  IN VOID                   *Arg\r
-  )\r
-{\r
-  NetFreePool (Arg);\r
-}\r
-\r
-\r
 /**\r
   Release the net buffer when packet is sent.\r
 \r
   @param  UdpPacket             The UDP packets received.\r
-  @param  Points                The local/remote UDP access points\r
+  @param  EndPoint              The local/remote UDP access point\r
   @param  IoStatus              The status of the UDP receive\r
   @param  Context               The opaque parameter to the function.\r
 \r
-  @return None\r
-\r
 **/\r
 VOID\r
+EFIAPI\r
 DhcpOnPacketSent (\r
   NET_BUF                   *Packet,\r
-  UDP_POINTS                *Points,\r
+  UDP_END_POINT             *EndPoint,\r
   EFI_STATUS                IoStatus,\r
   VOID                      *Context\r
   )\r
@@ -1166,16 +1119,17 @@ DhcpOnPacketSent (
   the state (as defined in Figure 5. of the same RFC) before sending\r
   a DHCP message. The table is adjusted accordingly.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
-  @param  Seed                  The seed packet which the new packet is based on\r
-  @param  Para                  The DHCP parameter of the Seed packet\r
-  @param  Type                  The message type to send\r
-  @param  Msg                   The human readable message to include in the packet\r
-                                sent.\r
+  @param[in]  DhcpSb                The DHCP service instance\r
+  @param[in]  Seed                  The seed packet which the new packet is based on\r
+  @param[in]  Para                  The DHCP parameter of the Seed packet\r
+  @param[in]  Type                  The message type to send\r
+  @param[in]  Msg                   The human readable message to include in the packet\r
+                                    sent.\r
 \r
   @retval EFI_OUT_OF_RESOURCES  Failed to allocate resources for the packet\r
   @retval EFI_ACCESS_DENIED     Failed to transmit the packet through UDP\r
   @retval EFI_SUCCESS           The message is sent\r
+  @retval other                 Other error occurs\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1192,8 +1146,8 @@ DhcpSendMessage (
   EFI_DHCP4_PACKET          *NewPacket;\r
   EFI_DHCP4_HEADER          *Head;\r
   EFI_DHCP4_HEADER          *SeedHead;\r
-  UDP_IO_PORT               *UdpIo;\r
-  UDP_POINTS                EndPoint;\r
+  UDP_IO                    *UdpIo;\r
+  UDP_END_POINT             EndPoint;\r
   NET_BUF                   *Wrap;\r
   NET_FRAGMENT              Frag;\r
   EFI_STATUS                Status;\r
@@ -1212,7 +1166,7 @@ DhcpSendMessage (
     Len += (UINT32)AsciiStrLen ((CHAR8 *) Msg);\r
   }\r
 \r
-  Packet = NetAllocatePool (Len);\r
+  Packet = AllocatePool (Len);\r
 \r
   if (Packet == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -1232,7 +1186,7 @@ DhcpSendMessage (
   }\r
 \r
   Head = &Packet->Dhcp4.Header;\r
-  NetZeroMem (Head, sizeof (EFI_DHCP4_HEADER));\r
+  ZeroMem (Head, sizeof (EFI_DHCP4_HEADER));\r
 \r
   Head->OpCode       = BOOTP_REQUEST;\r
   Head->HwType       = DhcpSb->HwType;\r
@@ -1241,14 +1195,25 @@ DhcpSendMessage (
   Head->Reserved     = HTONS (0x8000);  //Server, broadcast the message please.\r
 \r
   EFI_IP4 (Head->ClientAddr) = HTONL (DhcpSb->ClientAddr);\r
-  NetCopyMem (Head->ClientHwAddr, DhcpSb->Mac.Addr, DhcpSb->HwLen);\r
+  CopyMem (Head->ClientHwAddr, DhcpSb->Mac.Addr, DhcpSb->HwLen);\r
+\r
+  if ((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) {\r
+    Head->Seconds = 0;\r
+  } else if ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting)) {\r
+    //\r
+    // Use the same value as the original DHCPDISCOVER message.\r
+    //\r
+    Head->Seconds = DhcpSb->LastPacket->Dhcp4.Header.Seconds;\r
+  } else {\r
+    SetElapsedTime(&Head->Seconds, DhcpSb->ActiveChild);\r
+  }\r
 \r
   //\r
   // Append the DHCP message type\r
   //\r
   Packet->Dhcp4.Magik = DHCP_OPTION_MAGIC;\r
   Buf                 = Packet->Dhcp4.Option;\r
-  Buf                 = DhcpAppendOption (Buf, DHCP_TAG_TYPE, 1, &Type);\r
+  Buf                 = DhcpAppendOption (Buf, DHCP4_TAG_MSG_TYPE, 1, &Type);\r
 \r
   //\r
   // Append the serverid option if necessary:\r
@@ -1257,12 +1222,13 @@ DhcpSendMessage (
   //   3. DHCP request to confirm one lease.\r
   //\r
   if ((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE) ||\r
-      ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting))) {\r
+      ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting))\r
+      ) {\r
 \r
     ASSERT ((Para != NULL) && (Para->ServerId != 0));\r
 \r
     IpAddr  = HTONL (Para->ServerId);\r
-    Buf     = DhcpAppendOption (Buf, DHCP_TAG_SERVER_ID, 4, (UINT8 *) &IpAddr);\r
+    Buf     = DhcpAppendOption (Buf, DHCP4_TAG_SERVER_ID, 4, (UINT8 *) &IpAddr);\r
   }\r
 \r
   //\r
@@ -1288,7 +1254,7 @@ DhcpSendMessage (
   }\r
 \r
   if (IpAddr != 0) {\r
-    Buf = DhcpAppendOption (Buf, DHCP_TAG_REQUEST_IP, 4, (UINT8 *) &IpAddr);\r
+    Buf = DhcpAppendOption (Buf, DHCP4_TAG_REQUEST_IP, 4, (UINT8 *) &IpAddr);\r
   }\r
 \r
   //\r
@@ -1298,7 +1264,7 @@ DhcpSendMessage (
   //\r
   if ((Type != DHCP_MSG_DECLINE) && (Type != DHCP_MSG_RELEASE)) {\r
     MaxMsg  = HTONS (0xFF00);\r
-    Buf     = DhcpAppendOption (Buf, DHCP_TAG_MAXMSG, 2, (UINT8 *) &MaxMsg);\r
+    Buf     = DhcpAppendOption (Buf, DHCP4_TAG_MAXMSG, 2, (UINT8 *) &MaxMsg);\r
   }\r
 \r
   //\r
@@ -1306,7 +1272,7 @@ DhcpSendMessage (
   //\r
   if (Msg != NULL) {\r
     Len     = MIN ((UINT32) AsciiStrLen ((CHAR8 *) Msg), 255);\r
-    Buf     = DhcpAppendOption (Buf, DHCP_TAG_MESSAGE, (UINT16) Len, Msg);\r
+    Buf     = DhcpAppendOption (Buf, DHCP4_TAG_MESSAGE, (UINT16) Len, Msg);\r
   }\r
 \r
   //\r
@@ -1319,7 +1285,7 @@ DhcpSendMessage (
       // if it is a DHCP decline or DHCP release .\r
       //\r
       if (((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) &&\r
-          (Config->OptionList[Index]->OpCode != DHCP_TAG_CLIENT_ID)) {\r
+          (Config->OptionList[Index]->OpCode != DHCP4_TAG_CLIENT_ID)) {\r
         continue;\r
       }\r
 \r
@@ -1332,7 +1298,7 @@ DhcpSendMessage (
     }\r
   }\r
 \r
-  *(Buf++) = DHCP_TAG_EOP;\r
+  *(Buf++) = DHCP4_TAG_EOP;\r
   Packet->Length += (UINT32) (Buf - Packet->Dhcp4.Option);\r
 \r
   //\r
@@ -1352,24 +1318,33 @@ DhcpSendMessage (
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-    NetFreePool (Packet);\r
+    FreePool (Packet);\r
     return Status;\r
   }\r
 \r
   if (NewPacket != NULL) {\r
-    NetFreePool (Packet);\r
+    FreePool (Packet);\r
     Packet = NewPacket;\r
   }\r
 \r
+  //\r
+  // Save the Client Address will be sent out\r
+  //\r
+  CopyMem (\r
+    &DhcpSb->ClientAddressSendOut[0],\r
+    &Packet->Dhcp4.Header.ClientHwAddr[0],\r
+    Packet->Dhcp4.Header.HwAddrLen\r
+    );\r
+\r
   //\r
   // Wrap it into a netbuf then send it.\r
   //\r
   Frag.Bulk = (UINT8 *) &Packet->Dhcp4.Header;\r
   Frag.Len  = Packet->Length;\r
-  Wrap      = NetbufFromExt (&Frag, 1, 0, 0, DhcpReleasePacket, Packet);\r
+  Wrap      = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL);\r
 \r
   if (Wrap == NULL) {\r
-    NetFreePool (Packet);\r
+    FreePool (Packet);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -1377,31 +1352,38 @@ DhcpSendMessage (
   // Save it as the last sent packet for retransmission\r
   //\r
   if (DhcpSb->LastPacket != NULL) {\r
-    NetbufFree (DhcpSb->LastPacket);\r
+    FreePool (DhcpSb->LastPacket);\r
   }\r
 \r
-  NET_GET_REF (Wrap);\r
-  DhcpSb->LastPacket = Wrap;\r
+  DhcpSb->LastPacket = Packet;\r
   DhcpSetTransmitTimer (DhcpSb);\r
 \r
   //\r
   // Broadcast the message, unless we know the server address.\r
   // Use the lease UdpIo port to send the unicast packet.\r
   //\r
-  EndPoint.RemoteAddr = 0xffffffff;\r
-  EndPoint.LocalAddr  = 0;\r
-  EndPoint.RemotePort = DHCP_SERVER_PORT;\r
-  EndPoint.LocalPort  = DHCP_CLIENT_PORT;\r
-  UdpIo               = DhcpSb->UdpIo;\r
+  EndPoint.RemoteAddr.Addr[0] = 0xffffffff;\r
+  EndPoint.LocalAddr.Addr[0]  = 0;\r
+  EndPoint.RemotePort         = DHCP_SERVER_PORT;\r
+  EndPoint.LocalPort          = DHCP_CLIENT_PORT;\r
+  UdpIo                       = DhcpSb->UdpIo;\r
 \r
   if ((DhcpSb->DhcpState == Dhcp4Renewing) || (Type == DHCP_MSG_RELEASE)) {\r
-    EndPoint.RemoteAddr = DhcpSb->ServerAddr;\r
-    EndPoint.LocalAddr  = DhcpSb->ClientAddr;\r
-    UdpIo               = DhcpSb->LeaseIoPort;\r
+    EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr;\r
+    EndPoint.LocalAddr.Addr[0]  = DhcpSb->ClientAddr;\r
+    UdpIo                       = DhcpSb->LeaseIoPort;\r
   }\r
 \r
   ASSERT (UdpIo != NULL);\r
-  Status = UdpIoSendDatagram (UdpIo, Wrap, &EndPoint, 0, DhcpOnPacketSent, DhcpSb);\r
+\r
+  Status = UdpIoSendDatagram (\r
+             UdpIo,\r
+             Wrap,\r
+             &EndPoint,\r
+             NULL,\r
+             DhcpOnPacketSent,\r
+             DhcpSb\r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     NetbufFree (Wrap);\r
@@ -1416,7 +1398,7 @@ DhcpSendMessage (
   Retransmit a saved packet. Only DISCOVER and REQUEST messages\r
   will be retransmitted.\r
 \r
-  @param  DhcpSb                The DHCP service instance\r
+  @param[in]  DhcpSb                The DHCP service instance\r
 \r
   @retval EFI_ACCESS_DENIED     Failed to transmit packet through UDP port\r
   @retval EFI_SUCCESS           The packet is retransmitted.\r
@@ -1427,41 +1409,60 @@ DhcpRetransmit (
   IN DHCP_SERVICE           *DhcpSb\r
   )\r
 {\r
-  UDP_IO_PORT               *UdpIo;\r
-  UDP_POINTS                EndPoint;\r
+  UDP_IO                    *UdpIo;\r
+  UDP_END_POINT             EndPoint;\r
+  NET_BUF                   *Wrap;\r
+  NET_FRAGMENT              Frag;\r
   EFI_STATUS                Status;\r
 \r
   ASSERT (DhcpSb->LastPacket != NULL);\r
 \r
+  //\r
+  // For REQUEST message in Dhcp4Requesting state, do not change the secs fields.\r
+  //\r
+  if (DhcpSb->DhcpState != Dhcp4Requesting) {\r
+    SetElapsedTime(&DhcpSb->LastPacket->Dhcp4.Header.Seconds, DhcpSb->ActiveChild);\r
+  }\r
+\r
+  //\r
+  // Wrap it into a netbuf then send it.\r
+  //\r
+  Frag.Bulk = (UINT8 *) &DhcpSb->LastPacket->Dhcp4.Header;\r
+  Frag.Len  = DhcpSb->LastPacket->Length;\r
+  Wrap      = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL);\r
+\r
+  if (Wrap == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   //\r
   // Broadcast the message, unless we know the server address.\r
   //\r
-  EndPoint.RemotePort = DHCP_SERVER_PORT;\r
-  EndPoint.LocalPort  = DHCP_CLIENT_PORT;\r
-  EndPoint.RemoteAddr = 0xffffffff;\r
-  EndPoint.LocalAddr  = 0;\r
-  UdpIo               = DhcpSb->UdpIo;\r
+  EndPoint.RemotePort         = DHCP_SERVER_PORT;\r
+  EndPoint.LocalPort          = DHCP_CLIENT_PORT;\r
+  EndPoint.RemoteAddr.Addr[0] = 0xffffffff;\r
+  EndPoint.LocalAddr.Addr[0]  = 0;\r
+  UdpIo                       = DhcpSb->UdpIo;\r
 \r
   if (DhcpSb->DhcpState == Dhcp4Renewing) {\r
-    EndPoint.RemoteAddr = DhcpSb->ServerAddr;\r
-    EndPoint.LocalAddr  = DhcpSb->ClientAddr;\r
-    UdpIo               = DhcpSb->LeaseIoPort;\r
+    EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr;\r
+    EndPoint.LocalAddr.Addr[0]  = DhcpSb->ClientAddr;\r
+    UdpIo                       = DhcpSb->LeaseIoPort;\r
   }\r
 \r
   ASSERT (UdpIo != NULL);\r
 \r
-  NET_GET_REF (DhcpSb->LastPacket);\r
   Status = UdpIoSendDatagram (\r
              UdpIo,\r
-             DhcpSb->LastPacket,\r
+             Wrap,\r
              &EndPoint,\r
-             0,\r
+             NULL,\r
              DhcpOnPacketSent,\r
              DhcpSb\r
              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    NET_PUT_REF (DhcpSb->LastPacket);\r
+    NetbufFree (Wrap);\r
     return EFI_ACCESS_DENIED;\r
   }\r
 \r
@@ -1476,10 +1477,8 @@ DhcpRetransmit (
   and lease to determine the time to renew and rebind the lease.\r
   DhcpOnTimerTick will be called once every second.\r
 \r
-  @param  Event                 The timer event\r
-  @param  Context               The context, which is the DHCP service instance.\r
-\r
-  @return None\r
+  @param[in]  Event                 The timer event\r
+  @param[in]  Context               The context, which is the DHCP service instance.\r
 \r
 **/\r
 VOID\r
@@ -1489,36 +1488,44 @@ DhcpOnTimerTick (
   IN VOID                   *Context\r
   )\r
 {\r
+  LIST_ENTRY                *Entry;\r
+  LIST_ENTRY                *Next;\r
   DHCP_SERVICE              *DhcpSb;\r
   DHCP_PROTOCOL             *Instance;\r
   EFI_STATUS                Status;\r
-  \r
+\r
   DhcpSb   = (DHCP_SERVICE *) Context;\r
   Instance = DhcpSb->ActiveChild;\r
 \r
   //\r
-  // Check the time to wait offer\r
+  // 0xffff is the maximum supported value for elapsed time according to RFC.\r
   //\r
-  if ((DhcpSb->WaitOffer > 0) && (--DhcpSb->WaitOffer == 0)) {\r
-    //\r
-    // OK, offer collection finished, select a offer\r
-    //\r
-    ASSERT (DhcpSb->DhcpState == Dhcp4Selecting);\r
-\r
-    if (DhcpSb->LastOffer == NULL) {\r
-      goto END_SESSION;\r
-    }\r
-\r
-    if (EFI_ERROR (DhcpChooseOffer (DhcpSb))) {\r
-      goto END_SESSION;\r
-    }\r
+  if (Instance != NULL && Instance->ElaspedTime < 0xffff) {\r
+    Instance->ElaspedTime++;\r
   }\r
-  \r
+\r
   //\r
   // Check the retransmit timer\r
   //\r
   if ((DhcpSb->PacketToLive > 0) && (--DhcpSb->PacketToLive == 0)) {\r
 \r
+    //\r
+    // Select offer at each timeout if any offer received.\r
+    //\r
+    if (DhcpSb->DhcpState == Dhcp4Selecting && DhcpSb->LastOffer != NULL) {\r
+\r
+      Status = DhcpChooseOffer (DhcpSb);\r
+\r
+      if (EFI_ERROR(Status)) {\r
+        if (DhcpSb->LastOffer != NULL) {\r
+          FreePool (DhcpSb->LastOffer);\r
+          DhcpSb->LastOffer = NULL;\r
+        }\r
+      } else {\r
+        goto ON_EXIT;\r
+      }\r
+    }\r
+\r
     if (++DhcpSb->CurRetry < DhcpSb->MaxRetries) {\r
       //\r
       // Still has another try\r
@@ -1526,17 +1533,14 @@ DhcpOnTimerTick (
       DhcpRetransmit (DhcpSb);\r
       DhcpSetTransmitTimer (DhcpSb);\r
 \r
-    } else {\r
-      if (!DHCP_CONNECTED (DhcpSb->DhcpState)) {\r
-        goto END_SESSION;\r
-      }\r
+    } else if (DHCP_CONNECTED (DhcpSb->DhcpState)) {\r
 \r
       //\r
       // Retransmission failed, if the DHCP request is initiated by\r
       // user, adjust the current state according to the lease life.\r
       // Otherwise do nothing to wait the lease to timeout\r
       //\r
-      if (DhcpSb->ExtraRefresh) {\r
+      if (DhcpSb->ExtraRefresh != 0) {\r
         Status = EFI_SUCCESS;\r
 \r
         if (DhcpSb->LeaseLife < DhcpSb->T1) {\r
@@ -1556,9 +1560,11 @@ DhcpOnTimerTick (
         DhcpSb->IoStatus = EFI_TIMEOUT;\r
         DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_RENEWREBIND);\r
       }\r
+    } else {\r
+      goto END_SESSION;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // If an address has been acquired, check whether need to\r
   // refresh or whether it has expired.\r
@@ -1570,7 +1576,7 @@ DhcpOnTimerTick (
     // Don't timeout the lease, only count the life if user is\r
     // requesting extra renew/rebind. Adjust the state after that.\r
     //\r
-    if (DhcpSb->ExtraRefresh) {\r
+    if (DhcpSb->ExtraRefresh != 0) {\r
       return ;\r
     }\r
 \r
@@ -1588,6 +1594,10 @@ DhcpOnTimerTick (
         goto END_SESSION;\r
       }\r
 \r
+      if (Instance != NULL) {\r
+        Instance->ElaspedTime= 0;\r
+      }\r
+\r
       Status = DhcpSendMessage (\r
                  DhcpSb,\r
                  DhcpSb->Selected,\r
@@ -1608,6 +1618,10 @@ DhcpOnTimerTick (
         goto END_SESSION;\r
       }\r
 \r
+      if (Instance != NULL) {\r
+        Instance->ElaspedTime= 0;\r
+      }\r
+\r
       Status = DhcpSendMessage (\r
                  DhcpSb,\r
                  DhcpSb->Selected,\r
@@ -1622,12 +1636,14 @@ DhcpOnTimerTick (
     }\r
   }\r
 \r
+ON_EXIT:\r
   //\r
+  // Iterate through all the DhcpSb Children.\r
   //\r
-  //\r
-  if ((Instance != NULL) && (Instance->Token != NULL)) {\r
+  NET_LIST_FOR_EACH_SAFE (Entry, Next, &DhcpSb->Children) {\r
+    Instance = NET_LIST_USER_STRUCT (Entry, DHCP_PROTOCOL, Link);\r
     Instance->Timeout--;\r
-    if (Instance->Timeout == 0) {\r
+    if (Instance->Timeout == 0 && Instance->Token != NULL) {\r
       PxeDhcpDone (Instance);\r
     }\r
   }\r