]> 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
-  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
 // 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
@@ -58,7 +58,7 @@ PxeBcParseDhcp4Options (
   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
@@ -70,7 +70,7 @@ PxeBcParseDhcp4Options (
     //\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
@@ -108,7 +108,7 @@ PxeBcParseVendorOptions (
 \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
@@ -201,7 +201,7 @@ PxeBcParseVendorOptions (
     //\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
@@ -243,7 +243,7 @@ PxeBcBuildDhcp4Options (
     //\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
@@ -253,10 +253,10 @@ PxeBcBuildDhcp4Options (
     //\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
-    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
@@ -265,36 +265,36 @@ PxeBcBuildDhcp4Options (
   //\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
-  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
@@ -309,7 +309,7 @@ PxeBcBuildDhcp4Options (
   //\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
@@ -320,13 +320,14 @@ PxeBcBuildDhcp4Options (
     //\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
-  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
@@ -346,7 +347,7 @@ PxeBcBuildDhcp4Options (
   //\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
@@ -357,7 +358,7 @@ PxeBcBuildDhcp4Options (
   //\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
@@ -414,7 +415,7 @@ PxeBcSeedDhcp4Packet (
   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
@@ -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
+  @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
-VOID\r
+EFI_STATUS\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
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
@@ -460,9 +468,11 @@ PxeBcParseDhcp4Packet (
   BOOLEAN                        IsProxyOffer;\r
   BOOLEAN                        IsPxeOffer;\r
   UINT8                          *Ptr8;\r
+  BOOLEAN                        FileFieldOverloaded;\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
@@ -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
+      FileFieldOverloaded = TRUE;\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
-  } 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
@@ -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
+  @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
-VOID\r
+EFI_STATUS\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
+  EFI_STATUS              Status;\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
@@ -639,6 +657,8 @@ PxeBcCopyDhcp4Ack (
     CopyMem (&Mode->DhcpAck.Dhcpv4, &Ack->Dhcp4, Ack->Length);\r
     Mode->DhcpAckReceived = TRUE;\r
   }\r
+  \r
+  return EFI_SUCCESS;\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
+  @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
-VOID\r
+EFI_STATUS\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
+  EFI_STATUS              Status;\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
-  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
@@ -675,6 +703,8 @@ PxeBcCopyProxyOffer (
   //\r
   CopyMem (&Mode->ProxyOffer.Dhcpv4, &Offer->Dhcp4, Offer->Length);\r
   Mode->ProxyOfferReceived = TRUE;\r
+\r
+  return EFI_SUCCESS;\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
+  @retval     EFI_SUCCESS      Cache and parse the packet successfully.\r
+  @retval     Others           Operation failed.\r
+\r
 **/\r
-VOID\r
+EFI_STATUS\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
+  EFI_STATUS                Status;\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
-  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
-    return;\r
+    return EFI_ABORTED;\r
   }\r
 \r
   //\r
@@ -818,7 +855,7 @@ PxeBcCacheDhcp4Offer (
       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
@@ -834,14 +871,15 @@ PxeBcCacheDhcp4Offer (
         //\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
-        return ;\r
+        return EFI_ABORTED;\r
       }\r
     } else {\r
       //\r
@@ -853,6 +891,8 @@ PxeBcCacheDhcp4Offer (
   }\r
 \r
   Private->OfferNum++;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
@@ -977,11 +1017,12 @@ PxeBcSelectDhcp4Offer (
 /**\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
-  @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
@@ -1086,7 +1127,7 @@ PxeBcHandleDhcp4Offer (
         //\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
@@ -1113,7 +1154,10 @@ PxeBcHandleDhcp4Offer (
       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
@@ -1167,6 +1211,8 @@ PxeBcDhcp4CallBack (
     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
@@ -1177,10 +1223,10 @@ PxeBcDhcp4CallBack (
   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
-    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
@@ -1206,6 +1252,14 @@ PxeBcDhcp4CallBack (
   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
@@ -1213,6 +1267,14 @@ PxeBcDhcp4CallBack (
     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
@@ -1221,6 +1283,7 @@ PxeBcDhcp4CallBack (
         //\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
@@ -1229,16 +1292,25 @@ PxeBcDhcp4CallBack (
 \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 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
+    ASSERT (NewPacket != NULL);\r
+    \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
-    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
@@ -1353,14 +1428,14 @@ PxeBcDhcp4Discover (
       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
-    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
@@ -1397,6 +1472,7 @@ PxeBcDhcp4Discover (
       //\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
@@ -1458,6 +1534,12 @@ PxeBcDhcp4Discover (
     // 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
@@ -1476,7 +1558,6 @@ PxeBcDhcp4Discover (
 \r
       SrvIndex = 0;\r
       RepIndex++;\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
-        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
-        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
@@ -1497,12 +1584,15 @@ PxeBcDhcp4Discover (
       //\r
       Status = EFI_NOT_FOUND;\r
     }\r
-    if (Token.ResponseList != NULL) {\r
-      FreePool (Token.ResponseList);\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
@@ -1614,16 +1704,16 @@ PxeBcDhcp4Dora (
   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
-  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
+\r
+    if (Status == EFI_TIMEOUT && Private->OfferNum > 0) {\r
+      Status = EFI_NO_RESPONSE;\r
+    }\r
+    \r
     goto ON_EXIT;\r
   }\r
 \r