diff options
author | sfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-09-09 08:31:37 +0000 |
---|---|---|
committer | sfu5 <sfu5@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-09-09 08:31:37 +0000 |
commit | c3cd46d421cef32077ae6caf860b50d00ba2aa7f (patch) | |
tree | 9843e5ee1cb086d96deccd10fa851db04050ba6a | |
parent | eb2710af5bee8637741d92ed8d32df562941e6d9 (diff) | |
download | edk2-c3cd46d421cef32077ae6caf860b50d00ba2aa7f.zip edk2-c3cd46d421cef32077ae6caf860b50d00ba2aa7f.tar.gz edk2-c3cd46d421cef32077ae6caf860b50d00ba2aa7f.tar.bz2 |
1. 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@12309 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r-- | MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c index dfdfd35..6f6d7f9 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c @@ -1631,7 +1631,13 @@ EfiPxeBcUdpRead ( EFI_STATUS Status;
BOOLEAN IsDone;
BOOLEAN Matched;
- UINTN CopyLen;
+ UINTN CopiedLen;
+ UINTN HeaderLen;
+ UINTN HeaderCopiedLen;
+ UINTN BufferCopiedLen;
+ UINT32 FragmentLength;
+ UINTN FragmentIndex;
+ UINT8 *FragmentBuffer;
if (This == NULL || DestIp == NULL || DestPort == NULL) {
return EFI_INVALID_PARAMETER;
@@ -1788,26 +1794,51 @@ TRY_AGAIN: }
if (Matched) {
+ ASSERT (RxData != NULL);
- CopyLen = 0;
-
+ HeaderLen = 0;
if (HeaderSize != NULL) {
- CopyLen = MIN (*HeaderSize, RxData->DataLength);
- CopyMem (HeaderPtr, RxData->FragmentTable[0].FragmentBuffer, CopyLen);
- *HeaderSize = CopyLen;
+ HeaderLen = MIN (*HeaderSize, RxData->DataLength);
}
- if (RxData->DataLength - CopyLen > *BufferSize) {
-
+ if (RxData->DataLength - HeaderLen > *BufferSize) {
Status = EFI_BUFFER_TOO_SMALL;
} else {
-
- *BufferSize = RxData->DataLength - CopyLen;
- CopyMem (
- BufferPtr,
- (UINT8 *) RxData->FragmentTable[0].FragmentBuffer + CopyLen,
- *BufferSize
- );
+ *HeaderSize = HeaderLen;
+ *BufferSize = RxData->DataLength - HeaderLen;
+
+ HeaderCopiedLen = 0;
+ BufferCopiedLen = 0;
+ for (FragmentIndex = 0; FragmentIndex < RxData->FragmentCount; FragmentIndex++) {
+ FragmentLength = RxData->FragmentTable[FragmentIndex].FragmentLength;
+ FragmentBuffer = RxData->FragmentTable[FragmentIndex].FragmentBuffer;
+ if (HeaderCopiedLen + FragmentLength < HeaderLen) {
+ //
+ // Copy the header part of received data.
+ //
+ CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, FragmentLength);
+ HeaderCopiedLen += FragmentLength;
+ } else if (HeaderCopiedLen < HeaderLen) {
+ //
+ // Copy the header part of received data.
+ //
+ CopiedLen = HeaderLen - HeaderCopiedLen;
+ CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, CopiedLen);
+ HeaderCopiedLen += CopiedLen;
+
+ //
+ // Copy the other part of received data.
+ //
+ CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer + CopiedLen, FragmentLength - CopiedLen);
+ BufferCopiedLen += (FragmentLength - CopiedLen);
+ } else {
+ //
+ // Copy the other part of received data.
+ //
+ CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer, FragmentLength);
+ BufferCopiedLen += FragmentLength;
+ }
+ }
}
} else {
|