mirror of https://github.com/acidanthera/audk.git
1. Fix bugs for PXE-IPv6 to accommodate the situation:
1.1 Proxy DHCP6 service and DHCP6 service on different servers. 1.2 Proxy DHCP6 server with Response Delay setting. 2. Update to support percent-encoding in NBP file name in netboot6 BootFileURL. Signed-off-by: hhuan13 Reviewed-by: xdu2, tye git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12122 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
1c2ae02e76
commit
129b8b096f
|
@ -212,6 +212,7 @@ struct _DHCP6_TX_CB {
|
||||||
UINT32 RetryLos;
|
UINT32 RetryLos;
|
||||||
UINT32 TickTime;
|
UINT32 TickTime;
|
||||||
UINT16 *Elapsed;
|
UINT16 *Elapsed;
|
||||||
|
BOOLEAN SolicitRetry;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -2817,7 +2817,7 @@ Dhcp6OnTimerTick (
|
||||||
//
|
//
|
||||||
// Handle the first rt in the transmission of solicit specially.
|
// Handle the first rt in the transmission of solicit specially.
|
||||||
//
|
//
|
||||||
if (TxCb->RetryCnt == 0 && TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {
|
if ((TxCb->RetryCnt == 0 || TxCb->SolicitRetry) && TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {
|
||||||
if (Instance->AdSelect == NULL) {
|
if (Instance->AdSelect == NULL) {
|
||||||
//
|
//
|
||||||
// Set adpref as 0xff here to indicate select any advertisement
|
// Set adpref as 0xff here to indicate select any advertisement
|
||||||
|
@ -2893,6 +2893,10 @@ Dhcp6OnTimerTick (
|
||||||
// Retransmit the last sent packet again.
|
// Retransmit the last sent packet again.
|
||||||
//
|
//
|
||||||
Dhcp6TransmitPacket (Instance, TxCb->TxPacket, TxCb->Elapsed);
|
Dhcp6TransmitPacket (Instance, TxCb->TxPacket, TxCb->Elapsed);
|
||||||
|
TxCb->SolicitRetry = FALSE;
|
||||||
|
if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {
|
||||||
|
TxCb->SolicitRetry = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
The internal functions and routines to transmit the IP6 packet.
|
The internal functions and routines to transmit the IP6 packet.
|
||||||
|
|
||||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -689,6 +689,17 @@ Ip6Output (
|
||||||
// For unicast packets, use a combination of the Destination Cache, the Prefix List
|
// For unicast packets, use a combination of the Destination Cache, the Prefix List
|
||||||
// and the Default Router List to determine the IP address of the appropriate next hop.
|
// and the Default Router List to determine the IP address of the appropriate next hop.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
NeighborCache = Ip6FindNeighborEntry (IpSb, &Head->DestinationAddress);
|
||||||
|
if (NeighborCache != NULL) {
|
||||||
|
//
|
||||||
|
// Hit Neighbor Cache.
|
||||||
|
//
|
||||||
|
IP6_COPY_ADDRESS (&NextHop, &Head->DestinationAddress);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Not in Neighbor Cache, check Router cache
|
||||||
|
//
|
||||||
RouteCache = Ip6Route (IpSb, &Head->DestinationAddress, &Head->SourceAddress);
|
RouteCache = Ip6Route (IpSb, &Head->DestinationAddress, &Head->SourceAddress);
|
||||||
if (RouteCache == NULL) {
|
if (RouteCache == NULL) {
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
|
@ -697,6 +708,7 @@ Ip6Output (
|
||||||
IP6_COPY_ADDRESS (&NextHop, &RouteCache->NextHop);
|
IP6_COPY_ADDRESS (&NextHop, &RouteCache->NextHop);
|
||||||
Ip6FreeRouteCacheEntry (RouteCache);
|
Ip6FreeRouteCacheEntry (RouteCache);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Examines the Neighbor Cache for link-layer information about that neighbor.
|
// Examines the Neighbor Cache for link-layer information about that neighbor.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Functions implementation related with DHCPv6 for UefiPxeBc Driver.
|
Functions implementation related with DHCPv6 for UefiPxeBc Driver.
|
||||||
|
|
||||||
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -236,6 +236,7 @@ PxeBcExtractBootFileUrl (
|
||||||
UINT8 *BootFileName;
|
UINT8 *BootFileName;
|
||||||
UINT16 BootFileNameLen;
|
UINT16 BootFileNameLen;
|
||||||
CHAR8 *TmpStr;
|
CHAR8 *TmpStr;
|
||||||
|
CHAR8 TmpChar;
|
||||||
CHAR8 *ServerAddressOption;
|
CHAR8 *ServerAddressOption;
|
||||||
CHAR8 *ServerAddress;
|
CHAR8 *ServerAddress;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
@ -321,17 +322,35 @@ PxeBcExtractBootFileUrl (
|
||||||
++BootFileNamePtr;
|
++BootFileNamePtr;
|
||||||
BootFileNameLen = (UINT16)(Length - (UINT16) ((UINTN)BootFileNamePtr - (UINTN)TmpStr) + 1);
|
BootFileNameLen = (UINT16)(Length - (UINT16) ((UINTN)BootFileNamePtr - (UINTN)TmpStr) + 1);
|
||||||
if (BootFileNameLen != 0 || FileName != NULL) {
|
if (BootFileNameLen != 0 || FileName != NULL) {
|
||||||
|
//
|
||||||
|
// Extract boot file name from URL.
|
||||||
|
//
|
||||||
BootFileName = (UINT8 *) AllocateZeroPool (BootFileNameLen);
|
BootFileName = (UINT8 *) AllocateZeroPool (BootFileNameLen);
|
||||||
if (BootFileName == NULL) {
|
if (BootFileName == NULL) {
|
||||||
FreePool (TmpStr);
|
FreePool (TmpStr);
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMem (BootFileName, BootFileNamePtr, BootFileNameLen);
|
|
||||||
BootFileName[BootFileNameLen - 1] = '\0';
|
|
||||||
*FileName = BootFileName;
|
*FileName = BootFileName;
|
||||||
}
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Decode percent-encoding in boot file name.
|
||||||
|
//
|
||||||
|
while (*BootFileNamePtr != '\0') {
|
||||||
|
if (*BootFileNamePtr == '%') {
|
||||||
|
TmpChar = *(BootFileNamePtr+ 3);
|
||||||
|
*(BootFileNamePtr+ 3) = '\0';
|
||||||
|
*BootFileName = (UINT8) AsciiStrHexToUintn (BootFileNamePtr + 1);
|
||||||
|
BootFileName++;
|
||||||
|
*(BootFileNamePtr+ 3) = TmpChar;
|
||||||
|
BootFileNamePtr += 3;
|
||||||
|
} else {
|
||||||
|
*BootFileName = *BootFileNamePtr;
|
||||||
|
BootFileName++;
|
||||||
|
BootFileNamePtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*BootFileName = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
FreePool (TmpStr);
|
FreePool (TmpStr);
|
||||||
|
|
||||||
|
@ -455,13 +474,13 @@ PxeBcParseDhcp6Packet (
|
||||||
// An ia_na option, embeded with valid ia_addr option and a status_code of success.
|
// An ia_na option, embeded with valid ia_addr option and a status_code of success.
|
||||||
//
|
//
|
||||||
Option = Options[PXEBC_DHCP6_IDX_IA_NA];
|
Option = Options[PXEBC_DHCP6_IDX_IA_NA];
|
||||||
if (Option != NULL && NTOHS(Option->OpLen) >= 12) {
|
if (Option != NULL) {
|
||||||
Option = PxeBcParseDhcp6Options (
|
Option = PxeBcParseDhcp6Options (
|
||||||
Option->Data + 12,
|
Option->Data + 12,
|
||||||
NTOHS (Option->OpLen),
|
NTOHS (Option->OpLen),
|
||||||
PXEBC_DHCP6_OPT_STATUS_CODE
|
PXEBC_DHCP6_OPT_STATUS_CODE
|
||||||
);
|
);
|
||||||
if (Option != NULL && Option->Data[0] == 0) {
|
if ((Option != NULL && Option->Data[0] == 0) || (Option == NULL)) {
|
||||||
IsProxyOffer = FALSE;
|
IsProxyOffer = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,11 +489,12 @@ PxeBcParseDhcp6Packet (
|
||||||
// The offer with "PXEClient" is a pxe offer.
|
// The offer with "PXEClient" is a pxe offer.
|
||||||
//
|
//
|
||||||
Option = Options[PXEBC_DHCP6_IDX_VENDOR_CLASS];
|
Option = Options[PXEBC_DHCP6_IDX_VENDOR_CLASS];
|
||||||
EnterpriseNum = PXEBC_DHCP6_ENTERPRISE_NUM;
|
EnterpriseNum = HTONL(PXEBC_DHCP6_ENTERPRISE_NUM);
|
||||||
|
|
||||||
if (Option != NULL &&
|
if (Option != NULL &&
|
||||||
NTOHS(Option->OpLen) >= 13 &&
|
NTOHS(Option->OpLen) >= 13 &&
|
||||||
CompareMem (Option->Data, &EnterpriseNum, sizeof (UINT32)) == 0 &&
|
CompareMem (Option->Data, &EnterpriseNum, sizeof (UINT32)) == 0 &&
|
||||||
CompareMem (&Option->Data[4], DEFAULT_CLASS_ID_DATA, 9) == 0) {
|
CompareMem (&Option->Data[6], DEFAULT_CLASS_ID_DATA, 9) == 0) {
|
||||||
IsPxeOffer = TRUE;
|
IsPxeOffer = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,6 +586,223 @@ PxeBcCopyDhcp6Proxy (
|
||||||
Mode->ProxyOfferReceived = TRUE;
|
Mode->ProxyOfferReceived = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Seek the address of the first byte of the option header.
|
||||||
|
|
||||||
|
@param[in] Buf The pointer to the buffer.
|
||||||
|
@param[in] SeekLen The length to seek.
|
||||||
|
@param[in] OptType The option type.
|
||||||
|
|
||||||
|
@retval NULL If it failed to seek the option.
|
||||||
|
@retval others The position to the option.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT8 *
|
||||||
|
PxeBcDhcp6SeekOption (
|
||||||
|
IN UINT8 *Buf,
|
||||||
|
IN UINT32 SeekLen,
|
||||||
|
IN UINT16 OptType
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 *Cursor;
|
||||||
|
UINT8 *Option;
|
||||||
|
UINT16 DataLen;
|
||||||
|
UINT16 OpCode;
|
||||||
|
|
||||||
|
Option = NULL;
|
||||||
|
Cursor = Buf;
|
||||||
|
|
||||||
|
while (Cursor < Buf + SeekLen) {
|
||||||
|
OpCode = ReadUnaligned16 ((UINT16 *) Cursor);
|
||||||
|
if (OpCode == HTONS (OptType)) {
|
||||||
|
Option = Cursor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DataLen = NTOHS (ReadUnaligned16 ((UINT16 *) (Cursor + 2)));
|
||||||
|
Cursor += (DataLen + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Option;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Build and send out the request packet for the bootfile, and parse the reply.
|
||||||
|
|
||||||
|
@param[in] Private The pointer to PxeBc private data.
|
||||||
|
@param[in] Index PxeBc option boot item type.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Successfully discovered the boot file.
|
||||||
|
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||||
|
@retval EFI_NOT_FOUND Can't get the PXE reply packet.
|
||||||
|
@retval Others Failed to discover the boot file.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
PxeBcRequestBootService (
|
||||||
|
IN PXEBC_PRIVATE_DATA *Private,
|
||||||
|
IN UINT32 Index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_PXE_BASE_CODE_UDP_PORT SrcPort;
|
||||||
|
EFI_PXE_BASE_CODE_UDP_PORT DestPort;
|
||||||
|
EFI_PXE_BASE_CODE_MODE *Mode;
|
||||||
|
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
|
||||||
|
EFI_PXE_BASE_CODE_DHCPV6_PACKET *Discover;
|
||||||
|
UINTN DiscoverLen;
|
||||||
|
EFI_DHCP6_PACKET *Request;
|
||||||
|
UINTN RequestLen;
|
||||||
|
EFI_DHCP6_PACKET *Reply;
|
||||||
|
UINT8 *RequestOpt;
|
||||||
|
UINT8 *DiscoverOpt;
|
||||||
|
UINTN ReadSize;
|
||||||
|
UINT16 OpFlags;
|
||||||
|
UINT16 OpCode;
|
||||||
|
UINT16 OpLen;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DHCP6_PACKET *ProxyOffer;
|
||||||
|
UINT8 *Option;
|
||||||
|
|
||||||
|
PxeBc = &Private->PxeBc;
|
||||||
|
Mode = PxeBc->Mode;
|
||||||
|
Request = Private->Dhcp6Request;
|
||||||
|
ProxyOffer = &Private->OfferBuffer[Index].Dhcp6.Packet.Offer;
|
||||||
|
SrcPort = PXEBC_BS_DISCOVER_PORT;
|
||||||
|
DestPort = PXEBC_BS_DISCOVER_PORT;
|
||||||
|
OpFlags = 0;
|
||||||
|
|
||||||
|
if (Request == NULL) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
Discover = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_DHCPV6_PACKET));
|
||||||
|
if (Discover == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build the request packet by the cached request packet before.
|
||||||
|
//
|
||||||
|
Discover->TransactionId = ProxyOffer->Dhcp6.Header.TransactionId;
|
||||||
|
Discover->MessageType = Request->Dhcp6.Header.MessageType;
|
||||||
|
RequestOpt = Request->Dhcp6.Option;
|
||||||
|
DiscoverOpt = Discover->DhcpOptions;
|
||||||
|
DiscoverLen = sizeof (EFI_DHCP6_HEADER);
|
||||||
|
RequestLen = DiscoverLen;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find Server ID Option from ProxyOffer.
|
||||||
|
//
|
||||||
|
Option = PxeBcDhcp6SeekOption (
|
||||||
|
ProxyOffer->Dhcp6.Option,
|
||||||
|
ProxyOffer->Length - 4,
|
||||||
|
PXEBC_DHCP6_OPT_SERVER_ID
|
||||||
|
);
|
||||||
|
if (Option == NULL) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add Server ID Option.
|
||||||
|
//
|
||||||
|
OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *) Option)->OpLen);
|
||||||
|
CopyMem (DiscoverOpt, Option, OpLen + 4);
|
||||||
|
DiscoverOpt += (OpLen + 4);
|
||||||
|
DiscoverLen += (OpLen + 4);
|
||||||
|
|
||||||
|
while (RequestLen < Request->Length) {
|
||||||
|
OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *) RequestOpt)->OpCode);
|
||||||
|
OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *) RequestOpt)->OpLen);
|
||||||
|
if (OpCode != EFI_DHCP6_IA_TYPE_NA &&
|
||||||
|
OpCode != EFI_DHCP6_IA_TYPE_TA &&
|
||||||
|
OpCode != PXEBC_DHCP6_OPT_SERVER_ID
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
// Copy all the options except IA option and Server ID
|
||||||
|
//
|
||||||
|
CopyMem (DiscoverOpt, RequestOpt, OpLen + 4);
|
||||||
|
DiscoverOpt += (OpLen + 4);
|
||||||
|
DiscoverLen += (OpLen + 4);
|
||||||
|
}
|
||||||
|
RequestOpt += (OpLen + 4);
|
||||||
|
RequestLen += (OpLen + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update Elapsed option in the package
|
||||||
|
//
|
||||||
|
Option = PxeBcDhcp6SeekOption (
|
||||||
|
Discover->DhcpOptions,
|
||||||
|
(UINT32)(RequestLen - 4),
|
||||||
|
PXEBC_DHCP6_OPT_ELAPSED_TIME
|
||||||
|
);
|
||||||
|
if (Option != NULL) {
|
||||||
|
CalcElapsedTime (Private);
|
||||||
|
WriteUnaligned16 ((UINT16*)(Option + 4), HTONS((UINT16) Private->ElapsedTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = PxeBc->UdpWrite (
|
||||||
|
PxeBc,
|
||||||
|
OpFlags,
|
||||||
|
&Private->ServerIp,
|
||||||
|
&DestPort,
|
||||||
|
NULL,
|
||||||
|
&Private->StationIp,
|
||||||
|
&SrcPort,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&DiscoverLen,
|
||||||
|
(VOID *) Discover
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cache the right PXE reply packet here, set valid flag later.
|
||||||
|
// Especially for PXE discover packet, store it into mode data here.
|
||||||
|
//
|
||||||
|
Reply = &Private->ProxyOffer.Dhcp6.Packet.Offer;
|
||||||
|
ReadSize = (UINTN) Reply->Size;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start Udp6Read instance
|
||||||
|
//
|
||||||
|
Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = PxeBc->UdpRead (
|
||||||
|
PxeBc,
|
||||||
|
OpFlags,
|
||||||
|
&Private->StationIp,
|
||||||
|
&SrcPort,
|
||||||
|
&Private->ServerIp,
|
||||||
|
&DestPort,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&ReadSize,
|
||||||
|
(VOID *) &Reply->Dhcp6
|
||||||
|
);
|
||||||
|
//
|
||||||
|
// Stop Udp6Read instance
|
||||||
|
//
|
||||||
|
Private->Udp6Read->Configure (Private->Udp6Read, NULL);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update length
|
||||||
|
//
|
||||||
|
Reply->Length = (UINT32) ReadSize;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Retry to request bootfile name by the BINL offer.
|
Retry to request bootfile name by the BINL offer.
|
||||||
|
@ -586,7 +823,6 @@ PxeBcRetryDhcp6Binl (
|
||||||
EFI_PXE_BASE_CODE_MODE *Mode;
|
EFI_PXE_BASE_CODE_MODE *Mode;
|
||||||
PXEBC_DHCP6_PACKET_CACHE *Offer;
|
PXEBC_DHCP6_PACKET_CACHE *Offer;
|
||||||
PXEBC_DHCP6_PACKET_CACHE *Cache6;
|
PXEBC_DHCP6_PACKET_CACHE *Cache6;
|
||||||
EFI_IP_ADDRESS ServerIp;
|
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
ASSERT (Index < PXEBC_OFFER_MAX_NUM);
|
ASSERT (Index < PXEBC_OFFER_MAX_NUM);
|
||||||
|
@ -602,8 +838,8 @@ PxeBcRetryDhcp6Binl (
|
||||||
// Parse out the next server address from the last offer, and store it
|
// Parse out the next server address from the last offer, and store it
|
||||||
//
|
//
|
||||||
Status = PxeBcExtractBootFileUrl (
|
Status = PxeBcExtractBootFileUrl (
|
||||||
NULL,
|
&Private->BootFileName,
|
||||||
&ServerIp.v6,
|
&Private->ServerIp.v6,
|
||||||
(CHAR8 *) (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->Data),
|
(CHAR8 *) (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->Data),
|
||||||
NTOHS (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->OpLen)
|
NTOHS (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->OpLen)
|
||||||
);
|
);
|
||||||
|
@ -614,13 +850,8 @@ PxeBcRetryDhcp6Binl (
|
||||||
//
|
//
|
||||||
// Retry Dhcp6Binl again for the bootfile, and the reply cached into Private->ProxyOffer.
|
// Retry Dhcp6Binl again for the bootfile, and the reply cached into Private->ProxyOffer.
|
||||||
//
|
//
|
||||||
Status = PxeBcDhcp6Discover (
|
Status = PxeBcRequestBootService (Private, Index);
|
||||||
Private,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
FALSE,
|
|
||||||
&ServerIp
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -1193,6 +1424,13 @@ PxeBcDhcp6CallBack (
|
||||||
switch (Dhcp6Event) {
|
switch (Dhcp6Event) {
|
||||||
|
|
||||||
case Dhcp6SendSolicit:
|
case Dhcp6SendSolicit:
|
||||||
|
//
|
||||||
|
// Record the first Solicate msg time
|
||||||
|
//
|
||||||
|
if (Private->SolicitTimes == 0) {
|
||||||
|
CalcElapsedTime (Private);
|
||||||
|
Private->SolicitTimes++;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Cache the dhcp discover packet to mode data directly.
|
// Cache the dhcp discover packet to mode data directly.
|
||||||
//
|
//
|
||||||
|
|
|
@ -321,6 +321,8 @@ EfiPxeBcStop (
|
||||||
gBS->CloseEvent (Private->UdpTimeOutEvent);
|
gBS->CloseEvent (Private->UdpTimeOutEvent);
|
||||||
Private->CurSrcPort = 0;
|
Private->CurSrcPort = 0;
|
||||||
Private->BootFileSize = 0;
|
Private->BootFileSize = 0;
|
||||||
|
Private->SolicitTimes = 0;
|
||||||
|
Private->ElapsedTime = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reset the mode data.
|
// Reset the mode data.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
This EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL.
|
This EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL.
|
||||||
interfaces declaration.
|
interfaces declaration.
|
||||||
|
|
||||||
Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -43,6 +43,7 @@
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/UefiDriverEntryPoint.h>
|
#include <Library/UefiDriverEntryPoint.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/NetLib.h>
|
#include <Library/NetLib.h>
|
||||||
|
@ -146,6 +147,8 @@ struct _PXEBC_PRIVATE_DATA {
|
||||||
EFI_PXE_BASE_CODE_MODE Mode;
|
EFI_PXE_BASE_CODE_MODE Mode;
|
||||||
EFI_PXE_BASE_CODE_FUNCTION Function;
|
EFI_PXE_BASE_CODE_FUNCTION Function;
|
||||||
UINT32 Ip6Policy;
|
UINT32 Ip6Policy;
|
||||||
|
UINT32 SolicitTimes;
|
||||||
|
UINT64 ElapsedTime;
|
||||||
|
|
||||||
EFI_UDP4_CONFIG_DATA Udp4CfgData;
|
EFI_UDP4_CONFIG_DATA Udp4CfgData;
|
||||||
EFI_UDP6_CONFIG_DATA Udp6CfgData;
|
EFI_UDP6_CONFIG_DATA Udp6CfgData;
|
||||||
|
|
|
@ -1464,3 +1464,56 @@ PxeBcUniHexToUint8 (
|
||||||
|
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculate the elapsed time
|
||||||
|
|
||||||
|
@param[in] Private The pointer to PXE private data
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
CalcElapsedTime (
|
||||||
|
IN PXEBC_PRIVATE_DATA *Private
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_TIME Time;
|
||||||
|
UINT64 CurrentStamp;
|
||||||
|
UINT64 ElapsedTimeValue;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Generate a time stamp of the centiseconds from 1900/1/1, assume 30day/month.
|
||||||
|
//
|
||||||
|
ZeroMem (&Time, sizeof (EFI_TIME));
|
||||||
|
gRT->GetTime (&Time, NULL);
|
||||||
|
CurrentStamp = (UINT64)
|
||||||
|
(
|
||||||
|
((((((Time.Year - 1900) * 360 +
|
||||||
|
(Time.Month - 1)) * 30 +
|
||||||
|
(Time.Day - 1)) * 24 + Time.Hour) * 60 +
|
||||||
|
Time.Minute) * 60 + Time.Second) * 100
|
||||||
|
+ DivU64x32(Time.Nanosecond, 10000000)
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sentinel value of 0 means that this is the first DHCP packet that we are
|
||||||
|
// sending and that we need to initialize the value. First DHCP Solicit
|
||||||
|
// gets 0 elapsed-time. Otherwise, calculate based on StartTime.
|
||||||
|
//
|
||||||
|
if (Private->ElapsedTime == 0) {
|
||||||
|
Private->ElapsedTime = CurrentStamp;
|
||||||
|
} else {
|
||||||
|
ElapsedTimeValue = CurrentStamp - Private->ElapsedTime;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If elapsed time cannot fit in two bytes, set it to 0xffff.
|
||||||
|
//
|
||||||
|
if (ElapsedTimeValue > 0xffff) {
|
||||||
|
ElapsedTimeValue = 0xffff;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Save the elapsed time
|
||||||
|
//
|
||||||
|
Private->ElapsedTime = ElapsedTimeValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -474,4 +474,15 @@ PxeBcUniHexToUint8 (
|
||||||
IN CHAR16 Char
|
IN CHAR16 Char
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculate the elapsed time
|
||||||
|
|
||||||
|
@param[in] Private The pointer to PXE private data
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
CalcElapsedTime (
|
||||||
|
IN PXEBC_PRIVATE_DATA *Private
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue