]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c
1. Fix a bug to initialize the UdpRead instance in EfiPxeBcStart function.
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcImpl.c
index cd8eab3df904d65d4ee57a957d5c003ff12e1626..00f1e4d39515f8aaf6206e5a148b91ebe3dc6d14 100644 (file)
@@ -81,6 +81,17 @@ EfiPxeBcStart (
 \r
   if (Mode->UsingIpv6) {\r
     AsciiPrint ("\n>>Start PXE over IPv6");\r
+    //\r
+    // Configure udp6 instance to receive data.\r
+    //\r
+    Status = Private->Udp6Read->Configure (\r
+                                  Private->Udp6Read,\r
+                                  &Private->Udp6CfgData\r
+                                  );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+    \r
     //\r
     // Configure block size for TFTP as a default value to handle all link layers.\r
     //\r
@@ -115,6 +126,17 @@ EfiPxeBcStart (
     }\r
   } else {\r
     AsciiPrint ("\n>>Start PXE over IPv4");\r
+    //\r
+    // Configure udp4 instance to receive data.\r
+    //\r
+    Status = Private->Udp4Read->Configure (\r
+                                  Private->Udp4Read,\r
+                                  &Private->Udp4CfgData\r
+                                  );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+    \r
     //\r
     // Configure block size for TFTP as a default value to handle all link layers.\r
     //\r
@@ -321,6 +343,8 @@ EfiPxeBcStop (
   gBS->CloseEvent (Private->UdpTimeOutEvent);\r
   Private->CurSrcPort   = 0;\r
   Private->BootFileSize = 0;\r
+  Private->SolicitTimes = 0;\r
+  Private->ElapsedTime  = 0;\r
 \r
   //\r
   // Reset the mode data.\r
@@ -386,6 +410,8 @@ EfiPxeBcDhcp (
   Mode->IcmpErrorReceived = FALSE;\r
   Private->Function       = EFI_PXE_BASE_CODE_FUNCTION_DHCP;\r
   Private->IsOfferSorted  = SortOffers;\r
+  Private->SolicitTimes   = 0;\r
+  Private->ElapsedTime    = 0;\r
 \r
   if (!Mode->Started) {\r
     return EFI_NOT_STARTED;\r
@@ -403,6 +429,10 @@ EfiPxeBcDhcp (
     //\r
     Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6);\r
 \r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
     //\r
     // Configure Udp6Read instance\r
     //\r
@@ -419,6 +449,10 @@ EfiPxeBcDhcp (
     //\r
     Status = PxeBcDhcp4Dora (Private, Private->Dhcp4);\r
 \r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
     //\r
     // Configure Udp4Read instance\r
     //\r
@@ -657,7 +691,9 @@ EfiPxeBcDiscover (
                );\r
   }\r
 \r
-  if (!EFI_ERROR (Status)) {\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;    \r
+  } else {\r
     //\r
     // Parse the cached PXE reply packet, and store it into mode data if valid.\r
     //\r
@@ -925,6 +961,10 @@ EfiPxeBcMtftp (
     Mode->IcmpErrorReceived = TRUE;\r
   }\r
 \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
   if (Mode->UsingIpv6) {\r
     Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);    \r
   } else {\r
@@ -1210,6 +1250,12 @@ EfiPxeBcUdpRead (
   BOOLEAN                     IsDone;\r
   BOOLEAN                     IsMatched;\r
   UINTN                       CopiedLen;\r
+  UINTN                       HeaderLen;\r
+  UINTN                       HeaderCopiedLen;\r
+  UINTN                       BufferCopiedLen;\r
+  UINT32                      FragmentLength;\r
+  UINTN                       FragmentIndex;\r
+  UINT8                       *FragmentBuffer;\r
 \r
   if (This == NULL || DestIp == NULL || DestPort == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1324,26 +1370,53 @@ EfiPxeBcUdpRead (
     //\r
     // Copy the rececived packet to user if matched by filter.\r
     //\r
-    CopiedLen = 0;\r
     if (Mode->UsingIpv6) {\r
       Udp6Rx = Udp6Token.Packet.RxData;\r
       ASSERT (Udp6Rx != NULL);\r
-      //\r
-      // Copy the header part of received data.\r
-      //\r
+\r
+      HeaderLen = 0;\r
       if (HeaderSize != NULL) {\r
-        CopiedLen   = MIN (*HeaderSize, Udp6Rx->DataLength);\r
-        *HeaderSize = CopiedLen;\r
-        CopyMem (HeaderPtr, Udp6Rx->FragmentTable[0].FragmentBuffer, *HeaderSize);\r
+        HeaderLen = MIN (*HeaderSize, Udp6Rx->DataLength);\r
       }\r
-      //\r
-      // Copy the other part of received data.\r
-      //\r
-      if (Udp6Rx->DataLength - CopiedLen > *BufferSize) {\r
+\r
+      if (Udp6Rx->DataLength - HeaderLen > *BufferSize) {\r
         Status = EFI_BUFFER_TOO_SMALL;\r
       } else {\r
-        *BufferSize = Udp6Rx->DataLength - CopiedLen;\r
-        CopyMem (BufferPtr, (UINT8 *) Udp6Rx->FragmentTable[0].FragmentBuffer + CopiedLen, *BufferSize);\r
+        *HeaderSize = HeaderLen;\r
+        *BufferSize = Udp6Rx->DataLength - HeaderLen;\r
+\r
+        HeaderCopiedLen = 0;\r
+        BufferCopiedLen = 0;\r
+        for (FragmentIndex = 0; FragmentIndex < Udp6Rx->FragmentCount; FragmentIndex++) {\r
+          FragmentLength = Udp6Rx->FragmentTable[FragmentIndex].FragmentLength;\r
+          FragmentBuffer = Udp6Rx->FragmentTable[FragmentIndex].FragmentBuffer;\r
+          if (HeaderCopiedLen + FragmentLength < HeaderLen) {\r
+            //\r
+            // Copy the header part of received data.\r
+            //\r
+            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, FragmentLength);\r
+            HeaderCopiedLen += FragmentLength;\r
+          } else if (HeaderCopiedLen < HeaderLen) {\r
+            //\r
+            // Copy the header part of received data.\r
+            //\r
+            CopiedLen = HeaderLen - HeaderCopiedLen;\r
+            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, CopiedLen);\r
+            HeaderCopiedLen += CopiedLen;\r
+\r
+            //\r
+            // Copy the other part of received data.\r
+            //\r
+            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer + CopiedLen, FragmentLength - CopiedLen);\r
+            BufferCopiedLen += (FragmentLength - CopiedLen);\r
+          } else {\r
+            //\r
+            // Copy the other part of received data.\r
+            //\r
+            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer, FragmentLength);\r
+            BufferCopiedLen += FragmentLength;\r
+          }\r
+        }\r
       }\r
       //\r
       // Recycle the receiving buffer after copy to user.\r
@@ -1352,22 +1425,50 @@ EfiPxeBcUdpRead (
     } else {\r
       Udp4Rx = Udp4Token.Packet.RxData;\r
       ASSERT (Udp4Rx != NULL);\r
-      //\r
-      // Copy the header part of received data.\r
-      //\r
+\r
+      HeaderLen = 0;\r
       if (HeaderSize != NULL) {\r
-        CopiedLen   = MIN (*HeaderSize, Udp4Rx->DataLength);\r
-        *HeaderSize = CopiedLen;\r
-        CopyMem (HeaderPtr, Udp4Rx->FragmentTable[0].FragmentBuffer, *HeaderSize);\r
+        HeaderLen = MIN (*HeaderSize, Udp4Rx->DataLength);\r
       }\r
-      //\r
-      // Copy the other part of received data.\r
-      //\r
-      if (Udp4Rx->DataLength - CopiedLen > *BufferSize) {\r
+\r
+      if (Udp4Rx->DataLength - HeaderLen > *BufferSize) {\r
         Status = EFI_BUFFER_TOO_SMALL;\r
       } else {\r
-        *BufferSize = Udp4Rx->DataLength - CopiedLen;\r
-        CopyMem (BufferPtr, (UINT8 *) Udp4Rx->FragmentTable[0].FragmentBuffer + CopiedLen, *BufferSize);\r
+        *HeaderSize = HeaderLen;\r
+        *BufferSize = Udp4Rx->DataLength - HeaderLen;\r
+\r
+        HeaderCopiedLen = 0;\r
+        BufferCopiedLen = 0;\r
+        for (FragmentIndex = 0; FragmentIndex < Udp4Rx->FragmentCount; FragmentIndex++) {\r
+          FragmentLength = Udp4Rx->FragmentTable[FragmentIndex].FragmentLength;\r
+          FragmentBuffer = Udp4Rx->FragmentTable[FragmentIndex].FragmentBuffer;\r
+          if (HeaderCopiedLen + FragmentLength < HeaderLen) {\r
+            //\r
+            // Copy the header part of received data.\r
+            //\r
+            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, FragmentLength);\r
+            HeaderCopiedLen += FragmentLength;\r
+          } else if (HeaderCopiedLen < HeaderLen) {\r
+            //\r
+            // Copy the header part of received data.\r
+            //\r
+            CopiedLen = HeaderLen - HeaderCopiedLen;\r
+            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, CopiedLen);\r
+            HeaderCopiedLen += CopiedLen;\r
+\r
+            //\r
+            // Copy the other part of received data.\r
+            //\r
+            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer + CopiedLen, FragmentLength - CopiedLen);\r
+            BufferCopiedLen += (FragmentLength - CopiedLen);\r
+          } else {\r
+            //\r
+            // Copy the other part of received data.\r
+            //\r
+            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer, FragmentLength);\r
+            BufferCopiedLen += FragmentLength;\r
+          }\r
+        }\r
       }\r
       //\r
       // Recycle the receiving buffer after copy to user.\r