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.