X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcImpl.c;h=00f1e4d39515f8aaf6206e5a148b91ebe3dc6d14;hb=ce280355b2505c3a0b5d167e963448aedcb905dc;hp=cd8eab3df904d65d4ee57a957d5c003ff12e1626;hpb=19ddbb25872eb727e1751fb842f0f5948a0b3aa7;p=mirror_edk2.git diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c index cd8eab3df9..00f1e4d395 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c @@ -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. // @@ -321,6 +343,8 @@ EfiPxeBcStop ( gBS->CloseEvent (Private->UdpTimeOutEvent); Private->CurSrcPort = 0; Private->BootFileSize = 0; + Private->SolicitTimes = 0; + Private->ElapsedTime = 0; // // Reset the mode data. @@ -386,6 +410,8 @@ EfiPxeBcDhcp ( Mode->IcmpErrorReceived = FALSE; Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DHCP; Private->IsOfferSorted = SortOffers; + Private->SolicitTimes = 0; + Private->ElapsedTime = 0; if (!Mode->Started) { return EFI_NOT_STARTED; @@ -403,6 +429,10 @@ EfiPxeBcDhcp ( // Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6); + if (EFI_ERROR (Status)) { + return Status; + } + // // Configure Udp6Read instance // @@ -419,6 +449,10 @@ EfiPxeBcDhcp ( // Status = PxeBcDhcp4Dora (Private, Private->Dhcp4); + if (EFI_ERROR (Status)) { + return Status; + } + // // Configure Udp4Read instance // @@ -657,7 +691,9 @@ EfiPxeBcDiscover ( ); } - if (!EFI_ERROR (Status)) { + if (EFI_ERROR (Status)) { + return Status; + } else { // // Parse the cached PXE reply packet, and store it into mode data if valid. // @@ -925,6 +961,10 @@ EfiPxeBcMtftp ( Mode->IcmpErrorReceived = TRUE; } + if (EFI_ERROR (Status)) { + return Status; + } + if (Mode->UsingIpv6) { Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); } else { @@ -1210,6 +1250,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; @@ -1324,26 +1370,53 @@ 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); + *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. @@ -1352,22 +1425,50 @@ 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); + *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.