]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpBootDxe/HttpBootDhcp4.c
NetworkPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / NetworkPkg / HttpBootDxe / HttpBootDhcp4.c
index 5a226d7f7600b320ece641b859e1e4ee26bfafb7..b5dd6e09567aaa00ede203ba4db006123cd553cb 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   Functions implementation related with DHCPv4 for HTTP boot driver.\r
 \r
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials are licensed and made available under \r
-the terms and conditions of the BSD License that accompanies this distribution.  \r
-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
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -18,13 +12,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 // This is a map from the interested DHCP4 option tags' index to the tag value.\r
 //\r
 UINT8 mInterestedDhcp4Tags[HTTP_BOOT_DHCP4_TAG_INDEX_MAX] = {\r
-  HTTP_BOOT_DHCP4_TAG_BOOTFILE_LEN,\r
-  HTTP_BOOT_DHCP4_TAG_OVERLOAD,\r
-  HTTP_BOOT_DHCP4_TAG_MSG_TYPE,\r
-  HTTP_BOOT_DHCP4_TAG_SERVER_ID,\r
-  HTTP_BOOT_DHCP4_TAG_CLASS_ID,\r
-  HTTP_BOOT_DHCP4_TAG_BOOTFILE,\r
-  HTTP_BOOT_DHCP4_TAG_DNS_SERVER\r
+  DHCP4_TAG_BOOTFILE_LEN,\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
+  DHCP4_TAG_DNS_SERVER\r
 };\r
 \r
 //\r
@@ -59,42 +53,42 @@ HttpBootBuildDhcp4Options (
   //\r
   // Append parameter request list option.\r
   //\r
-  OptList[Index]->OpCode    = HTTP_BOOT_DHCP4_TAG_PARA_LIST;\r
+  OptList[Index]->OpCode    = DHCP4_TAG_PARA_LIST;\r
   OptList[Index]->Length    = 27;\r
   OptEnt.Para               = (HTTP_BOOT_DHCP4_OPTION_PARA *) OptList[Index]->Data;\r
-  OptEnt.Para->ParaList[0]  = HTTP_BOOT_DHCP4_TAG_NETMASK;\r
-  OptEnt.Para->ParaList[1]  = HTTP_BOOT_DHCP4_TAG_TIME_OFFSET;\r
-  OptEnt.Para->ParaList[2]  = HTTP_BOOT_DHCP4_TAG_ROUTER;\r
-  OptEnt.Para->ParaList[3]  = HTTP_BOOT_DHCP4_TAG_TIME_SERVER;\r
-  OptEnt.Para->ParaList[4]  = HTTP_BOOT_DHCP4_TAG_NAME_SERVER;\r
-  OptEnt.Para->ParaList[5]  = HTTP_BOOT_DHCP4_TAG_DNS_SERVER;\r
-  OptEnt.Para->ParaList[6]  = HTTP_BOOT_DHCP4_TAG_HOSTNAME;\r
-  OptEnt.Para->ParaList[7]  = HTTP_BOOT_DHCP4_TAG_BOOTFILE_LEN;\r
-  OptEnt.Para->ParaList[8]  = HTTP_BOOT_DHCP4_TAG_DOMAINNAME;\r
-  OptEnt.Para->ParaList[9]  = HTTP_BOOT_DHCP4_TAG_ROOTPATH;\r
-  OptEnt.Para->ParaList[10] = HTTP_BOOT_DHCP4_TAG_EXTEND_PATH;\r
-  OptEnt.Para->ParaList[11] = HTTP_BOOT_DHCP4_TAG_EMTU;\r
-  OptEnt.Para->ParaList[12] = HTTP_BOOT_DHCP4_TAG_TTL;\r
-  OptEnt.Para->ParaList[13] = HTTP_BOOT_DHCP4_TAG_BROADCAST;\r
-  OptEnt.Para->ParaList[14] = HTTP_BOOT_DHCP4_TAG_NIS_DOMAIN;\r
-  OptEnt.Para->ParaList[15] = HTTP_BOOT_DHCP4_TAG_NIS_SERVER;\r
-  OptEnt.Para->ParaList[16] = HTTP_BOOT_DHCP4_TAG_NTP_SERVER;\r
-  OptEnt.Para->ParaList[17] = HTTP_BOOT_DHCP4_TAG_VENDOR;\r
-  OptEnt.Para->ParaList[18] = HTTP_BOOT_DHCP4_TAG_REQUEST_IP;\r
-  OptEnt.Para->ParaList[19] = HTTP_BOOT_DHCP4_TAG_LEASE;\r
-  OptEnt.Para->ParaList[20] = HTTP_BOOT_DHCP4_TAG_SERVER_ID;\r
-  OptEnt.Para->ParaList[21] = HTTP_BOOT_DHCP4_TAG_T1;\r
-  OptEnt.Para->ParaList[22] = HTTP_BOOT_DHCP4_TAG_T2;\r
-  OptEnt.Para->ParaList[23] = HTTP_BOOT_DHCP4_TAG_CLASS_ID;\r
-  OptEnt.Para->ParaList[25] = HTTP_BOOT_DHCP4_TAG_BOOTFILE;\r
-  OptEnt.Para->ParaList[26] = HTTP_BOOT_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[25] = DHCP4_TAG_BOOTFILE;\r
+  OptEnt.Para->ParaList[26] = DHCP4_TAG_UUID;\r
   Index++;\r
   OptList[Index]            = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);\r
 \r
   //\r
   // Append UUID/Guid-based client identifier option\r
   //\r
-  OptList[Index]->OpCode  = HTTP_BOOT_DHCP4_TAG_UUID;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_UUID;\r
   OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_UUID);\r
   OptEnt.Uuid             = (HTTP_BOOT_DHCP4_OPTION_UUID *) OptList[Index]->Data;\r
   OptEnt.Uuid->Type       = 0;\r
@@ -110,7 +104,7 @@ HttpBootBuildDhcp4Options (
   //\r
   // Append client network device interface option\r
   //\r
-  OptList[Index]->OpCode  = HTTP_BOOT_DHCP4_TAG_UNDI;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_UNDI;\r
   OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_UNDI);\r
   OptEnt.Undi             = (HTTP_BOOT_DHCP4_OPTION_UNDI *) OptList[Index]->Data;\r
 \r
@@ -130,7 +124,7 @@ HttpBootBuildDhcp4Options (
   //\r
   // Append client system architecture option\r
   //\r
-  OptList[Index]->OpCode  = HTTP_BOOT_DHCP4_TAG_ARCH;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_ARCH;\r
   OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_ARCH);\r
   OptEnt.Arch             = (HTTP_BOOT_DHCP4_OPTION_ARCH *) OptList[Index]->Data;\r
   Value                   = HTONS (EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE);\r
@@ -141,7 +135,7 @@ HttpBootBuildDhcp4Options (
   //\r
   // Append vendor class identify option\r
   //\r
-  OptList[Index]->OpCode  = HTTP_BOOT_DHCP4_TAG_CLASS_ID;\r
+  OptList[Index]->OpCode  = DHCP4_TAG_VENDOR_CLASS_ID;\r
   OptList[Index]->Length  = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_CLID);\r
   OptEnt.Clid             = (HTTP_BOOT_DHCP4_OPTION_CLID *) OptList[Index]->Data;\r
   CopyMem (\r
@@ -190,7 +184,7 @@ HttpBootParseDhcp4Options (
   Option  = (EFI_DHCP4_PACKET_OPTION *) Buffer;\r
   Offset  = 0;\r
 \r
-  while (Offset < Length && Option->OpCode != HTTP_BOOT_DHCP4_TAG_EOP) {\r
+  while (Offset < Length && Option->OpCode != DHCP4_TAG_EOP) {\r
 \r
     if (Option->OpCode == OptTag) {\r
       //\r
@@ -202,7 +196,7 @@ HttpBootParseDhcp4Options (
     //\r
     // Skip the current option to the next.\r
     //\r
-    if (Option->OpCode == HTTP_BOOT_DHCP4_TAG_PAD) {\r
+    if (Option->OpCode == DHCP4_TAG_PAD) {\r
       Offset++;\r
     } else {\r
       Offset += Option->Length + 2;\r
@@ -220,17 +214,24 @@ HttpBootParseDhcp4Options (
   @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
 HttpBootCacheDhcp4Packet (\r
   IN EFI_DHCP4_PACKET     *Dst,\r
   IN EFI_DHCP4_PACKET     *Src\r
   )\r
 {\r
-  ASSERT (Dst->Size >= Src->Length);\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
@@ -260,7 +261,7 @@ HttpBootParseDhcp4Packet (
   HTTP_BOOT_OFFER_TYPE           OfferType;\r
   EFI_IPv4_ADDRESS               IpAddr;\r
   BOOLEAN                        FileFieldOverloaded;\r
-  \r
+\r
   IsDnsOffer     = FALSE;\r
   IpExpressedUri = FALSE;\r
   IsProxyOffer   = FALSE;\r
@@ -284,7 +285,7 @@ HttpBootParseDhcp4Packet (
                        );\r
   }\r
   //\r
-  // Second, Check if bootfilename and serverhostname is overloaded to carry DHCP options refers to rfc-2132. \r
+  // Second, Check if bootfilename and serverhostname is overloaded to carry DHCP options refers to rfc-2132.\r
   // If yes, try to parse options from the BootFileName field, then ServerName field.\r
   //\r
   Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_OVERLOAD];\r
@@ -325,8 +326,8 @@ HttpBootParseDhcp4Packet (
   // The offer with "HTTPClient" is a Http offer.\r
   //\r
   Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_CLASS_ID];\r
-  if ((Option != NULL) && (Option->Length >= 9) &&\r
-      (CompareMem (Option->Data, DEFAULT_CLASS_ID_DATA, 9) == 0)) {\r
+  if ((Option != NULL) && (Option->Length >= 10) &&\r
+      (CompareMem (Option->Data, DEFAULT_CLASS_ID_DATA, 10) == 0)) {\r
     IsHttpOffer = TRUE;\r
   }\r
 \r
@@ -372,7 +373,7 @@ HttpBootParseDhcp4Packet (
   }\r
 \r
   //\r
-  // Try to retrieve the IP of HTTP server from URI. \r
+  // Try to retrieve the IP of HTTP server from URI.\r
   //\r
   if (IsHttpOffer) {\r
     Status = HttpParseUrl (\r
@@ -415,10 +416,13 @@ HttpBootParseDhcp4Packet (
     if (!IsProxyOffer) {\r
       OfferType = IsDnsOffer ? HttpOfferTypeDhcpDns : HttpOfferTypeDhcpOnly;\r
     } else {\r
+      if (Cache4->UriParser != NULL) {\r
+        FreePool (Cache4->UriParser);\r
+      }\r
       return EFI_DEVICE_ERROR;\r
     }\r
   }\r
-  \r
+\r
   Cache4->OfferType = OfferType;\r
   return EFI_SUCCESS;\r
 }\r
@@ -429,8 +433,10 @@ HttpBootParseDhcp4Packet (
   @param[in]  Private               Pointer to HTTP boot driver 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
-VOID\r
+EFI_STATUS\r
 HttpBootCacheDhcp4Offer (\r
   IN HTTP_BOOT_PRIVATE_DATA  *Private,\r
   IN EFI_DHCP4_PACKET        *RcvdOffer\r
@@ -439,6 +445,7 @@ HttpBootCacheDhcp4Offer (
   HTTP_BOOT_DHCP4_PACKET_CACHE  *Cache4;\r
   EFI_DHCP4_PACKET              *Offer;\r
   HTTP_BOOT_OFFER_TYPE          OfferType;\r
+  EFI_STATUS                    Status;\r
 \r
   ASSERT (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM);\r
   Cache4 = &Private->OfferBuffer[Private->OfferNum].Dhcp4;\r
@@ -447,13 +454,16 @@ HttpBootCacheDhcp4Offer (
   //\r
   // Cache the content of DHCPv4 packet firstly.\r
   //\r
-  HttpBootCacheDhcp4Packet (Offer, RcvdOffer);\r
+  Status = HttpBootCacheDhcp4Packet (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 (HttpBootParseDhcp4Packet (Cache4))) {\r
-    return;\r
+    return EFI_ABORTED;\r
   }\r
 \r
   //\r
@@ -465,6 +475,8 @@ HttpBootCacheDhcp4Offer (
   Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;\r
   Private->OfferCount[OfferType]++;\r
   Private->OfferNum++;\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -488,70 +500,70 @@ HttpBootSelectDhcpOffer (
     // The offer with DNS server address takes priority here.\r
     //\r
     if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0) {\r
-      \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;\r
-      \r
+\r
     } else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {\r
-    \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;\r
-      \r
+\r
     } else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {\r
-    \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;\r
-      \r
+\r
     }  else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0) {\r
-    \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;\r
-      \r
+\r
     }  else if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {\r
-    \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;\r
     }\r
-    \r
+\r
   } else {\r
     //\r
     // We are in corporate environment.\r
     //\r
     // Priority1: HttpOfferTypeDhcpIpUri or HttpOfferTypeDhcpIpUriDns\r
-    // Priority2: HttpOfferTypeDhcpNameUriDns                      \r
-    // Priority3: HttpOfferTypeDhcpOnly + HttpOfferTypeProxyIpUri  \r
-    // Priority4: HttpOfferTypeDhcpDns  + HttpOfferTypeProxyIpUri  \r
+    // Priority2: HttpOfferTypeDhcpNameUriDns\r
+    // Priority3: HttpOfferTypeDhcpOnly + HttpOfferTypeProxyIpUri\r
+    // Priority4: HttpOfferTypeDhcpDns  + HttpOfferTypeProxyIpUri\r
     // Priority5: HttpOfferTypeDhcpDns  + HttpOfferTypeProxyNameUri\r
-    // Priority6: HttpOfferTypeDhcpDns  + HttpOfferTypeDhcpNameUri \r
-    //    \r
+    // Priority6: HttpOfferTypeDhcpDns  + HttpOfferTypeDhcpNameUri\r
+    //\r
     if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {\r
-      \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;\r
-      \r
+\r
     } else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {\r
-      \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;\r
-      \r
+\r
     }else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {\r
-    \r
+\r
       Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;\r
-      \r
+\r
     } else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0 &&\r
                Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {\r
-               \r
+\r
       Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;\r
       Private->SelectProxyType = HttpOfferTypeProxyIpUri;\r
-      \r
+\r
     } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&\r
                Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {\r
-               \r
+\r
       Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;\r
       Private->SelectProxyType = HttpOfferTypeProxyIpUri;\r
-      \r
+\r
     } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&\r
                Private->OfferCount[HttpOfferTypeProxyNameUri] > 0) {\r
-               \r
+\r
       Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;\r
       Private->SelectProxyType = HttpOfferTypeProxyNameUri;\r
-      \r
+\r
     } else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&\r
                Private->OfferCount[HttpOfferTypeDhcpNameUri] > 0) {\r
-               \r
+\r
       Private->SelectIndex     = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;\r
       Private->SelectProxyType = HttpOfferTypeDhcpNameUri;\r
     }\r
@@ -594,11 +606,16 @@ HttpBootDhcp4CallBack (
   EFI_DHCP4_PACKET_OPTION              *MaxMsgSize;\r
   UINT16                               Value;\r
   EFI_STATUS                           Status;\r
+  BOOLEAN                              Received;\r
 \r
-  if ((Dhcp4Event != Dhcp4RcvdOffer) && (Dhcp4Event != Dhcp4SelectOffer)) {\r
+  if ((Dhcp4Event != Dhcp4SendDiscover) &&\r
+      (Dhcp4Event != Dhcp4RcvdOffer) &&\r
+      (Dhcp4Event != Dhcp4SendRequest) &&\r
+      (Dhcp4Event != Dhcp4RcvdAck) &&\r
+      (Dhcp4Event != Dhcp4SelectOffer)) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   Private = (HTTP_BOOT_PRIVATE_DATA *) Context;\r
 \r
   //\r
@@ -607,21 +624,45 @@ HttpBootDhcp4CallBack (
   MaxMsgSize = HttpBootParseDhcp4Options (\r
                  Packet->Dhcp4.Option,\r
                  GET_OPTION_BUFFER_LEN (Packet),\r
-                 HTTP_BOOT_DHCP4_TAG_MAXMSG\r
+                 DHCP4_TAG_MAXMSG\r
                  );\r
   if (MaxMsgSize != NULL) {\r
     Value = HTONS (HTTP_BOOT_DHCP4_PACKET_MAX_SIZE);\r
     CopyMem (MaxMsgSize->Data, &Value, sizeof (Value));\r
   }\r
 \r
+  //\r
+  // Callback to user if any packets sent or received.\r
+  //\r
+  if (Private->HttpBootCallback != NULL && Dhcp4Event != Dhcp4SelectOffer) {\r
+    Received = (BOOLEAN) (Dhcp4Event == Dhcp4RcvdOffer || Dhcp4Event == Dhcp4RcvdAck);\r
+    Status = Private->HttpBootCallback->Callback (\r
+               Private->HttpBootCallback,\r
+               HttpBootDhcp4,\r
+               Received,\r
+               Packet->Length,\r
+               &Packet->Dhcp4\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_ABORTED;\r
+    }\r
+  }\r
+\r
   Status = EFI_SUCCESS;\r
   switch (Dhcp4Event) {\r
   case Dhcp4RcvdOffer:\r
     Status = EFI_NOT_READY;\r
+    if (Packet->Length > HTTP_BOOT_DHCP4_PACKET_MAX_SIZE) {\r
+      //\r
+      // Ignore the incoming packets which exceed the maximum length.\r
+      //\r
+      break;\r
+    }\r
     if (Private->OfferNum < HTTP_BOOT_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
       HttpBootCacheDhcp4Offer (Private, Packet);\r
     }\r
@@ -629,7 +670,7 @@ HttpBootDhcp4CallBack (
 \r
   case Dhcp4SelectOffer:\r
     //\r
-    // Select offer according to the priority in UEFI spec, and record the SelectIndex \r
+    // Select offer according to the priority in UEFI spec, and record the SelectIndex\r
     // and SelectProxyType.\r
     //\r
     HttpBootSelectDhcpOffer (Private);\r
@@ -640,7 +681,7 @@ HttpBootDhcp4CallBack (
       *NewPacket = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp4.Packet.Offer;\r
     }\r
     break;\r
-    \r
+\r
   default:\r
     break;\r
   }\r
@@ -650,7 +691,7 @@ HttpBootDhcp4CallBack (
 \r
 /**\r
   This function will register the IPv4 gateway address to the network device.\r
-  \r
+\r
   @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.\r
 \r
   @retval     EFI_SUCCESS         The new IP configuration has been configured successfully.\r
@@ -689,7 +730,7 @@ HttpBootRegisterIp4Gateway (
 \r
 /**\r
   This function will register the default DNS addresses to the network device.\r
-  \r
+\r
   @param[in]  Private             The pointer to HTTP_BOOT_PRIVATE_DATA.\r
   @param[in]  DataLength          Size of the buffer pointed to by DnsServerData in bytes.\r
   @param[in]  DnsServerData       Point a list of DNS server address in an array\r
@@ -707,11 +748,11 @@ HttpBootRegisterIp4Dns (
   )\r
 {\r
   EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2;\r
-  \r
+\r
   ASSERT (!Private->UsingIpv6);\r
 \r
   Ip4Config2 = Private->Ip4Config2;\r
-  \r
+\r
   return Ip4Config2->SetData (\r
                        Ip4Config2,\r
                        Ip4Config2DataTypeDnsServer,\r
@@ -763,7 +804,7 @@ HttpBootSetIp4Policy (
                           );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
-    } \r
+    }\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -790,7 +831,7 @@ HttpBootDhcp4Dora (
   EFI_DHCP4_CONFIG_DATA        Config;\r
   EFI_STATUS                   Status;\r
   EFI_DHCP4_MODE_DATA          Mode;\r
-  \r
+\r
   Dhcp4 = Private->Dhcp4;\r
   ASSERT (Dhcp4 != NULL);\r
 \r