\r
if (Mode->UsingIpv6) {\r
AsciiPrint ("\n>>Start PXE over IPv6");\r
+ //\r
+ // Configure udp6 instance to receive data.\r
+ //\r
+ Status = Private->Udp6Read->Configure (\r
+ Private->Udp6Read,\r
+ &Private->Udp6CfgData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+ \r
//\r
// Configure block size for TFTP as a default value to handle all link layers.\r
//\r
}\r
} else {\r
AsciiPrint ("\n>>Start PXE over IPv4");\r
+ //\r
+ // Configure udp4 instance to receive data.\r
+ //\r
+ Status = Private->Udp4Read->Configure (\r
+ Private->Udp4Read,\r
+ &Private->Udp4CfgData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+ \r
//\r
// Configure block size for TFTP as a default value to handle all link layers.\r
//\r
Mode->IcmpErrorReceived = FALSE;\r
Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DHCP;\r
Private->IsOfferSorted = SortOffers;\r
+ Private->SolicitTimes = 0;\r
+ Private->ElapsedTime = 0;\r
\r
if (!Mode->Started) {\r
return EFI_NOT_STARTED;\r
//\r
Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6);\r
\r
- //\r
- // Configure Udp6Read instance\r
- //\r
- Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); \r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
} else {\r
\r
//\r
//\r
Status = PxeBcDhcp4Dora (Private, Private->Dhcp4);\r
\r
- //\r
- // Configure Udp4Read instance\r
- //\r
- Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+ \r
+ON_EXIT:\r
+ if (Mode->UsingIpv6) {\r
+ Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);\r
+ } else {\r
+ Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);\r
}\r
-\r
//\r
// Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP\r
// receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.\r
);\r
}\r
\r
- if (!EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ } else {\r
//\r
// Parse the cached PXE reply packet, and store it into mode data if valid.\r
//\r
ON_EXIT:\r
\r
if (Mode->UsingIpv6) {\r
- Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); \r
+ Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);\r
} else {\r
- Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); \r
+ Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);\r
}\r
\r
//\r
Mode->IcmpErrorReceived = TRUE;\r
}\r
\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ \r
+ON_EXIT:\r
if (Mode->UsingIpv6) {\r
- Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); \r
+ Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);\r
} else {\r
- Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); \r
+ Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);\r
}\r
-\r
//\r
// Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP\r
// receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.\r
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
//\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
} 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