]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpBootDxe/HttpBootDhcp4.c
NetworkPkg/HttpBootDxe: fix typo in DHCPv4 packet parsing
[mirror_edk2.git] / NetworkPkg / HttpBootDxe / HttpBootDhcp4.c
index a47a8f494f9ec1cf8c4f0678dddfb429a49a2a07..229e6cb0ec6a73791a9c25a55ff30cb90caf31fc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Functions implementation related with DHCPv4 for HTTP boot driver.\r
 \r
-Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2017, 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
@@ -220,17 +220,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
@@ -325,8 +332,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
@@ -415,6 +422,9 @@ 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
@@ -429,8 +439,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 +451,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 +460,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 +481,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
@@ -594,8 +612,13 @@ 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
@@ -613,15 +636,39 @@ HttpBootDhcp4CallBack (
     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