/** @file\r
Support functions implementation for UefiPxeBc Driver.\r
\r
- Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
\r
/**\r
- Flush the previous configration using the new station Ip address.\r
+ Flush the previous configuration using the new station Ip address.\r
\r
@param[in] Private The pointer to the PxeBc private data.\r
@param[in] StationIp The pointer to the station Ip address.\r
EFI_STATUS\r
PxeBcFlushStationIp (\r
PXEBC_PRIVATE_DATA *Private,\r
- EFI_IP_ADDRESS *StationIp,\r
+ EFI_IP_ADDRESS *StationIp, OPTIONAL\r
EFI_IP_ADDRESS *SubnetMask OPTIONAL\r
)\r
{\r
EFI_PXE_BASE_CODE_MODE *Mode;\r
EFI_STATUS Status;\r
-\r
- ASSERT (StationIp != NULL);\r
+ EFI_ARP_CONFIG_DATA ArpConfigData;\r
\r
Mode = Private->PxeBc.Mode;\r
Status = EFI_SUCCESS;\r
+ ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));\r
\r
- if (Mode->UsingIpv6) {\r
-\r
+ if (Mode->UsingIpv6 && StationIp != NULL) {\r
+ //\r
+ // Overwrite Udp6CfgData/Ip6CfgData StationAddress.\r
+ //\r
CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
\r
\r
Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);\r
} else {\r
- ASSERT (SubnetMask != NULL);\r
- CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+ if (StationIp != NULL) {\r
+ //\r
+ // Reconfigure the ARP instance with station Ip address.\r
+ //\r
+ ArpConfigData.SwAddressType = 0x0800;\r
+ ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS);\r
+ ArpConfigData.StationAddress = StationIp;\r
\r
- //\r
- // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.\r
- //\r
- Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);\r
- Private->Ip4->Configure (Private->Ip4, NULL);\r
+ Private->Arp->Configure (Private->Arp, NULL);\r
+ Private->Arp->Configure (Private->Arp, &ArpConfigData);\r
\r
- Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
+ //\r
+ // Overwrite Udp4CfgData/Ip4CfgData StationAddress.\r
+ //\r
+ CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
}\r
\r
- Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);\r
+ if (SubnetMask != NULL) {\r
+ //\r
+ // Overwrite Udp4CfgData/Ip4CfgData SubnetMask.\r
+ //\r
+ CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+ }\r
+\r
+ if (StationIp != NULL && SubnetMask != NULL) {\r
+ //\r
+ // Updated the route table.\r
+ //\r
+ Mode->RouteTableEntries = 1;\r
+ Mode->RouteTable[0].IpAddr.Addr[0] = StationIp->Addr[0] & SubnetMask->Addr[0];\r
+ Mode->RouteTable[0].SubnetMask.Addr[0] = SubnetMask->Addr[0];\r
+ Mode->RouteTable[0].GwAddr.Addr[0] = 0;\r
+ }\r
+\r
+ if (StationIp != NULL || SubnetMask != NULL) {\r
+ //\r
+ // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.\r
+ //\r
+ Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);\r
+ Private->Ip4->Configure (Private->Ip4, NULL);\r
+\r
+ Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);\r
+ }\r
}\r
\r
ON_EXIT:\r
\r
@param Mode The pointer to EFI_PXE_BASE_CODE_MODE.\r
@param Ip4Addr The Ip4 address for resolution.\r
- @param MacAddress The resoluted MAC address if the resolution is successful.\r
+ @param MacAddress The resolved MAC address if the resolution is successful.\r
The value is undefined if the resolution fails.\r
\r
@retval TRUE Found an matched entry.\r
//\r
// The return status should be recognized as EFI_ICMP_ERROR.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
if (EFI_IP4 (RxData->Header->SourceAddress) != 0 &&\r
//\r
// The source address of the received packet should be a valid unicast address.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) {\r
//\r
// The destination address of the received packet should be equal to the host address.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
- if (RxData->Header->Protocol != EFI_IP_PROTO_ICMP) {\r
- //\r
- // The protocol value in the header of the receveid packet should be EFI_IP_PROTO_ICMP.\r
- //\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
- }\r
+ //\r
+ // The protocol has been configured to only receive ICMP packet.\r
+ //\r
+ ASSERT (RxData->Header->Protocol == EFI_IP_PROTO_ICMP);\r
\r
Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
\r
//\r
// The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
//\r
IcmpError += CopiedLen;\r
}\r
\r
+ON_RECYCLE:\r
+ gBS->SignalEvent (RxData->RecycleSignal);\r
+\r
ON_EXIT:\r
Private->IcmpToken.Status = EFI_NOT_READY;\r
Ip4->Receive (Ip4, &Private->IcmpToken);\r
//\r
// The return status should be recognized as EFI_ICMP_ERROR.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) {\r
//\r
// The source address of the received packet should be a valid unicast address.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) &&\r
//\r
// The destination address of the received packet should be equal to the host address.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
- if (RxData->Header->NextHeader != IP6_ICMP) {\r
- //\r
- // The nextheader in the header of the receveid packet should be IP6_ICMP.\r
- //\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
- }\r
+ //\r
+ // The protocol has been configured to only receive ICMP packet.\r
+ //\r
+ ASSERT (RxData->Header->NextHeader == IP6_ICMP);\r
\r
Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
\r
if (Type != ICMP_V6_DEST_UNREACHABLE &&\r
Type != ICMP_V6_PACKET_TOO_BIG &&\r
- Type != ICMP_V6_PACKET_TOO_BIG &&\r
+ Type != ICMP_V6_TIME_EXCEEDED &&\r
Type != ICMP_V6_PARAMETER_PROBLEM) {\r
//\r
// The type of the receveid packet should be an ICMP6 error message.\r
//\r
- gBS->SignalEvent (RxData->RecycleSignal);\r
- goto ON_EXIT;\r
+ goto ON_RECYCLE;\r
}\r
\r
//\r
Icmp6Error += CopiedLen;\r
}\r
\r
+ON_RECYCLE:\r
+ gBS->SignalEvent (RxData->RecycleSignal);\r
+\r
ON_EXIT:\r
Private->Icmp6Token.Status = EFI_NOT_READY;\r
Ip6->Receive (Ip6, &Private->Icmp6Token);\r
@param[in, out] SrcPort The pointer to the source port.\r
@param[in] DoNotFragment If TRUE, fragment is not enabled.\r
Otherwise, fragment is enabled.\r
- @param[in] Ttl The time to live field of the IP header. \r
+ @param[in] Ttl The time to live field of the IP header.\r
@param[in] ToS The type of service field of the IP header.\r
\r
@retval EFI_SUCCESS Successfully configured this instance.\r
Token->Status == EFI_NOT_READY &&\r
EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
//\r
- // Poll the token utill reply/ICMPv6 error message received or timeout.\r
+ // Poll the token until reply/ICMPv6 error message received or timeout.\r
//\r
Udp4->Poll (Udp4);\r
if (Token->Status == EFI_ICMP_ERROR ||\r
Token->Status == EFI_NOT_READY &&\r
EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
//\r
- // Poll the token utill reply/ICMPv6 error message received or timeout.\r
+ // Poll the token until reply/ICMPv6 error message received or timeout.\r
//\r
Udp6->Poll (Udp6);\r
if (Token->Status == EFI_ICMP_ERROR ||\r
//\r
ZeroMem (&Time, sizeof (EFI_TIME));\r
gRT->GetTime (&Time, NULL);\r
- CurrentStamp = (UINT64)\r
- (\r
- ((((((Time.Year - 1900) * 360 +\r
- (Time.Month - 1)) * 30 +\r
- (Time.Day - 1)) * 24 + Time.Hour) * 60 +\r
- Time.Minute) * 60 + Time.Second) * 100\r
- + DivU64x32(Time.Nanosecond, 10000000)\r
- );\r
+ CurrentStamp = MultU64x32 (\r
+ ((((UINT32)(Time.Year - 1900) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) * 60 + Time.Second,\r
+ 100\r
+ ) +\r
+ DivU64x32 (\r
+ Time.Nanosecond,\r
+ 10000000\r
+ );\r
\r
//\r
// Sentinel value of 0 means that this is the first DHCP packet that we are\r