X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcImpl.c;h=ba7f9485949ef74f36a8c3b77ab93d2a7d570f4d;hb=d40002bab9958da3439a2548aa3003d8d68672ff;hp=82fddb169ae0a6e14525cb4130637ffd5331e3ae;hpb=4496ff751f7843fbbedf91f1a58212eb7c9a1ca8;p=mirror_edk2.git
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c
index 82fddb169a..ba7f948594 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c
@@ -1,7 +1,7 @@
/** @file
This implementation of EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL.
- Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -81,6 +81,17 @@ EfiPxeBcStart (
if (Mode->UsingIpv6) {
AsciiPrint ("\n>>Start PXE over IPv6");
+ //
+ // Configure udp6 instance to receive data.
+ //
+ Status = Private->Udp6Read->Configure (
+ Private->Udp6Read,
+ &Private->Udp6CfgData
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
//
// Configure block size for TFTP as a default value to handle all link layers.
//
@@ -115,6 +126,17 @@ EfiPxeBcStart (
}
} else {
AsciiPrint ("\n>>Start PXE over IPv4");
+ //
+ // Configure udp4 instance to receive data.
+ //
+ Status = Private->Udp4Read->Configure (
+ Private->Udp4Read,
+ &Private->Udp4CfgData
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
//
// Configure block size for TFTP as a default value to handle all link layers.
//
@@ -408,13 +430,8 @@ EfiPxeBcDhcp (
Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6);
if (EFI_ERROR (Status)) {
- return Status;
+ goto ON_EXIT;
}
-
- //
- // Configure Udp6Read instance
- //
- Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
} else {
//
@@ -428,15 +445,16 @@ EfiPxeBcDhcp (
Status = PxeBcDhcp4Dora (Private, Private->Dhcp4);
if (EFI_ERROR (Status)) {
- return Status;
+ goto ON_EXIT;
}
-
- //
- // Configure Udp4Read instance
- //
- Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
}
-
+
+ON_EXIT:
+ if (Mode->UsingIpv6) {
+ Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
+ } else {
+ Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
+ }
//
// Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP
// receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
@@ -669,7 +687,9 @@ EfiPxeBcDiscover (
);
}
- if (!EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ } else {
//
// Parse the cached PXE reply packet, and store it into mode data if valid.
//
@@ -701,9 +721,9 @@ EfiPxeBcDiscover (
ON_EXIT:
if (Mode->UsingIpv6) {
- Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
+ Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
} else {
- Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
+ Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
}
//
@@ -937,12 +957,16 @@ EfiPxeBcMtftp (
Mode->IcmpErrorReceived = TRUE;
}
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
if (Mode->UsingIpv6) {
- Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
+ Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
} else {
- Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
+ Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
}
-
//
// Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP
// receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
@@ -1222,6 +1246,12 @@ EfiPxeBcUdpRead (
BOOLEAN IsDone;
BOOLEAN IsMatched;
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;
@@ -1336,26 +1366,55 @@ EfiPxeBcUdpRead (
//
// Copy the rececived packet to user if matched by filter.
//
- CopiedLen = 0;
if (Mode->UsingIpv6) {
Udp6Rx = Udp6Token.Packet.RxData;
ASSERT (Udp6Rx != NULL);
- //
- // Copy the header part of received data.
- //
+
+ HeaderLen = 0;
if (HeaderSize != NULL) {
- CopiedLen = MIN (*HeaderSize, Udp6Rx->DataLength);
- *HeaderSize = CopiedLen;
- CopyMem (HeaderPtr, Udp6Rx->FragmentTable[0].FragmentBuffer, *HeaderSize);
+ HeaderLen = MIN (*HeaderSize, Udp6Rx->DataLength);
}
- //
- // Copy the other part of received data.
- //
- if (Udp6Rx->DataLength - CopiedLen > *BufferSize) {
+
+ if (Udp6Rx->DataLength - HeaderLen > *BufferSize) {
Status = EFI_BUFFER_TOO_SMALL;
} else {
- *BufferSize = Udp6Rx->DataLength - CopiedLen;
- CopyMem (BufferPtr, (UINT8 *) Udp6Rx->FragmentTable[0].FragmentBuffer + CopiedLen, *BufferSize);
+ if (HeaderSize != NULL) {
+ *HeaderSize = HeaderLen;
+ }
+ *BufferSize = Udp6Rx->DataLength - HeaderLen;
+
+ HeaderCopiedLen = 0;
+ BufferCopiedLen = 0;
+ for (FragmentIndex = 0; FragmentIndex < Udp6Rx->FragmentCount; FragmentIndex++) {
+ FragmentLength = Udp6Rx->FragmentTable[FragmentIndex].FragmentLength;
+ FragmentBuffer = Udp6Rx->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;
+ }
+ }
}
//
// Recycle the receiving buffer after copy to user.
@@ -1364,22 +1423,52 @@ EfiPxeBcUdpRead (
} else {
Udp4Rx = Udp4Token.Packet.RxData;
ASSERT (Udp4Rx != NULL);
- //
- // Copy the header part of received data.
- //
+
+ HeaderLen = 0;
if (HeaderSize != NULL) {
- CopiedLen = MIN (*HeaderSize, Udp4Rx->DataLength);
- *HeaderSize = CopiedLen;
- CopyMem (HeaderPtr, Udp4Rx->FragmentTable[0].FragmentBuffer, *HeaderSize);
+ HeaderLen = MIN (*HeaderSize, Udp4Rx->DataLength);
}
- //
- // Copy the other part of received data.
- //
- if (Udp4Rx->DataLength - CopiedLen > *BufferSize) {
+
+ if (Udp4Rx->DataLength - HeaderLen > *BufferSize) {
Status = EFI_BUFFER_TOO_SMALL;
} else {
- *BufferSize = Udp4Rx->DataLength - CopiedLen;
- CopyMem (BufferPtr, (UINT8 *) Udp4Rx->FragmentTable[0].FragmentBuffer + CopiedLen, *BufferSize);
+ if (HeaderSize != NULL) {
+ *HeaderSize = HeaderLen;
+ }
+ *BufferSize = Udp4Rx->DataLength - HeaderLen;
+
+ HeaderCopiedLen = 0;
+ BufferCopiedLen = 0;
+ for (FragmentIndex = 0; FragmentIndex < Udp4Rx->FragmentCount; FragmentIndex++) {
+ FragmentLength = Udp4Rx->FragmentTable[FragmentIndex].FragmentLength;
+ FragmentBuffer = Udp4Rx->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;
+ }
+ }
}
//
// Recycle the receiving buffer after copy to user.