]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. Support netboot6 tftp URL format like tftp://[aaaa::bbbb]/myfile.efi;mode=octet...
authorsfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 9 Sep 2011 08:31:08 +0000 (08:31 +0000)
committersfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 9 Sep 2011 08:31:08 +0000 (08:31 +0000)
2. Fix bug in PXE driver UdpRead function to handle the IP fragmentation.

Signed-off-by: sfu5
Reviewed-by: xdu2
Reviewed-by: hhuan13
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12308 6f19259b-4bc3-4df7-8a09-765794883524

NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c

index 92972f6706883b1c96f3aab51826da7be0711256..c3ae23ec82f52d9059704456e62402c62b719b5d 100644 (file)
@@ -239,6 +239,7 @@ PxeBcExtractBootFileUrl (
   CHAR8                      TmpChar;\r
   CHAR8                      *ServerAddressOption;\r
   CHAR8                      *ServerAddress;\r
+  CHAR8                      *ModeStr;\r
   EFI_STATUS                 Status;\r
 \r
   //\r
@@ -322,6 +323,17 @@ PxeBcExtractBootFileUrl (
   ++BootFileNamePtr;\r
   BootFileNameLen = (UINT16)(Length - (UINT16) ((UINTN)BootFileNamePtr - (UINTN)TmpStr) + 1);\r
   if (BootFileNameLen != 0 || FileName != NULL) {\r
+    //\r
+    // Remove trailing mode=octet if present and ignore.  All other modes are\r
+    // invalid for netboot6, so reject them.\r
+    //\r
+    ModeStr = AsciiStrStr (BootFileNamePtr, ";mode=octet");\r
+    if (ModeStr != NULL && *(ModeStr + AsciiStrLen (";mode=octet")) == '\0') {\r
+      *ModeStr = '\0';\r
+    } else if (AsciiStrStr (BootFileNamePtr, ";mode=") != NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
     //\r
     // Extract boot file name from URL.\r
     //\r
index ae81693bfb5879d55130a956b29e6d70bc2e68c1..0e17731151129777929485f824c9ffd05fdca6f9 100644 (file)
@@ -1228,6 +1228,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
@@ -1342,26 +1348,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
@@ -1370,22 +1403,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