]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
NetworkPkg: Add warning message for PXE if failed to read system GUID from SMBIOS.
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcDhcp4.c
index 587566d4e0d8a5cba7fb6a1269a6a84de223b979..bb65445fc9f0f3b95b6285ea9bfb0a46579f927f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Functions implementation related with DHCPv4 for UefiPxeBc Driver.\r
 \r
 /** @file\r
   Functions implementation related with DHCPv4 for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 // This is a map from the interested DHCP4 option tags' index to the tag value.\r
 //\r
 UINT8 mInterestedDhcp4Tags[PXEBC_DHCP4_TAG_INDEX_MAX] = {\r
 // This is a map from the interested DHCP4 option tags' index to the tag value.\r
 //\r
 UINT8 mInterestedDhcp4Tags[PXEBC_DHCP4_TAG_INDEX_MAX] = {\r
-  PXEBC_DHCP4_TAG_BOOTFILE_LEN,\r
-  PXEBC_DHCP4_TAG_VENDOR,\r
-  PXEBC_DHCP4_TAG_OVERLOAD,\r
-  PXEBC_DHCP4_TAG_MSG_TYPE,\r
-  PXEBC_DHCP4_TAG_SERVER_ID,\r
-  PXEBC_DHCP4_TAG_CLASS_ID,\r
-  PXEBC_DHCP4_TAG_BOOTFILE\r
+  DHCP4_TAG_BOOTFILE_LEN,\r
+  DHCP4_TAG_VENDOR,\r
+  DHCP4_TAG_OVERLOAD,\r
+  DHCP4_TAG_MSG_TYPE,\r
+  DHCP4_TAG_SERVER_ID,\r
+  DHCP4_TAG_VENDOR_CLASS_ID,\r
+  DHCP4_TAG_BOOTFILE\r
 };\r
 \r
 //\r
 };\r
 \r
 //\r
@@ -58,7 +58,7 @@ PxeBcParseDhcp4Options (
   Option  = (EFI_DHCP4_PACKET_OPTION *) Buffer;\r
   Offset  = 0;\r
 \r
   Option  = (EFI_DHCP4_PACKET_OPTION *) Buffer;\r
   Offset  = 0;\r
 \r
-  while (Offset < Length && Option->OpCode != PXEBC_DHCP4_TAG_EOP) {\r
+  while (Offset < Length && Option->OpCode != DHCP4_TAG_EOP) {\r
 \r
     if (Option->OpCode == OptTag) {\r
       //\r
 \r
     if (Option->OpCode == OptTag) {\r
       //\r
@@ -70,7 +70,7 @@ PxeBcParseDhcp4Options (
     //\r
     // Skip the current option to the next.\r
     //\r
     //\r
     // Skip the current option to the next.\r
     //\r
-    if (Option->OpCode == PXEBC_DHCP4_TAG_PAD) {\r
+    if (Option->OpCode == DHCP4_TAG_PAD) {\r
       Offset++;\r
     } else {\r
       Offset += Option->Length + 2;\r
       Offset++;\r
     } else {\r
       Offset += Option->Length + 2;\r
@@ -108,7 +108,7 @@ PxeBcParseVendorOptions (
 \r
   ASSERT (PxeOption != NULL);\r
 \r
 \r
   ASSERT (PxeOption != NULL);\r
 \r
-  while ((Offset < VendorOptionLen) && (PxeOption->OpCode != PXEBC_DHCP4_TAG_EOP)) {\r
+  while ((Offset < VendorOptionLen) && (PxeOption->OpCode != DHCP4_TAG_EOP)) {\r
     //\r
     // Parse all the interesting PXE vendor options one by one.\r
     //\r
     //\r
     // Parse all the interesting PXE vendor options one by one.\r
     //\r
@@ -201,7 +201,7 @@ PxeBcParseVendorOptions (
     //\r
     // Continue to the next option.\r
     //\r
     //\r
     // Continue to the next option.\r
     //\r
-    if (PxeOption->OpCode == PXEBC_DHCP4_TAG_PAD) {\r
+    if (PxeOption->OpCode == DHCP4_TAG_PAD) {\r
       Offset++;\r
     } else {\r
       Offset = (UINT8) (Offset + PxeOption->Length + 2);\r
       Offset++;\r
     } else {\r
       Offset = (UINT8) (Offset + PxeOption->Length + 2);\r
@@ -243,7 +243,7 @@ PxeBcBuildDhcp4Options (
     //\r
     // Append message type.\r
     //\r
     //\r
     // Append message type.\r
     //\r
-    OptList[Index]->OpCode  = PXEBC_DHCP4_TAG_MSG_TYPE;\r
+    OptList[Index]->OpCode  = DHCP4_TAG_MSG_TYPE;\r
     OptList[Index]->Length  = 1;\r
     OptEnt.Mesg             = (PXEBC_DHCP4_OPTION_MESG *) OptList[Index]->Data;\r
     OptEnt.Mesg->Type       = PXEBC_DHCP4_MSG_TYPE_REQUEST;\r
     OptList[Index]->Length  = 1;\r
     OptEnt.Mesg             = (PXEBC_DHCP4_OPTION_MESG *) OptList[Index]->Data;\r
     OptEnt.Mesg->Type       = PXEBC_DHCP4_MSG_TYPE_REQUEST;\r
@@ -253,10 +253,10 @@ PxeBcBuildDhcp4Options (
     //\r
     // Append max message size.\r
     //\r
     //\r
     // Append max message size.\r
     //\r
-    OptList[Index]->OpCode  = PXEBC_DHCP4_TAG_MAXMSG;\r
+    OptList[Index]->OpCode  = DHCP4_TAG_MAXMSG;\r
     OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE);\r
     OptEnt.MaxMesgSize      = (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE *) OptList[Index]->Data;\r
     OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE);\r
     OptEnt.MaxMesgSize      = (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE *) OptList[Index]->Data;\r
-    Value                   = NTOHS (PXEBC_DHCP4_PACKET_MAX_SIZE - 8);\r
+    Value                   = NTOHS (PXEBC_DHCP4_PACKET_MAX_SIZE);\r
     CopyMem (&OptEnt.MaxMesgSize->Size, &Value, sizeof (UINT16));\r
     Index++;\r
     OptList[Index]          = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);\r
     CopyMem (&OptEnt.MaxMesgSize->Size, &Value, sizeof (UINT16));\r
     Index++;\r
     OptList[Index]          = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);\r
@@ -265,36 +265,36 @@ PxeBcBuildDhcp4Options (
   //\r
   // Append parameter request list option.\r
   //\r
   //\r
   // Append parameter request list option.\r
   //\r
-  OptList[Index]->OpCode    = PXEBC_DHCP4_TAG_PARA_LIST;\r
+  OptList[Index]->OpCode    = DHCP4_TAG_PARA_LIST;\r
   OptList[Index]->Length    = 35;\r
   OptEnt.Para               = (PXEBC_DHCP4_OPTION_PARA *) OptList[Index]->Data;\r
   OptList[Index]->Length    = 35;\r
   OptEnt.Para               = (PXEBC_DHCP4_OPTION_PARA *) OptList[Index]->Data;\r
-  OptEnt.Para->ParaList[0]  = PXEBC_DHCP4_TAG_NETMASK;\r
-  OptEnt.Para->ParaList[1]  = PXEBC_DHCP4_TAG_TIME_OFFSET;\r
-  OptEnt.Para->ParaList[2]  = PXEBC_DHCP4_TAG_ROUTER;\r
-  OptEnt.Para->ParaList[3]  = PXEBC_DHCP4_TAG_TIME_SERVER;\r
-  OptEnt.Para->ParaList[4]  = PXEBC_DHCP4_TAG_NAME_SERVER;\r
-  OptEnt.Para->ParaList[5]  = PXEBC_DHCP4_TAG_DNS_SERVER;\r
-  OptEnt.Para->ParaList[6]  = PXEBC_DHCP4_TAG_HOSTNAME;\r
-  OptEnt.Para->ParaList[7]  = PXEBC_DHCP4_TAG_BOOTFILE_LEN;\r
-  OptEnt.Para->ParaList[8]  = PXEBC_DHCP4_TAG_DOMAINNAME;\r
-  OptEnt.Para->ParaList[9]  = PXEBC_DHCP4_TAG_ROOTPATH;\r
-  OptEnt.Para->ParaList[10] = PXEBC_DHCP4_TAG_EXTEND_PATH;\r
-  OptEnt.Para->ParaList[11] = PXEBC_DHCP4_TAG_EMTU;\r
-  OptEnt.Para->ParaList[12] = PXEBC_DHCP4_TAG_TTL;\r
-  OptEnt.Para->ParaList[13] = PXEBC_DHCP4_TAG_BROADCAST;\r
-  OptEnt.Para->ParaList[14] = PXEBC_DHCP4_TAG_NIS_DOMAIN;\r
-  OptEnt.Para->ParaList[15] = PXEBC_DHCP4_TAG_NIS_SERVER;\r
-  OptEnt.Para->ParaList[16] = PXEBC_DHCP4_TAG_NTP_SERVER;\r
-  OptEnt.Para->ParaList[17] = PXEBC_DHCP4_TAG_VENDOR;\r
-  OptEnt.Para->ParaList[18] = PXEBC_DHCP4_TAG_REQUEST_IP;\r
-  OptEnt.Para->ParaList[19] = PXEBC_DHCP4_TAG_LEASE;\r
-  OptEnt.Para->ParaList[20] = PXEBC_DHCP4_TAG_SERVER_ID;\r
-  OptEnt.Para->ParaList[21] = PXEBC_DHCP4_TAG_T1;\r
-  OptEnt.Para->ParaList[22] = PXEBC_DHCP4_TAG_T2;\r
-  OptEnt.Para->ParaList[23] = PXEBC_DHCP4_TAG_CLASS_ID;\r
-  OptEnt.Para->ParaList[24] = PXEBC_DHCP4_TAG_TFTP;\r
-  OptEnt.Para->ParaList[25] = PXEBC_DHCP4_TAG_BOOTFILE;\r
-  OptEnt.Para->ParaList[26] = PXEBC_PXE_DHCP4_TAG_UUID;\r
+  OptEnt.Para->ParaList[0]  = DHCP4_TAG_NETMASK;\r
+  OptEnt.Para->ParaList[1]  = DHCP4_TAG_TIME_OFFSET;\r
+  OptEnt.Para->ParaList[2]  = DHCP4_TAG_ROUTER;\r
+  OptEnt.Para->ParaList[3]  = DHCP4_TAG_TIME_SERVER;\r
+  OptEnt.Para->ParaList[4]  = DHCP4_TAG_NAME_SERVER;\r
+  OptEnt.Para->ParaList[5]  = DHCP4_TAG_DNS_SERVER;\r
+  OptEnt.Para->ParaList[6]  = DHCP4_TAG_HOSTNAME;\r
+  OptEnt.Para->ParaList[7]  = DHCP4_TAG_BOOTFILE_LEN;\r
+  OptEnt.Para->ParaList[8]  = DHCP4_TAG_DOMAINNAME;\r
+  OptEnt.Para->ParaList[9]  = DHCP4_TAG_ROOTPATH;\r
+  OptEnt.Para->ParaList[10] = DHCP4_TAG_EXTEND_PATH;\r
+  OptEnt.Para->ParaList[11] = DHCP4_TAG_EMTU;\r
+  OptEnt.Para->ParaList[12] = DHCP4_TAG_TTL;\r
+  OptEnt.Para->ParaList[13] = DHCP4_TAG_BROADCAST;\r
+  OptEnt.Para->ParaList[14] = DHCP4_TAG_NIS_DOMAIN;\r
+  OptEnt.Para->ParaList[15] = DHCP4_TAG_NIS_SERVER;\r
+  OptEnt.Para->ParaList[16] = DHCP4_TAG_NTP_SERVER;\r
+  OptEnt.Para->ParaList[17] = DHCP4_TAG_VENDOR;\r
+  OptEnt.Para->ParaList[18] = DHCP4_TAG_REQUEST_IP;\r
+  OptEnt.Para->ParaList[19] = DHCP4_TAG_LEASE;\r
+  OptEnt.Para->ParaList[20] = DHCP4_TAG_SERVER_ID;\r
+  OptEnt.Para->ParaList[21] = DHCP4_TAG_T1;\r
+  OptEnt.Para->ParaList[22] = DHCP4_TAG_T2;\r
+  OptEnt.Para->ParaList[23] = DHCP4_TAG_VENDOR_CLASS_ID;\r
+  OptEnt.Para->ParaList[24] = DHCP4_TAG_TFTP;\r
+  OptEnt.Para->ParaList[25] = DHCP4_TAG_BOOTFILE;\r
+  OptEnt.Para->ParaList[26] = DHCP4_TAG_UUID;\r
   OptEnt.Para->ParaList[27] = 0x80;\r
   OptEnt.Para->ParaList[28] = 0x81;\r
   OptEnt.Para->ParaList[29] = 0x82;\r
   OptEnt.Para->ParaList[27] = 0x80;\r
   OptEnt.Para->ParaList[28] = 0x81;\r
   OptEnt.Para->ParaList[29] = 0x82;\r
@@ -309,7 +309,7 @@ PxeBcBuildDhcp4Options (
   //\r
   // Append UUID/Guid-based client identifier option\r
   //\r
   //\r
   // Append UUID/Guid-based client identifier option\r
   //\r
-  OptList[Index]->OpCode  = PXEBC_PXE_DHCP4_TAG_UUID;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_UUID;\r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_UUID);\r
   OptEnt.Uuid             = (PXEBC_DHCP4_OPTION_UUID *) OptList[Index]->Data;\r
   OptEnt.Uuid->Type       = 0;\r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_UUID);\r
   OptEnt.Uuid             = (PXEBC_DHCP4_OPTION_UUID *) OptList[Index]->Data;\r
   OptEnt.Uuid->Type       = 0;\r
@@ -320,13 +320,14 @@ PxeBcBuildDhcp4Options (
     //\r
     // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
     //\r
     //\r
     // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
     //\r
+    DEBUG ((EFI_D_WARN, "PXE: Failed to read system GUID from the smbios table!\n"));\r
     ZeroMem (OptEnt.Uuid->Guid, sizeof (EFI_GUID));\r
   }\r
 \r
   //\r
   // Append client network device interface option\r
   //\r
     ZeroMem (OptEnt.Uuid->Guid, sizeof (EFI_GUID));\r
   }\r
 \r
   //\r
   // Append client network device interface option\r
   //\r
-  OptList[Index]->OpCode  = PXEBC_PXE_DHCP4_TAG_UNDI;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_UNDI;\r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_UNDI);\r
   OptEnt.Undi             = (PXEBC_DHCP4_OPTION_UNDI *) OptList[Index]->Data;\r
 \r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_UNDI);\r
   OptEnt.Undi             = (PXEBC_DHCP4_OPTION_UNDI *) OptList[Index]->Data;\r
 \r
@@ -346,7 +347,7 @@ PxeBcBuildDhcp4Options (
   //\r
   // Append client system architecture option\r
   //\r
   //\r
   // Append client system architecture option\r
   //\r
-  OptList[Index]->OpCode  = PXEBC_PXE_DHCP4_TAG_ARCH;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_ARCH;\r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_ARCH);\r
   OptEnt.Arch             = (PXEBC_DHCP4_OPTION_ARCH *) OptList[Index]->Data;\r
   Value                   = HTONS (EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE);\r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_ARCH);\r
   OptEnt.Arch             = (PXEBC_DHCP4_OPTION_ARCH *) OptList[Index]->Data;\r
   Value                   = HTONS (EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE);\r
@@ -357,7 +358,7 @@ PxeBcBuildDhcp4Options (
   //\r
   // Append vendor class identify option\r
   //\r
   //\r
   // Append vendor class identify option\r
   //\r
-  OptList[Index]->OpCode  = PXEBC_DHCP4_TAG_CLASS_ID;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_VENDOR_CLASS_ID;\r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_CLID);\r
   OptEnt.Clid             = (PXEBC_DHCP4_OPTION_CLID *) OptList[Index]->Data;\r
   CopyMem (\r
   OptList[Index]->Length  = (UINT8) sizeof (PXEBC_DHCP4_OPTION_CLID);\r
   OptEnt.Clid             = (PXEBC_DHCP4_OPTION_CLID *) OptList[Index]->Data;\r
   CopyMem (\r
@@ -414,7 +415,7 @@ PxeBcSeedDhcp4Packet (
   CopyMem (Header->ClientHwAddr, &Mode.CurrentAddress, Header->HwAddrLen);\r
 \r
   Seed->Dhcp4.Magik     = PXEBC_DHCP4_MAGIC;\r
   CopyMem (Header->ClientHwAddr, &Mode.CurrentAddress, Header->HwAddrLen);\r
 \r
   Seed->Dhcp4.Magik     = PXEBC_DHCP4_MAGIC;\r
-  Seed->Dhcp4.Option[0] = PXEBC_DHCP4_TAG_EOP;\r
+  Seed->Dhcp4.Option[0] = DHCP4_TAG_EOP;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -424,17 +425,24 @@ PxeBcSeedDhcp4Packet (
   @param[in]  Dst          Pointer to the cache buffer for DHCPv4 packet.\r
   @param[in]  Src          Pointer to the DHCPv4 packet to be cached.\r
 \r
   @param[in]  Dst          Pointer to the cache buffer for DHCPv4 packet.\r
   @param[in]  Src          Pointer to the DHCPv4 packet to be cached.\r
 \r
+  @retval     EFI_SUCCESS                Packet is copied.\r
+  @retval     EFI_BUFFER_TOO_SMALL       Cache buffer is not big enough to hold the packet.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 PxeBcCacheDhcp4Packet (\r
   IN EFI_DHCP4_PACKET     *Dst,\r
   IN EFI_DHCP4_PACKET     *Src\r
   )\r
 {\r
 PxeBcCacheDhcp4Packet (\r
   IN EFI_DHCP4_PACKET     *Dst,\r
   IN EFI_DHCP4_PACKET     *Src\r
   )\r
 {\r
-  ASSERT (Dst->Size >= Src->Length);\r
-\r
+  if (Dst->Size < Src->Length) {\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+  \r
   CopyMem (&Dst->Dhcp4, &Src->Dhcp4, Src->Length);\r
   Dst->Length = Src->Length;\r
   CopyMem (&Dst->Dhcp4, &Src->Dhcp4, Src->Length);\r
   Dst->Length = Src->Length;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -460,9 +468,11 @@ PxeBcParseDhcp4Packet (
   BOOLEAN                        IsProxyOffer;\r
   BOOLEAN                        IsPxeOffer;\r
   UINT8                          *Ptr8;\r
   BOOLEAN                        IsProxyOffer;\r
   BOOLEAN                        IsPxeOffer;\r
   UINT8                          *Ptr8;\r
+  BOOLEAN                        FileFieldOverloaded;\r
 \r
   IsProxyOffer = FALSE;\r
   IsPxeOffer   = FALSE;\r
 \r
   IsProxyOffer = FALSE;\r
   IsPxeOffer   = FALSE;\r
+  FileFieldOverloaded = FALSE;\r
 \r
   ZeroMem (Cache4->OptList, sizeof (Cache4->OptList));\r
   ZeroMem (&Cache4->VendorOpt, sizeof (Cache4->VendorOpt));\r
 \r
   ZeroMem (Cache4->OptList, sizeof (Cache4->OptList));\r
   ZeroMem (&Cache4->VendorOpt, sizeof (Cache4->VendorOpt));\r
@@ -488,6 +498,7 @@ PxeBcParseDhcp4Packet (
   Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];\r
   if (Option != NULL) {\r
     if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {\r
   Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];\r
   if (Option != NULL) {\r
     if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {\r
+      FileFieldOverloaded = TRUE;\r
       for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {\r
         if (Options[Index] == NULL) {\r
           Options[Index] = PxeBcParseDhcp4Options (\r
       for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {\r
         if (Options[Index] == NULL) {\r
           Options[Index] = PxeBcParseDhcp4Options (\r
@@ -550,7 +561,7 @@ PxeBcParseDhcp4Packet (
     if (*(Ptr8 - 1) != '\0') {\r
       *Ptr8 = '\0';\r
     }\r
     if (*(Ptr8 - 1) != '\0') {\r
       *Ptr8 = '\0';\r
     }\r
-  } else if (Offer->Dhcp4.Header.BootFileName[0] != 0) {\r
+  } else if (!FileFieldOverloaded && Offer->Dhcp4.Header.BootFileName[0] != 0) {\r
     //\r
     // If the bootfile is not present and bootfilename is present in DHCPv4 packet, just parse it.\r
     // Do not count dhcp option header here, or else will destroy the serverhostname.\r
     //\r
     // If the bootfile is not present and bootfilename is present in DHCPv4 packet, just parse it.\r
     // Do not count dhcp option header here, or else will destroy the serverhostname.\r
@@ -617,8 +628,11 @@ PxeBcParseDhcp4Packet (
   @param[in]  Ack                 Pointer to the DHCPv4 ack packet.\r
   @param[in]  Verified            If TRUE, parse the ACK packet and store info into mode data.\r
 \r
   @param[in]  Ack                 Pointer to the DHCPv4 ack packet.\r
   @param[in]  Verified            If TRUE, parse the ACK packet and store info into mode data.\r
 \r
+  @retval     EFI_SUCCESS                Cache and parse the packet successfully.\r
+  @retval     EFI_BUFFER_TOO_SMALL       Cache buffer is not big enough to hold the packet.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 PxeBcCopyDhcp4Ack (\r
   IN PXEBC_PRIVATE_DATA   *Private,\r
   IN EFI_DHCP4_PACKET     *Ack,\r
 PxeBcCopyDhcp4Ack (\r
   IN PXEBC_PRIVATE_DATA   *Private,\r
   IN EFI_DHCP4_PACKET     *Ack,\r
@@ -626,10 +640,14 @@ PxeBcCopyDhcp4Ack (
   )\r
 {\r
   EFI_PXE_BASE_CODE_MODE  *Mode;\r
   )\r
 {\r
   EFI_PXE_BASE_CODE_MODE  *Mode;\r
+  EFI_STATUS              Status;\r
 \r
   Mode = Private->PxeBc.Mode;\r
 \r
 \r
   Mode = Private->PxeBc.Mode;\r
 \r
-  PxeBcCacheDhcp4Packet (&Private->DhcpAck.Dhcp4.Packet.Ack, Ack);\r
+  Status = PxeBcCacheDhcp4Packet (&Private->DhcpAck.Dhcp4.Packet.Ack, Ack);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   if (Verified) {\r
     //\r
 \r
   if (Verified) {\r
     //\r
@@ -639,6 +657,8 @@ PxeBcCopyDhcp4Ack (
     CopyMem (&Mode->DhcpAck.Dhcpv4, &Ack->Dhcp4, Ack->Length);\r
     Mode->DhcpAckReceived = TRUE;\r
   }\r
     CopyMem (&Mode->DhcpAck.Dhcpv4, &Ack->Dhcp4, Ack->Length);\r
     Mode->DhcpAckReceived = TRUE;\r
   }\r
+  \r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -648,8 +668,11 @@ PxeBcCopyDhcp4Ack (
   @param[in]  Private               Pointer to PxeBc private data.\r
   @param[in]  OfferIndex            The received order of offer packets.\r
 \r
   @param[in]  Private               Pointer to PxeBc private data.\r
   @param[in]  OfferIndex            The received order of offer packets.\r
 \r
+  @retval     EFI_SUCCESS                Cache and parse the packet successfully.\r
+  @retval     EFI_BUFFER_TOO_SMALL       Cache buffer is not big enough to hold the packet.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 PxeBcCopyProxyOffer (\r
   IN PXEBC_PRIVATE_DATA   *Private,\r
   IN UINT32               OfferIndex\r
 PxeBcCopyProxyOffer (\r
   IN PXEBC_PRIVATE_DATA   *Private,\r
   IN UINT32               OfferIndex\r
@@ -657,6 +680,7 @@ PxeBcCopyProxyOffer (
 {\r
   EFI_PXE_BASE_CODE_MODE  *Mode;\r
   EFI_DHCP4_PACKET        *Offer;\r
 {\r
   EFI_PXE_BASE_CODE_MODE  *Mode;\r
   EFI_DHCP4_PACKET        *Offer;\r
+  EFI_STATUS              Status;\r
 \r
   ASSERT (OfferIndex < Private->OfferNum);\r
   ASSERT (OfferIndex < PXEBC_OFFER_MAX_NUM);\r
 \r
   ASSERT (OfferIndex < Private->OfferNum);\r
   ASSERT (OfferIndex < PXEBC_OFFER_MAX_NUM);\r
@@ -667,7 +691,11 @@ PxeBcCopyProxyOffer (
   //\r
   // Cache the proxy offer packet and parse it.\r
   //\r
   //\r
   // Cache the proxy offer packet and parse it.\r
   //\r
-  PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Offer);\r
+  Status = PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Offer);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+  \r
   PxeBcParseDhcp4Packet (&Private->ProxyOffer.Dhcp4);\r
 \r
   //\r
   PxeBcParseDhcp4Packet (&Private->ProxyOffer.Dhcp4);\r
 \r
   //\r
@@ -675,6 +703,8 @@ PxeBcCopyProxyOffer (
   //\r
   CopyMem (&Mode->ProxyOffer.Dhcpv4, &Offer->Dhcp4, Offer->Length);\r
   Mode->ProxyOfferReceived = TRUE;\r
   //\r
   CopyMem (&Mode->ProxyOffer.Dhcpv4, &Offer->Dhcp4, Offer->Length);\r
   Mode->ProxyOfferReceived = TRUE;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -777,8 +807,11 @@ PxeBcRetryBinlOffer (
   @param[in]  Private               Pointer to PxeBc private data.\r
   @param[in]  RcvdOffer             Pointer to the received offer packet.\r
 \r
   @param[in]  Private               Pointer to PxeBc private data.\r
   @param[in]  RcvdOffer             Pointer to the received offer packet.\r
 \r
+  @retval     EFI_SUCCESS      Cache and parse the packet successfully.\r
+  @retval     Others           Operation failed.\r
+\r
 **/\r
 **/\r
