X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcSupport.c;h=720287583e5ff12ba8e065fbf005f8ef8cf9b436;hb=673abfb7491b4abd73bb6a770cf8cd293fbbccb4;hp=28383b32aa79c71f826144aa506fb16b198b6237;hpb=76389e18c04833a87811550ed6db06f1790aacde;p=mirror_edk2.git
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c
index 28383b32aa..720287583e 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c
@@ -1,7 +1,7 @@
/** @file
Support functions implementation for UefiPxeBc Driver.
- Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2017, 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
@@ -16,128 +16,6 @@
#include "PxeBcImpl.h"
-
-/**
- This function returns SMBIOS string given the string number.
-
- @param[in] Smbios The pointer to the SMBIOS structure
- @param[in] StringNumber String number to return. 0 is used to skip all
- strings and point to the next SMBIOS structure.
-
- @return String The pointer to the next SMBIOS structure if
- StringNumber == 0.
-
-**/
-CHAR8 *
-PxeBcGetSmbiosString (
- IN SMBIOS_STRUCTURE_POINTER *Smbios,
- IN UINT16 StringNumber
- )
-{
- UINT16 Index;
- CHAR8 *String;
-
- //
- // Skip over formatted section.
- //
- String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length);
-
- //
- // Look through unformated section.
- //
- for (Index = 1; Index <= StringNumber || StringNumber == 0; Index++) {
- if (StringNumber == Index) {
- return String;
- }
-
- //
- // Skip zero string.
- //
- while (*String != 0) {
- String++;
- }
- String++;
-
- if (*String == 0) {
- //
- // If double NULL then we are done.
- // Return pointer to next structure in Smbios.
- // if you pass in a 0 you will always get here
- //
- Smbios->Raw = (UINT8 *)++String;
- return NULL;
- }
- }
-
- return NULL;
-}
-
-
-/**
- This function obtains the system guid and the serial number from the smbios table.
-
- @param[out] SystemGuid The pointer of the returned system guid.
-
- @retval EFI_SUCCESS Successfully obtained the system guid.
- @retval EFI_NOT_FOUND Did not find the SMBIOS table.
-
-**/
-EFI_STATUS
-PxeBcGetSystemGuid (
- OUT EFI_GUID *SystemGuid
- )
-{
- EFI_STATUS Status;
- SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;
- SMBIOS_STRUCTURE_POINTER Smbios;
- SMBIOS_STRUCTURE_POINTER SmbiosEnd;
- UINT16 Index;
-
- SmbiosTable = NULL;
- Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable);
-
- if (EFI_ERROR (Status) || SmbiosTable == NULL) {
- return EFI_NOT_FOUND;
- }
-
- Smbios.Hdr = (SMBIOS_STRUCTURE *) (UINTN) SmbiosTable->TableAddress;
- SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength);
-
- for (Index = 0; Index < SmbiosTable->TableLength; Index++) {
- if (Smbios.Hdr->Type == 1) {
- if (Smbios.Hdr->Length < 0x19) {
- //
- // Older version did not support Guid and Serial number
- //
- continue;
- }
- //
- // SMBIOS tables are byte packed so we need to do a byte copy to
- // prevend alignment faults on Itanium-based platform.
- //
- CopyMem (SystemGuid, &Smbios.Type1->Uuid, sizeof (EFI_GUID));
- PxeBcGetSmbiosString (&Smbios, Smbios.Type1->SerialNumber);
-
- return EFI_SUCCESS;
- }
- //
- // Make Smbios point to the next record
- //
- PxeBcGetSmbiosString (&Smbios, 0);
-
- if (Smbios.Raw >= SmbiosEnd.Raw) {
- //
- // SMBIOS 2.1 incorrectly stated the length of SmbiosTable as 0x1e.
- // given this we must double check against the length of the structure.
- //
- return EFI_SUCCESS;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-
/**
Flush the previous configration using the new station Ip address.
@@ -150,24 +28,24 @@ PxeBcGetSystemGuid (
**/
EFI_STATUS
-PxeBcFlushStaionIp (
+PxeBcFlushStationIp (
PXEBC_PRIVATE_DATA *Private,
- EFI_IP_ADDRESS *StationIp,
+ EFI_IP_ADDRESS *StationIp, OPTIONAL
EFI_IP_ADDRESS *SubnetMask OPTIONAL
)
{
EFI_PXE_BASE_CODE_MODE *Mode;
EFI_STATUS Status;
- ASSERT (StationIp != NULL);
-
Mode = Private->PxeBc.Mode;
Status = EFI_SUCCESS;
if (Mode->UsingIpv6) {
- CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
- CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
+ if (StationIp != NULL) {
+ CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
+ CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
+ }
//
// Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.
@@ -181,16 +59,16 @@ PxeBcFlushStaionIp (
}
Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
-
} else {
- ASSERT (SubnetMask != NULL);
- CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
- CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
- CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
- CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
+ if (StationIp != NULL) {
+ CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
+ }
+
+ if (SubnetMask != NULL) {
+ CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
+ }
//
// Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.
@@ -204,10 +82,6 @@ PxeBcFlushStaionIp (
}
Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
-
}
ON_EXIT:
@@ -388,7 +262,9 @@ PxeBcIcmpErrorDpcHandle (
}
if (EFI_IP4 (RxData->Header->SourceAddress) != 0 &&
- !NetIp4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), 0)) {
+ (NTOHL (Mode->SubnetMask.Addr[0]) != 0) &&
+ IP4_NET_EQUAL (NTOHL(Mode->StationIp.Addr[0]), EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0])) &&
+ !NetIp4IsUnicast (EFI_NTOHL (RxData->Header->SourceAddress), NTOHL (Mode->SubnetMask.Addr[0]))) {
//
// The source address of the received packet should be a valid unicast address.
//
@@ -403,14 +279,11 @@ PxeBcIcmpErrorDpcHandle (
gBS->SignalEvent (RxData->RecycleSignal);
goto ON_EXIT;
}
-
- if (RxData->Header->Protocol != EFI_IP_PROTO_ICMP) {
- //
- // The protocol value in the header of the receveid packet should be EFI_IP_PROTO_ICMP.
- //
- gBS->SignalEvent (RxData->RecycleSignal);
- goto ON_EXIT;
- }
+
+ //
+ // The protocol has been configured to only receive ICMP packet.
+ //
+ ASSERT (RxData->Header->Protocol == EFI_IP_PROTO_ICMP);
Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);
@@ -540,19 +413,16 @@ PxeBcIcmp6ErrorDpcHandle (
goto ON_EXIT;
}
- if (RxData->Header->NextHeader != IP6_ICMP) {
- //
- // The nextheader in the header of the receveid packet should be IP6_ICMP.
- //
- gBS->SignalEvent (RxData->RecycleSignal);
- goto ON_EXIT;
- }
+ //
+ // The protocol has been configured to only receive ICMP packet.
+ //
+ ASSERT (RxData->Header->NextHeader == IP6_ICMP);
Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);
if (Type != ICMP_V6_DEST_UNREACHABLE &&
Type != ICMP_V6_PACKET_TOO_BIG &&
- Type != ICMP_V6_PACKET_TOO_BIG &&
+ Type != ICMP_V6_TIME_EXCEEDED &&
Type != ICMP_V6_PARAMETER_PROBLEM) {
//
// The type of the receveid packet should be an ICMP6 error message.
@@ -619,6 +489,8 @@ PxeBcIcmp6ErrorUpdate (
@param[in, out] SrcPort The pointer to the source port.
@param[in] DoNotFragment If TRUE, fragment is not enabled.
Otherwise, fragment is enabled.
+ @param[in] Ttl The time to live field of the IP header.
+ @param[in] ToS The type of service field of the IP header.
@retval EFI_SUCCESS Successfully configured this instance.
@retval Others Failed to configure this instance.
@@ -631,7 +503,9 @@ PxeBcConfigUdp4Write (
IN EFI_IPv4_ADDRESS *SubnetMask,
IN EFI_IPv4_ADDRESS *Gateway,
IN OUT UINT16 *SrcPort,
- IN BOOLEAN DoNotFragment
+ IN BOOLEAN DoNotFragment,
+ IN UINT8 Ttl,
+ IN UINT8 ToS
)
{
EFI_UDP4_CONFIG_DATA Udp4CfgData;
@@ -641,8 +515,8 @@ PxeBcConfigUdp4Write (
Udp4CfgData.TransmitTimeout = PXEBC_DEFAULT_LIFETIME;
Udp4CfgData.ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
- Udp4CfgData.TypeOfService = DEFAULT_ToS;
- Udp4CfgData.TimeToLive = DEFAULT_TTL;
+ Udp4CfgData.TypeOfService = ToS;
+ Udp4CfgData.TimeToLive = Ttl;
Udp4CfgData.AllowDuplicatePort = TRUE;
Udp4CfgData.DoNotFragment = DoNotFragment;
@@ -1507,11 +1381,10 @@ PxeBcUintnToAscDecWithFormat (
{
UINTN Remainder;
- while (Length > 0) {
- Length--;
+ for (; Length > 0; Length--) {
Remainder = Number % 10;
Number /= 10;
- Buffer[Length] = (UINT8) ('0' + Remainder);
+ Buffer[Length - 1] = (UINT8) ('0' + Remainder);
}
}
@@ -1522,6 +1395,7 @@ PxeBcUintnToAscDecWithFormat (
@param[in] Number Numeric value to be converted.
@param[in] Buffer The pointer to the buffer for ASCII string.
+ @param[in] BufferSize The maxsize of the buffer.
@return Length The actual length of the ASCII string.
@@ -1529,7 +1403,8 @@ PxeBcUintnToAscDecWithFormat (
UINTN
PxeBcUintnToAscDec (
IN UINTN Number,
- IN UINT8 *Buffer
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
)
{
UINTN Index;
@@ -1545,7 +1420,7 @@ PxeBcUintnToAscDec (
Number = (UINTN) (Number / 10);
} while (Number != 0);
- AsciiStrCpy ((CHAR8 *) Buffer, &TempStr[Index]);
+ AsciiStrCpyS ((CHAR8 *) Buffer, BufferSize, &TempStr[Index]);
Length = AsciiStrLen ((CHAR8 *) Buffer);
@@ -1586,3 +1461,56 @@ PxeBcUniHexToUint8 (
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;
+ }
+}
+