mirror of https://github.com/acidanthera/audk.git
320 lines
8.2 KiB
C
320 lines
8.2 KiB
C
/** @file
|
|
Routines used to operate the Ip4 configure variable.
|
|
|
|
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at<BR>
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include "Ip4Config.h"
|
|
#include "NicIp4Variable.h"
|
|
|
|
BOOLEAN mIp4ConfigVariableReclaimed = FALSE;
|
|
|
|
/**
|
|
Check whether the configure parameter is valid.
|
|
|
|
@param NicConfig The configure parameter to check
|
|
|
|
@return TRUE if the parameter is valid for the interface, otherwise FALSE.
|
|
|
|
**/
|
|
BOOLEAN
|
|
Ip4ConfigIsValid (
|
|
IN NIC_IP4_CONFIG_INFO *NicConfig
|
|
)
|
|
{
|
|
EFI_IP4_IPCONFIG_DATA *IpConfig;
|
|
IP4_ADDR Station;
|
|
IP4_ADDR Netmask;
|
|
IP4_ADDR Gateway;
|
|
UINT32 Index;
|
|
|
|
IpConfig = &NicConfig->Ip4Info;
|
|
|
|
if (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC) {
|
|
//
|
|
// Validate that the addresses are unicast and mask
|
|
// is properly formated
|
|
//
|
|
Station = EFI_NTOHL (IpConfig->StationAddress);
|
|
Netmask = EFI_NTOHL (IpConfig->SubnetMask);
|
|
|
|
if ((Netmask == 0) || !IP4_IS_VALID_NETMASK (Netmask) ||
|
|
(Station == 0) || !NetIp4IsUnicast (Station, Netmask)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Validate that the next hops are on the connected network
|
|
// or that is a direct route (Gateway == 0).
|
|
//
|
|
for (Index = 0; Index < IpConfig->RouteTableSize; Index++) {
|
|
Gateway = EFI_NTOHL (IpConfig->RouteTable[Index].GatewayAddress);
|
|
|
|
if ((Gateway != 0) && (!IP4_NET_EQUAL (Station, Gateway, Netmask) ||
|
|
!NetIp4IsUnicast (Gateway, Netmask))) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// return false if it is an unkown configure source. Valid
|
|
// sources are static and dhcp.
|
|
//
|
|
return (BOOLEAN) (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
Read the ip4 configure variable from the EFI variable.
|
|
|
|
@param Instance The IP4 CONFIG instance.
|
|
|
|
@return The IP4 configure read if it is there and is valid, otherwise NULL.
|
|
|
|
**/
|
|
NIC_IP4_CONFIG_INFO *
|
|
Ip4ConfigReadVariable (
|
|
IN IP4_CONFIG_INSTANCE *Instance
|
|
)
|
|
{
|
|
NIC_IP4_CONFIG_INFO *NicConfig;
|
|
|
|
NicConfig = GetVariable (Instance->MacString, &gEfiNicIp4ConfigVariableGuid);
|
|
if (NicConfig != NULL) {
|
|
Ip4ConfigFixRouteTablePointer (&NicConfig->Ip4Info);
|
|
}
|
|
|
|
return NicConfig;
|
|
}
|
|
|
|
/**
|
|
Write the IP4 configure variable to the NVRAM. If Config
|
|
is NULL, remove the variable.
|
|
|
|
@param Instance The IP4 CONFIG instance.
|
|
@param NicConfig The IP4 configure data to write.
|
|
|
|
@retval EFI_SUCCESS The variable is written to the NVRam.
|
|
@retval Others Failed to write the variable.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
Ip4ConfigWriteVariable (
|
|
IN IP4_CONFIG_INSTANCE *Instance,
|
|
IN NIC_IP4_CONFIG_INFO *NicConfig OPTIONAL
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = gRT->SetVariable (
|
|
Instance->MacString,
|
|
&gEfiNicIp4ConfigVariableGuid,
|
|
IP4_CONFIG_VARIABLE_ATTRIBUTES,
|
|
(NicConfig == NULL) ? 0 : SIZEOF_NIC_IP4_CONFIG_INFO (NicConfig),
|
|
NicConfig
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Check whether a NIC exist in the platform given its MAC address.
|
|
|
|
@param NicAddr The MAC address for the NIC to be checked.
|
|
|
|
@retval TRUE The NIC exist in the platform.
|
|
@retval FALSE The NIC doesn't exist in the platform.
|
|
|
|
**/
|
|
BOOLEAN
|
|
Ip4ConfigIsNicExist (
|
|
IN NIC_ADDR *NicAddr
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN NumberOfHandles;
|
|
UINTN Index;
|
|
BOOLEAN Found;
|
|
UINTN AddrSize;
|
|
EFI_MAC_ADDRESS MacAddr;
|
|
|
|
//
|
|
// Locate Service Binding handles.
|
|
//
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
|
NULL,
|
|
&NumberOfHandles,
|
|
&HandleBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return FALSE;
|
|
}
|
|
|
|
Found = FALSE;
|
|
for (Index = 0; Index < NumberOfHandles; Index++) {
|
|
//
|
|
// Get MAC address.
|
|
//
|
|
AddrSize = 0;
|
|
Status = NetLibGetMacAddress (HandleBuffer[Index], &MacAddr, &AddrSize);
|
|
if (EFI_ERROR (Status)) {
|
|
Found = FALSE;
|
|
goto Exit;
|
|
}
|
|
|
|
if ((NicAddr->Len == AddrSize) && (CompareMem (NicAddr->MacAddr.Addr, MacAddr.Addr, AddrSize) == 0)) {
|
|
Found = TRUE;
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
FreePool (HandleBuffer);
|
|
return Found;
|
|
}
|
|
|
|
/**
|
|
Reclaim Ip4Config Variables for NIC which has been removed from the platform.
|
|
|
|
**/
|
|
VOID
|
|
Ip4ConfigReclaimVariable (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN VariableNameSize;
|
|
CHAR16 *VariableName;
|
|
CHAR16 *CurrentVariableName;
|
|
EFI_GUID VendorGuid;
|
|
UINTN VariableNameBufferSize;
|
|
NIC_IP4_CONFIG_INFO *NicConfig;
|
|
|
|
//
|
|
// Check whether we need perform reclaim.
|
|
//
|
|
if (mIp4ConfigVariableReclaimed) {
|
|
return;
|
|
}
|
|
mIp4ConfigVariableReclaimed = TRUE;
|
|
|
|
//
|
|
// Get all Ip4Config Variable.
|
|
//
|
|
VariableNameSize = sizeof (CHAR16);
|
|
VariableName = AllocateZeroPool (VariableNameSize);
|
|
VariableNameBufferSize = VariableNameSize;
|
|
|
|
while (TRUE) {
|
|
Status = gRT->GetNextVariableName (
|
|
&VariableNameSize,
|
|
VariableName,
|
|
&VendorGuid
|
|
);
|
|
|
|
Check:
|
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
|
VariableName = ReallocatePool (VariableNameBufferSize, VariableNameSize, VariableName);
|
|
VariableNameBufferSize = VariableNameSize;
|
|
//
|
|
// Try again using the new buffer.
|
|
//
|
|
Status = gRT->GetNextVariableName (
|
|
&VariableNameSize,
|
|
VariableName,
|
|
&VendorGuid
|
|
);
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// No more variable available, finish search.
|
|
//
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Check variable GUID.
|
|
//
|
|
if (!CompareGuid (&VendorGuid, &gEfiNicIp4ConfigVariableGuid)) {
|
|
continue;
|
|
}
|
|
|
|
NicConfig = GetVariable (VariableName, &gEfiNicIp4ConfigVariableGuid);
|
|
if (NicConfig == NULL) {
|
|
break;
|
|
}
|
|
|
|
if (!Ip4ConfigIsNicExist (&NicConfig->NicAddr)) {
|
|
//
|
|
// No NIC found for this Ip4Config variable, remove it.
|
|
// Since we are in loop of GetNextVariableName(), we need move on to next
|
|
// Variable first and then delete current Variable.
|
|
//
|
|
CurrentVariableName = AllocateCopyPool (VariableNameSize, VariableName);
|
|
Status = gRT->GetNextVariableName (
|
|
&VariableNameSize,
|
|
VariableName,
|
|
&VendorGuid
|
|
);
|
|
|
|
gRT->SetVariable (
|
|
CurrentVariableName,
|
|
&gEfiNicIp4ConfigVariableGuid,
|
|
IP4_CONFIG_VARIABLE_ATTRIBUTES,
|
|
0,
|
|
NULL
|
|
);
|
|
FreePool (CurrentVariableName);
|
|
|
|
//
|
|
// We already get next variable, go to check it.
|
|
//
|
|
goto Check;
|
|
}
|
|
}
|
|
|
|
FreePool (VariableName);
|
|
}
|
|
|
|
/**
|
|
Fix the RouteTable pointer in an EFI_IP4_IPCONFIG_DATA structure.
|
|
|
|
The pointer is set to be immediately follow the ConfigData if there're entries
|
|
in the RouteTable. Otherwise it is set to NULL.
|
|
|
|
@param ConfigData The IP4 IP configure data.
|
|
|
|
**/
|
|
VOID
|
|
Ip4ConfigFixRouteTablePointer (
|
|
IN OUT EFI_IP4_IPCONFIG_DATA *ConfigData
|
|
)
|
|
{
|
|
//
|
|
// The memory used for route table entries must immediately follow
|
|
// the ConfigData and be not packed.
|
|
//
|
|
if (ConfigData->RouteTableSize > 0) {
|
|
ConfigData->RouteTable = (EFI_IP4_ROUTE_TABLE *) (ConfigData + 1);
|
|
} else {
|
|
ConfigData->RouteTable = NULL;
|
|
}
|
|
}
|
|
|