-VOID\r
+EFI_STATUS\r
 PxeBcCacheDhcp4Offer (\r
   IN PXEBC_PRIVATE_DATA     *Private,\r
   IN EFI_DHCP4_PACKET       *RcvdOffer\r
 PxeBcCacheDhcp4Offer (\r
   IN PXEBC_PRIVATE_DATA     *Private,\r
   IN EFI_DHCP4_PACKET       *RcvdOffer\r
@@ -787,6 +820,7 @@ PxeBcCacheDhcp4Offer (
   PXEBC_DHCP4_PACKET_CACHE  *Cache4;\r
   EFI_DHCP4_PACKET          *Offer;\r
   PXEBC_OFFER_TYPE          OfferType;\r
   PXEBC_DHCP4_PACKET_CACHE  *Cache4;\r
   EFI_DHCP4_PACKET          *Offer;\r
   PXEBC_OFFER_TYPE          OfferType;\r
+  EFI_STATUS                Status;\r
 \r
   ASSERT (Private->OfferNum < PXEBC_OFFER_MAX_NUM);\r
   Cache4 = &Private->OfferBuffer[Private->OfferNum].Dhcp4;\r
 \r
   ASSERT (Private->OfferNum < PXEBC_OFFER_MAX_NUM);\r
   Cache4 = &Private->OfferBuffer[Private->OfferNum].Dhcp4;\r
@@ -795,13 +829,16 @@ PxeBcCacheDhcp4Offer (
   //\r
   // Cache the content of DHCPv4 packet firstly.\r
   //\r
   //\r
   // Cache the content of DHCPv4 packet firstly.\r
   //\r
-  PxeBcCacheDhcp4Packet (Offer, RcvdOffer);\r
+  Status = PxeBcCacheDhcp4Packet (Offer, RcvdOffer);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Validate the DHCPv4 packet, and parse the options and offer type.\r
   //\r
   if (EFI_ERROR (PxeBcParseDhcp4Packet (Cache4))) {\r
 \r
   //\r
   // Validate the DHCPv4 packet, and parse the options and offer type.\r
   //\r
   if (EFI_ERROR (PxeBcParseDhcp4Packet (Cache4))) {\r
-    return;\r
+    return EFI_ABORTED;\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r
@@ -818,7 +855,7 @@ PxeBcCacheDhcp4Offer (
       Private->OfferIndex[OfferType][0] = Private->OfferNum;\r
       Private->OfferCount[OfferType]    = 1;\r
     } else {\r
       Private->OfferIndex[OfferType][0] = Private->OfferNum;\r
       Private->OfferCount[OfferType]    = 1;\r
     } else {\r
-      return;\r
+      return EFI_ABORTED;\r
     }\r
   } else {\r
     ASSERT (Private->OfferCount[OfferType] < PXEBC_OFFER_MAX_NUM);\r
     }\r
   } else {\r
     ASSERT (Private->OfferCount[OfferType] < PXEBC_OFFER_MAX_NUM);\r
@@ -834,14 +871,15 @@ PxeBcCacheDhcp4Offer (
         //\r
         Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;\r
         Private->OfferCount[OfferType]++;\r
         //\r
         Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;\r
         Private->OfferCount[OfferType]++;\r
-      } else if (Private->OfferCount[OfferType] > 0) {\r
+      } else if ((OfferType == PxeOfferTypeProxyPxe10 || OfferType == PxeOfferTypeProxyWfm11a) && \r
+                 Private->OfferCount[OfferType] < 1) {\r
         //\r
         // Only cache the first PXE10/WFM11a offer, and discard the others.\r
         //\r
         Private->OfferIndex[OfferType][0] = Private->OfferNum;\r
         Private->OfferCount[OfferType]    = 1;\r
       } else {\r
         //\r
         // Only cache the first PXE10/WFM11a offer, and discard the others.\r
         //\r
         Private->OfferIndex[OfferType][0] = Private->OfferNum;\r
         Private->OfferCount[OfferType]    = 1;\r
       } else {\r
-        return ;\r
+        return EFI_ABORTED;\r
       }\r
     } else {\r
       //\r
       }\r
     } else {\r
       //\r
@@ -853,6 +891,8 @@ PxeBcCacheDhcp4Offer (
   }\r
 \r
   Private->OfferNum++;\r
   }\r
 \r
   Private->OfferNum++;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 }\r
 \r
 \r
@@ -977,11 +1017,12 @@ PxeBcSelectDhcp4Offer (
 /**\r
   Handle the DHCPv4 offer packet.\r
 \r
 /**\r
   Handle the DHCPv4 offer packet.\r
 \r
-  @param[in]  Private             Pointer to PxeBc private data.\r
+  @param[in]  Private               Pointer to PxeBc private data.\r
 \r
 \r
-  @retval     EFI_SUCCESS         Handled the DHCPv4 offer packet successfully.\r
-  @retval     EFI_NO_RESPONSE     No response to the following request packet.\r
-  @retval     EFI_NOT_FOUND       No boot filename received.\r
+  @retval     EFI_SUCCESS           Handled the DHCPv4 offer packet successfully.\r
+  @retval     EFI_NO_RESPONSE       No response to the following request packet.\r
+  @retval     EFI_NOT_FOUND         No boot filename received.\r
+  @retval     EFI_BUFFER_TOO_SMALL  Can't cache the offer pacet.\r
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1086,7 +1127,7 @@ PxeBcHandleDhcp4Offer (
         //\r
         // Success to try to request by a ProxyPxe10 or ProxyWfm11a offer, copy and parse it.\r
         //\r
         //\r
         // Success to try to request by a ProxyPxe10 or ProxyWfm11a offer, copy and parse it.\r
         //\r
-        PxeBcCopyProxyOffer (Private, ProxyIndex);\r
+        Status = PxeBcCopyProxyOffer (Private, ProxyIndex);\r
       }\r
     } else {\r
       //\r
       }\r
     } else {\r
       //\r
@@ -1113,7 +1154,10 @@ PxeBcHandleDhcp4Offer (
       Ack = Offer;\r
     }\r
 \r
       Ack = Offer;\r
     }\r
 \r
-    PxeBcCopyDhcp4Ack (Private, Ack, TRUE);\r
+    Status = PxeBcCopyDhcp4Ack (Private, Ack, TRUE);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
     Mode->DhcpDiscoverValid = TRUE;\r
   }\r
 \r
     Mode->DhcpDiscoverValid = TRUE;\r
   }\r
 \r
@@ -1167,6 +1211,8 @@ PxeBcDhcp4CallBack (
     return EFI_SUCCESS;\r
   }\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
+  ASSERT (Packet != NULL);\r
+\r
   Private   = (PXEBC_PRIVATE_DATA *) Context;\r
   Mode      = Private->PxeBc.Mode;\r
   Callback  = Private->PxeBcCallback;\r
   Private   = (PXEBC_PRIVATE_DATA *) Context;\r
   Mode      = Private->PxeBc.Mode;\r
   Callback  = Private->PxeBcCallback;\r
@@ -1177,10 +1223,10 @@ PxeBcDhcp4CallBack (
   MaxMsgSize = PxeBcParseDhcp4Options (\r
                  Packet->Dhcp4.Option,\r
                  GET_OPTION_BUFFER_LEN (Packet),\r
   MaxMsgSize = PxeBcParseDhcp4Options (\r
                  Packet->Dhcp4.Option,\r
                  GET_OPTION_BUFFER_LEN (Packet),\r
-                 PXEBC_DHCP4_TAG_MAXMSG\r
+                 DHCP4_TAG_MAXMSG\r
                  );\r
   if (MaxMsgSize != NULL) {\r
                  );\r
   if (MaxMsgSize != NULL) {\r
-    Value = HTONS (PXEBC_DHCP4_PACKET_MAX_SIZE - 8);\r
+    Value = HTONS (PXEBC_DHCP4_PACKET_MAX_SIZE);\r
     CopyMem (MaxMsgSize->Data, &Value, sizeof (Value));\r
   }\r
 \r
     CopyMem (MaxMsgSize->Data, &Value, sizeof (Value));\r
   }\r
 \r
@@ -1206,6 +1252,14 @@ PxeBcDhcp4CallBack (
   switch (Dhcp4Event) {\r
 \r
   case Dhcp4SendDiscover:\r
   switch (Dhcp4Event) {\r
 \r
   case Dhcp4SendDiscover:\r
+    if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {\r
+      //\r
+      // If the to be sent packet exceeds the maximum length, abort the DHCP process.\r
+      //\r
+      Status = EFI_ABORTED;\r
+      break;\r
+    }\r
+\r
     //\r
     // Cache the DHCPv4 discover packet to mode data directly.\r
     // It need to check SendGuid as well as Dhcp4SendRequest.\r
     //\r
     // Cache the DHCPv4 discover packet to mode data directly.\r
     // It need to check SendGuid as well as Dhcp4SendRequest.\r
@@ -1213,6 +1267,14 @@ PxeBcDhcp4CallBack (
     CopyMem (&Mode->DhcpDiscover.Dhcpv4, &Packet->Dhcp4, Packet->Length);\r
 \r
   case Dhcp4SendRequest:\r
     CopyMem (&Mode->DhcpDiscover.Dhcpv4, &Packet->Dhcp4, Packet->Length);\r
 \r
   case Dhcp4SendRequest:\r
+    if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {\r
+      //\r
+      // If the to be sent packet exceeds the maximum length, abort the DHCP process.\r
+      //\r
+      Status = EFI_ABORTED;\r
+      break;\r
+    }\r
+    \r
     if (Mode->SendGUID) {\r
       //\r
       // Send the system Guid instead of the MAC address as the hardware address if required.\r
     if (Mode->SendGUID) {\r
       //\r
       // Send the system Guid instead of the MAC address as the hardware address if required.\r
@@ -1221,6 +1283,7 @@ PxeBcDhcp4CallBack (
         //\r
         // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
         //\r
         //\r
         // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
         //\r
+        DEBUG ((EFI_D_WARN, "PXE: Failed to read system GUID from the smbios table!\n"));\r
         ZeroMem (Packet->Dhcp4.Header.ClientHwAddr, sizeof (EFI_GUID));\r
       }\r
       Packet->Dhcp4.Header.HwAddrLen = (UINT8) sizeof (EFI_GUID);\r
         ZeroMem (Packet->Dhcp4.Header.ClientHwAddr, sizeof (EFI_GUID));\r
       }\r
       Packet->Dhcp4.Header.HwAddrLen = (UINT8) sizeof (EFI_GUID);\r
@@ -1229,16 +1292,25 @@ PxeBcDhcp4CallBack (
 \r
   case Dhcp4RcvdOffer:\r
     Status = EFI_NOT_READY;\r
 \r
   case Dhcp4RcvdOffer:\r
     Status = EFI_NOT_READY;\r
+    if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {\r
+      //\r
+      // Ignore the incoming packets which exceed the maximum length.\r
+      //\r
+      break;\r
+    }\r
     if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) {\r
       //\r
       // Cache the DHCPv4 offers to OfferBuffer[] for select later, and record\r
       // the OfferIndex and OfferCount.\r
     if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) {\r
       //\r
       // Cache the DHCPv4 offers to OfferBuffer[] for select later, and record\r
       // the OfferIndex and OfferCount.\r
+      // If error happens, just ignore this packet and continue to wait more offer.\r
       //\r
       PxeBcCacheDhcp4Offer (Private, Packet);\r
     }\r
     break;\r
 \r
   case Dhcp4SelectOffer:\r
       //\r
       PxeBcCacheDhcp4Offer (Private, Packet);\r
     }\r
     break;\r
 \r
   case Dhcp4SelectOffer:\r
+    ASSERT (NewPacket != NULL);\r
+    \r
     //\r
     // Select offer by the default policy or by order, and record the SelectIndex\r
     // and SelectProxyType.\r
     //\r
     // Select offer by the default policy or by order, and record the SelectIndex\r
     // and SelectProxyType.\r
@@ -1259,7 +1331,10 @@ PxeBcDhcp4CallBack (
     //\r
     ASSERT (Private->SelectIndex != 0);\r
 \r
     //\r
     ASSERT (Private->SelectIndex != 0);\r
 \r
-    PxeBcCopyDhcp4Ack (Private, Packet, FALSE);\r
+    Status = PxeBcCopyDhcp4Ack (Private, Packet, FALSE);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_ABORTED;\r
+    }\r
     break;\r
 \r
   default:\r
     break;\r
 \r
   default:\r
@@ -1353,14 +1428,14 @@ PxeBcDhcp4Discover (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    OptList[OptCount]->OpCode     = PXEBC_DHCP4_TAG_VENDOR;\r
+    OptList[OptCount]->OpCode     = DHCP4_TAG_VENDOR;\r
     OptList[OptCount]->Length     = (UINT8) (VendorOptLen - 2);\r
     PxeOpt                        = (EFI_DHCP4_PACKET_OPTION *) OptList[OptCount]->Data;\r
     PxeOpt->OpCode                = PXEBC_VENDOR_TAG_BOOT_ITEM;\r
     PxeOpt->Length                = (UINT8) sizeof (PXEBC_OPTION_BOOT_ITEM);\r
     PxeBootItem                   = (PXEBC_OPTION_BOOT_ITEM *) PxeOpt->Data;\r
     PxeBootItem->Type             = HTONS (Type);\r
     OptList[OptCount]->Length     = (UINT8) (VendorOptLen - 2);\r
     PxeOpt                        = (EFI_DHCP4_PACKET_OPTION *) OptList[OptCount]->Data;\r
     PxeOpt->OpCode                = PXEBC_VENDOR_TAG_BOOT_ITEM;\r
     PxeOpt->Length                = (UINT8) sizeof (PXEBC_OPTION_BOOT_ITEM);\r
     PxeBootItem                   = (PXEBC_OPTION_BOOT_ITEM *) PxeOpt->Data;\r
     PxeBootItem->Type             = HTONS (Type);\r
-    PxeOpt->Data[PxeOpt->Length]  = PXEBC_DHCP4_TAG_EOP;\r
+    PxeOpt->Data[PxeOpt->Length]  = DHCP4_TAG_EOP;\r
 \r
     if (Layer != NULL) {\r
       PxeBootItem->Layer          = HTONS (*Layer);\r
 \r
     if (Layer != NULL) {\r
       PxeBootItem->Layer          = HTONS (*Layer);\r
@@ -1397,6 +1472,7 @@ PxeBcDhcp4Discover (
       //\r
       // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
       //\r
       //\r
       // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
       //\r
+      DEBUG ((EFI_D_WARN, "PXE: Failed to read system GUID from the smbios table!\n"));\r
       ZeroMem (Token.Packet->Dhcp4.Header.ClientHwAddr, sizeof (EFI_GUID));\r
     }\r
     Token.Packet->Dhcp4.Header.HwAddrLen = (UINT8)  sizeof (EFI_GUID);\r
       ZeroMem (Token.Packet->Dhcp4.Header.ClientHwAddr, sizeof (EFI_GUID));\r
     }\r
     Token.Packet->Dhcp4.Header.HwAddrLen = (UINT8)  sizeof (EFI_GUID);\r
@@ -1458,6 +1534,12 @@ PxeBcDhcp4Discover (
     // Find the right PXE Reply according to server address.\r
     //\r
     while (RepIndex < Token.ResponseCount) {\r
     // Find the right PXE Reply according to server address.\r
     //\r
     while (RepIndex < Token.ResponseCount) {\r
+      if (Response->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) {\r
+        SrvIndex = 0;\r
+        RepIndex++;\r
+        Response = (EFI_DHCP4_PACKET *) ((UINT8 *) Response + Response->Size);\r
+        continue;\r
+      }\r
 \r
       while (SrvIndex < IpCount) {\r
         if (SrvList[SrvIndex].AcceptAnyResponse) {\r
 \r
       while (SrvIndex < IpCount) {\r
         if (SrvList[SrvIndex].AcceptAnyResponse) {\r
@@ -1476,7 +1558,6 @@ PxeBcDhcp4Discover (
 \r
       SrvIndex = 0;\r
       RepIndex++;\r
 \r
       SrvIndex = 0;\r
       RepIndex++;\r
-\r
       Response = (EFI_DHCP4_PACKET *) ((UINT8 *) Response + Response->Size);\r
     }\r
 \r
       Response = (EFI_DHCP4_PACKET *) ((UINT8 *) Response + Response->Size);\r
     }\r
 \r
@@ -1486,10 +1567,16 @@ PxeBcDhcp4Discover (
       // Especially for PXE discover packet, store it into mode data here.\r
       //\r
       if (Private->IsDoDiscover) {\r
       // Especially for PXE discover packet, store it into mode data here.\r
       //\r
       if (Private->IsDoDiscover) {\r
-        PxeBcCacheDhcp4Packet (&Private->PxeReply.Dhcp4.Packet.Ack, Response);\r
+        Status = PxeBcCacheDhcp4Packet (&Private->PxeReply.Dhcp4.Packet.Ack, Response);\r
+        if (EFI_ERROR(Status)) {\r
+          goto ON_EXIT;\r
+        }\r
         CopyMem (&Mode->PxeDiscover, &Token.Packet->Dhcp4, Token.Packet->Length);\r
       } else {\r
         CopyMem (&Mode->PxeDiscover, &Token.Packet->Dhcp4, Token.Packet->Length);\r
       } else {\r
-        PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Response);\r
+        Status = PxeBcCacheDhcp4Packet (&Private->ProxyOffer.Dhcp4.Packet.Offer, Response);\r
+        if (EFI_ERROR(Status)) {\r
+          goto ON_EXIT;\r
+        }\r
       }\r
     } else {\r
       //\r
       }\r
     } else {\r
       //\r
@@ -1497,12 +1584,15 @@ PxeBcDhcp4Discover (
       //\r
       Status = EFI_NOT_FOUND;\r
     }\r
       //\r
       Status = EFI_NOT_FOUND;\r
     }\r
-    if (Token.ResponseList != NULL) {\r
-      FreePool (Token.ResponseList);\r
-    }\r
   }\r
   }\r
-\r
-  FreePool (Token.Packet);\r
+ON_EXIT:\r
+  \r
+  if (Token.ResponseList != NULL) {\r
+    FreePool (Token.ResponseList);\r
+  }\r
+  if (Token.Packet != NULL) {\r
+    FreePool (Token.Packet);\r
+  }\r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
 \r
@@ -1614,16 +1704,16 @@ PxeBcDhcp4Dora (
   ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));\r
   ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));\r
 \r
   ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));\r
   ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));\r
 \r
-  //\r
-  // Start DHCPv4 D.O.R.A. process to acquire IPv4 address. This may \r
-  // have already been done, thus do not leave in error if the return\r
-  // code is EFI_ALREADY_STARTED.\r
-  //\r
   Status = Dhcp4->Start (Dhcp4, NULL);\r
   Status = Dhcp4->Start (Dhcp4, NULL);\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+  if (EFI_ERROR (Status)) {\r
     if (Status == EFI_ICMP_ERROR) {\r
       PxeMode->IcmpErrorReceived = TRUE;\r
     }\r
     if (Status == EFI_ICMP_ERROR) {\r
       PxeMode->IcmpErrorReceived = TRUE;\r
     }\r
+\r
+    if (Status == EFI_TIMEOUT && Private->OfferNum > 0) {\r
+      Status = EFI_NO_RESPONSE;\r
+    }\r
+    \r
     goto ON_EXIT;\r
   }\r
 \r
     goto ON_EXIT;\r
   }\r
 \r