sync sources wuth new edk2
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
parent
01473834b9
commit
15dada20e6
|
@ -3,6 +3,7 @@
|
|||
.DS_Store
|
||||
*.swp
|
||||
*.lock
|
||||
*.bak
|
||||
*~
|
||||
|
||||
# /CloverPackage/
|
||||
|
|
|
@ -27,8 +27,9 @@ ifndef HOST_ARCH
|
|||
endif
|
||||
ifneq (,$(findstring aarch64,$(uname_m)))
|
||||
HOST_ARCH=AARCH64
|
||||
endif
|
||||
ifneq (,$(findstring arm,$(uname_m)))
|
||||
else ifneq (,$(findstring arm64,$(uname_m)))
|
||||
HOST_ARCH=AARCH64
|
||||
else ifneq (,$(findstring arm,$(uname_m)))
|
||||
HOST_ARCH=ARM
|
||||
endif
|
||||
ifndef HOST_ARCH
|
||||
|
|
|
@ -69,8 +69,8 @@ clean:
|
|||
|
||||
.PHONY: cleanall
|
||||
cleanall:
|
||||
@if defined PYTHON_COMMAND $(PYTHON_COMMAND) $(PYTHON_COMMAND) Makefiles\NmakeSubdirs.py cleanall $(LIBRARIES) $(APPLICATIONS)
|
||||
@if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe $(PYTHON_COMMAND) Makefiles\NmakeSubdirs.py cleanall $(LIBRARIES) $(APPLICATIONS)
|
||||
@if defined PYTHON_COMMAND $(PYTHON_COMMAND) Makefiles\NmakeSubdirs.py cleanall $(LIBRARIES) $(APPLICATIONS)
|
||||
@if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe Makefiles\NmakeSubdirs.py cleanall $(LIBRARIES) $(APPLICATIONS)
|
||||
|
||||
!INCLUDE Makefiles\ms.rule
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
|
||||
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
|
||||
#PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
|
||||
NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
|
||||
NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf
|
||||
#
|
||||
# Platform
|
||||
#
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[FeaturePcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
|
||||
# gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES
|
||||
|
|
|
@ -190,7 +190,7 @@ CoreInitializeImageServices (
|
|||
mDxeCoreImageMachineType = PeCoffLoaderGetMachineType (Image->Info.ImageBase);
|
||||
gDxeCoreImageHandle = Image->Handle;
|
||||
gDxeCoreLoadedImage = &Image->Info;
|
||||
|
||||
/*
|
||||
if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {
|
||||
//
|
||||
// Export DXE Core PE Loader functionality for backward compatibility.
|
||||
|
@ -202,7 +202,7 @@ CoreInitializeImageServices (
|
|||
&mLoadPe32PrivateData.Pe32Image
|
||||
);
|
||||
}
|
||||
|
||||
*/
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
[Packages]
|
||||
CloverPkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
# MdeModulePkg/MdeModulePkg.dec
|
||||
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
# IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
|
|
|
@ -9,13 +9,7 @@
|
|||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2014 - 2015, Hewlett-Packard Development Company, L.P.<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
|
||||
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.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
|
@ -33,74 +27,74 @@
|
|||
/// Section 6.1, PCI Local Bus Specification, 2.2
|
||||
///
|
||||
typedef struct {
|
||||
UINT16 VendorId; //0
|
||||
UINT16 DeviceId; //2
|
||||
UINT16 Command; //4
|
||||
UINT16 Status; //6
|
||||
UINT8 RevisionID; //8
|
||||
UINT8 ClassCode[3]; //9
|
||||
UINT8 CacheLineSize; //c
|
||||
UINT8 LatencyTimer; //d
|
||||
UINT8 HeaderType; //e
|
||||
UINT8 BIST; //f
|
||||
} PCI_DEVICE_INDEPENDENT_REGION; //len=0x10
|
||||
UINT16 VendorId;
|
||||
UINT16 DeviceId;
|
||||
UINT16 Command;
|
||||
UINT16 Status;
|
||||
UINT8 RevisionID;
|
||||
UINT8 ClassCode[3];
|
||||
UINT8 CacheLineSize;
|
||||
UINT8 LatencyTimer;
|
||||
UINT8 HeaderType;
|
||||
UINT8 BIST;
|
||||
} PCI_DEVICE_INDEPENDENT_REGION;
|
||||
|
||||
///
|
||||
/// PCI Device header region in PCI Configuration Space
|
||||
/// Section 6.1, PCI Local Bus Specification, 2.2
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Bar[6]; //0
|
||||
UINT32 CISPtr; //18
|
||||
UINT16 SubsystemVendorID; //1c
|
||||
UINT16 SubsystemID; //1e
|
||||
UINT32 ExpansionRomBar; //20
|
||||
UINT8 CapabilityPtr; //24
|
||||
UINT8 Reserved1[3]; //25
|
||||
UINT32 Reserved2; //28
|
||||
UINT8 InterruptLine; //2c
|
||||
UINT8 InterruptPin; //2d
|
||||
UINT8 MinGnt; //2e
|
||||
UINT8 MaxLat; //2f
|
||||
} PCI_DEVICE_HEADER_TYPE_REGION; //len=0x30
|
||||
UINT32 Bar[6];
|
||||
UINT32 CISPtr;
|
||||
UINT16 SubsystemVendorID;
|
||||
UINT16 SubsystemID;
|
||||
UINT32 ExpansionRomBar;
|
||||
UINT8 CapabilityPtr;
|
||||
UINT8 Reserved1[3];
|
||||
UINT32 Reserved2;
|
||||
UINT8 InterruptLine;
|
||||
UINT8 InterruptPin;
|
||||
UINT8 MinGnt;
|
||||
UINT8 MaxLat;
|
||||
} PCI_DEVICE_HEADER_TYPE_REGION;
|
||||
|
||||
///
|
||||
/// PCI Device Configuration Space
|
||||
/// Section 6.1, PCI Local Bus Specification, 2.2
|
||||
///
|
||||
typedef struct {
|
||||
PCI_DEVICE_INDEPENDENT_REGION Hdr; //0
|
||||
PCI_DEVICE_HEADER_TYPE_REGION Device; //10
|
||||
} PCI_TYPE00; //len=0x40
|
||||
PCI_DEVICE_INDEPENDENT_REGION Hdr;
|
||||
PCI_DEVICE_HEADER_TYPE_REGION Device;
|
||||
} PCI_TYPE00;
|
||||
|
||||
///
|
||||
/// PCI-PCI Bridge header region in PCI Configuration Space
|
||||
/// Section 3.2, PCI-PCI Bridge Architecture, Version 1.2
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 Bar[2]; //0
|
||||
UINT8 PrimaryBus; //8
|
||||
UINT8 SecondaryBus; //9
|
||||
UINT8 SubordinateBus; //a
|
||||
UINT8 SecondaryLatencyTimer; //b
|
||||
UINT8 IoBase; //c
|
||||
UINT8 IoLimit; //d
|
||||
UINT16 SecondaryStatus; //e
|
||||
UINT16 MemoryBase; //10
|
||||
UINT16 MemoryLimit; //12
|
||||
UINT16 PrefetchableMemoryBase; //14
|
||||
UINT16 PrefetchableMemoryLimit; //16
|
||||
UINT32 PrefetchableBaseUpper32; //18
|
||||
UINT32 PrefetchableLimitUpper32; //1c
|
||||
UINT16 IoBaseUpper16; //20
|
||||
UINT16 IoLimitUpper16; //22
|
||||
UINT8 CapabilityPtr; //24
|
||||
UINT8 Reserved[3]; //25
|
||||
UINT32 ExpansionRomBAR; //28
|
||||
UINT8 InterruptLine; //2c
|
||||
UINT8 InterruptPin; //2d
|
||||
UINT16 BridgeControl; //2e
|
||||
} PCI_BRIDGE_CONTROL_REGISTER; //len=0x30
|
||||
UINT32 Bar[2];
|
||||
UINT8 PrimaryBus;
|
||||
UINT8 SecondaryBus;
|
||||
UINT8 SubordinateBus;
|
||||
UINT8 SecondaryLatencyTimer;
|
||||
UINT8 IoBase;
|
||||
UINT8 IoLimit;
|
||||
UINT16 SecondaryStatus;
|
||||
UINT16 MemoryBase;
|
||||
UINT16 MemoryLimit;
|
||||
UINT16 PrefetchableMemoryBase;
|
||||
UINT16 PrefetchableMemoryLimit;
|
||||
UINT32 PrefetchableBaseUpper32;
|
||||
UINT32 PrefetchableLimitUpper32;
|
||||
UINT16 IoBaseUpper16;
|
||||
UINT16 IoLimitUpper16;
|
||||
UINT8 CapabilityPtr;
|
||||
UINT8 Reserved[3];
|
||||
UINT32 ExpansionRomBAR;
|
||||
UINT8 InterruptLine;
|
||||
UINT8 InterruptPin;
|
||||
UINT16 BridgeControl;
|
||||
} PCI_BRIDGE_CONTROL_REGISTER;
|
||||
|
||||
///
|
||||
/// PCI-to-PCI Bridge Configuration Space
|
||||
|
@ -121,26 +115,26 @@ typedef union {
|
|||
/// Section 4.5.1, PC Card Standard. 8.0
|
||||
///
|
||||
typedef struct {
|
||||
UINT32 CardBusSocketReg; ///< Cardus Socket/ExCA Base //0
|
||||
UINT8 Cap_Ptr; //4
|
||||
UINT32 CardBusSocketReg; ///< Cardus Socket/ExCA Base
|
||||
UINT8 Cap_Ptr;
|
||||
UINT8 Reserved;
|
||||
UINT16 SecondaryStatus; ///< Secondary Status //6
|
||||
UINT8 PciBusNumber; ///< PCI Bus Number //8
|
||||
UINT8 CardBusBusNumber; ///< CardBus Bus Number //9
|
||||
UINT8 SubordinateBusNumber; ///< Subordinate Bus Number //a
|
||||
UINT8 CardBusLatencyTimer; ///< CardBus Latency Timer //b
|
||||
UINT32 MemoryBase0; ///< Memory Base Register 0 //c
|
||||
UINT32 MemoryLimit0; ///< Memory Limit Register 0 //10
|
||||
UINT32 MemoryBase1; //14
|
||||
UINT32 MemoryLimit1; //18
|
||||
UINT32 IoBase0; //1c
|
||||
UINT32 IoLimit0; ///< I/O Base Register 0 //20
|
||||
UINT32 IoBase1; ///< I/O Limit Register 0 //24
|
||||
UINT32 IoLimit1; //28
|
||||
UINT8 InterruptLine; ///< Interrupt Line //2c
|
||||
UINT8 InterruptPin; ///< Interrupt Pin //2d
|
||||
UINT16 BridgeControl; ///< Bridge Control //2e
|
||||
} PCI_CARDBUS_CONTROL_REGISTER; //len=0x30
|
||||
UINT16 SecondaryStatus; ///< Secondary Status
|
||||
UINT8 PciBusNumber; ///< PCI Bus Number
|
||||
UINT8 CardBusBusNumber; ///< CardBus Bus Number
|
||||
UINT8 SubordinateBusNumber; ///< Subordinate Bus Number
|
||||
UINT8 CardBusLatencyTimer; ///< CardBus Latency Timer
|
||||
UINT32 MemoryBase0; ///< Memory Base Register 0
|
||||
UINT32 MemoryLimit0; ///< Memory Limit Register 0
|
||||
UINT32 MemoryBase1;
|
||||
UINT32 MemoryLimit1;
|
||||
UINT32 IoBase0;
|
||||
UINT32 IoLimit0; ///< I/O Base Register 0
|
||||
UINT32 IoBase1; ///< I/O Limit Register 0
|
||||
UINT32 IoLimit1;
|
||||
UINT8 InterruptLine; ///< Interrupt Line
|
||||
UINT8 InterruptPin; ///< Interrupt Pin
|
||||
UINT16 BridgeControl; ///< Bridge Control
|
||||
} PCI_CARDBUS_CONTROL_REGISTER;
|
||||
|
||||
//
|
||||
// Definitions of PCI class bytes and manipulation macros.
|
||||
|
|
|
@ -1262,7 +1262,7 @@ extern EFI_GUID gEfiShellProtocolGuid;
|
|||
|
||||
enum ShellVersion {
|
||||
SHELL_MAJOR_VERSION = 2,
|
||||
SHELL_MINOR_VERSION = 204
|
||||
SHELL_MINOR_VERSION = 205
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,13 @@
|
|||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
The full text of the license may be found at
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
|
@ -244,14 +250,14 @@ typedef union {
|
|||
#if defined (MDE_CPU_IA32)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
|
||||
(((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
|
||||
((Machine) == EFI_IMAGE_MACHINE_IA32)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64)
|
||||
|
||||
#elif defined (MDE_CPU_X64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
|
||||
(((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
|
||||
((Machine) == EFI_IMAGE_MACHINE_X64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32)
|
||||
|
||||
|
@ -264,7 +270,7 @@ typedef union {
|
|||
#elif defined (MDE_CPU_AARCH64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
|
||||
(((Machine) == EFI_IMAGE_MACHINE_AARCH64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
|
||||
((Machine) == EFI_IMAGE_MACHINE_AARCH64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
|
||||
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
/** @file
|
||||
Defines data types and constants introduced in UEFI.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011 - 2016, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __UEFI_BASETYPE_H__
|
||||
#define __UEFI_BASETYPE_H__
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
//
|
||||
// Basic data type definitions introduced in UEFI.
|
||||
//
|
||||
|
||||
///
|
||||
/// 128-bit buffer containing a unique identifier value.
|
||||
///
|
||||
typedef GUID EFI_GUID;
|
||||
///
|
||||
/// Function return status for EFI API.
|
||||
///
|
||||
typedef RETURN_STATUS EFI_STATUS;
|
||||
///
|
||||
/// A collection of related interfaces.
|
||||
///
|
||||
typedef VOID *EFI_HANDLE;
|
||||
///
|
||||
/// Handle to an event structure.
|
||||
///
|
||||
typedef VOID *EFI_EVENT;
|
||||
///
|
||||
/// Task priority level.
|
||||
///
|
||||
typedef UINTN EFI_TPL;
|
||||
///
|
||||
/// Logical block address.
|
||||
///
|
||||
typedef UINT64 EFI_LBA;
|
||||
|
||||
///
|
||||
/// 64-bit physical memory address.
|
||||
///
|
||||
typedef UINT64 EFI_PHYSICAL_ADDRESS;
|
||||
|
||||
///
|
||||
/// 64-bit virtual memory address.
|
||||
///
|
||||
typedef UINT64 EFI_VIRTUAL_ADDRESS;
|
||||
|
||||
///
|
||||
/// EFI Time Abstraction:
|
||||
/// Year: 1900 - 9999
|
||||
/// Month: 1 - 12
|
||||
/// Day: 1 - 31
|
||||
/// Hour: 0 - 23
|
||||
/// Minute: 0 - 59
|
||||
/// Second: 0 - 59
|
||||
/// Nanosecond: 0 - 999,999,999
|
||||
/// TimeZone: -1440 to 1440 or 2047
|
||||
///
|
||||
typedef struct {
|
||||
UINT16 Year;
|
||||
UINT8 Month;
|
||||
UINT8 Day;
|
||||
UINT8 Hour;
|
||||
UINT8 Minute;
|
||||
UINT8 Second;
|
||||
UINT8 Pad1;
|
||||
UINT32 Nanosecond;
|
||||
INT16 TimeZone;
|
||||
UINT8 Daylight;
|
||||
UINT8 Pad2;
|
||||
} EFI_TIME;
|
||||
|
||||
|
||||
///
|
||||
/// 4-byte buffer. An IPv4 internet protocol address.
|
||||
///
|
||||
typedef IPv4_ADDRESS EFI_IPv4_ADDRESS;
|
||||
|
||||
///
|
||||
/// 16-byte buffer. An IPv6 internet protocol address.
|
||||
///
|
||||
typedef IPv6_ADDRESS EFI_IPv6_ADDRESS;
|
||||
|
||||
///
|
||||
/// 32-byte buffer containing a network Media Access Control address.
|
||||
///
|
||||
typedef struct {
|
||||
UINT8 Addr[32];
|
||||
} EFI_MAC_ADDRESS;
|
||||
|
||||
///
|
||||
/// 16-byte buffer aligned on a 4-byte boundary.
|
||||
/// An IPv4 or IPv6 internet protocol address.
|
||||
///
|
||||
typedef union {
|
||||
UINT32 Addr[4];
|
||||
EFI_IPv4_ADDRESS v4;
|
||||
EFI_IPv6_ADDRESS v6;
|
||||
} EFI_IP_ADDRESS;
|
||||
|
||||
|
||||
///
|
||||
/// Enumeration of EFI_STATUS.
|
||||
///@{
|
||||
#define EFI_SUCCESS RETURN_SUCCESS
|
||||
#define EFI_LOAD_ERROR RETURN_LOAD_ERROR
|
||||
#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER
|
||||
#define EFI_UNSUPPORTED RETURN_UNSUPPORTED
|
||||
#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE
|
||||
#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL
|
||||
#define EFI_NOT_READY RETURN_NOT_READY
|
||||
#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR
|
||||
#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED
|
||||
#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES
|
||||
#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED
|
||||
#define EFI_VOLUME_FULL RETURN_VOLUME_FULL
|
||||
#define EFI_NO_MEDIA RETURN_NO_MEDIA
|
||||
#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED
|
||||
#define EFI_NOT_FOUND RETURN_NOT_FOUND
|
||||
#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED
|
||||
#define EFI_NO_RESPONSE RETURN_NO_RESPONSE
|
||||
#define EFI_NO_MAPPING RETURN_NO_MAPPING
|
||||
#define EFI_TIMEOUT RETURN_TIMEOUT
|
||||
#define EFI_NOT_STARTED RETURN_NOT_STARTED
|
||||
#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED
|
||||
#define EFI_ABORTED RETURN_ABORTED
|
||||
#define EFI_ICMP_ERROR RETURN_ICMP_ERROR
|
||||
#define EFI_TFTP_ERROR RETURN_TFTP_ERROR
|
||||
#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR
|
||||
#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION
|
||||
#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION
|
||||
#define EFI_CRC_ERROR RETURN_CRC_ERROR
|
||||
#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA
|
||||
#define EFI_END_OF_FILE RETURN_END_OF_FILE
|
||||
#define EFI_INVALID_LANGUAGE RETURN_INVALID_LANGUAGE
|
||||
#define EFI_COMPROMISED_DATA RETURN_COMPROMISED_DATA
|
||||
#define EFI_HTTP_ERROR RETURN_HTTP_ERROR
|
||||
|
||||
#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH
|
||||
#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE
|
||||
#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE
|
||||
#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
|
||||
#define EFI_WARN_STALE_DATA RETURN_WARN_STALE_DATA
|
||||
#define EFI_WARN_FILE_SYSTEM RETURN_WARN_FILE_SYSTEM
|
||||
///@}
|
||||
|
||||
///
|
||||
/// Define macro to encode the status code.
|
||||
///
|
||||
#define EFIERR(_a) ENCODE_ERROR(_a)
|
||||
|
||||
#define EFI_ERROR(A) RETURN_ERROR(A)
|
||||
|
||||
///
|
||||
/// ICMP error definitions
|
||||
///@{
|
||||
#define EFI_NETWORK_UNREACHABLE EFIERR(100)
|
||||
#define EFI_HOST_UNREACHABLE EFIERR(101)
|
||||
#define EFI_PROTOCOL_UNREACHABLE EFIERR(102)
|
||||
#define EFI_PORT_UNREACHABLE EFIERR(103)
|
||||
///@}
|
||||
|
||||
///
|
||||
/// Tcp connection status definitions
|
||||
///@{
|
||||
#define EFI_CONNECTION_FIN EFIERR(104)
|
||||
#define EFI_CONNECTION_RESET EFIERR(105)
|
||||
#define EFI_CONNECTION_REFUSED EFIERR(106)
|
||||
///@}
|
||||
|
||||
//
|
||||
// The EFI memory allocation functions work in units of EFI_PAGEs that are
|
||||
// 4KB. This should in no way be confused with the page size of the processor.
|
||||
// An EFI_PAGE is just the quanta of memory in EFI.
|
||||
//
|
||||
#define EFI_PAGE_SIZE SIZE_4KB
|
||||
#define EFI_PAGE_MASK 0xFFF
|
||||
#define EFI_PAGE_SHIFT 12
|
||||
|
||||
/**
|
||||
Macro that converts a size, in bytes, to a number of EFI_PAGESs.
|
||||
|
||||
@param Size A size in bytes. This parameter is assumed to be type UINTN.
|
||||
Passing in a parameter that is larger than UINTN may produce
|
||||
unexpected results.
|
||||
|
||||
@return The number of EFI_PAGESs associated with the number of bytes specified
|
||||
by Size.
|
||||
|
||||
**/
|
||||
#define EFI_SIZE_TO_PAGES(Size) (((Size) >> EFI_PAGE_SHIFT) + (((Size) & EFI_PAGE_MASK) ? 1 : 0))
|
||||
|
||||
/**
|
||||
Macro that converts a number of EFI_PAGEs to a size in bytes.
|
||||
|
||||
@param Pages The number of EFI_PAGES. This parameter is assumed to be
|
||||
type UINTN. Passing in a parameter that is larger than
|
||||
UINTN may produce unexpected results.
|
||||
|
||||
@return The number of bytes associated with the number of EFI_PAGEs specified
|
||||
by Pages.
|
||||
|
||||
**/
|
||||
#define EFI_PAGES_TO_SIZE(Pages) ((Pages) << EFI_PAGE_SHIFT)
|
||||
|
||||
///
|
||||
/// PE32+ Machine type for IA32 UEFI images.
|
||||
///
|
||||
#define EFI_IMAGE_MACHINE_IA32 0x014C
|
||||
|
||||
///
|
||||
/// PE32+ Machine type for IA64 UEFI images.
|
||||
///
|
||||
#define EFI_IMAGE_MACHINE_IA64 0x0200
|
||||
|
||||
///
|
||||
/// PE32+ Machine type for EBC UEFI images.
|
||||
///
|
||||
#define EFI_IMAGE_MACHINE_EBC 0x0EBC
|
||||
|
||||
///
|
||||
/// PE32+ Machine type for X64 UEFI images.
|
||||
///
|
||||
#define EFI_IMAGE_MACHINE_X64 0x8664
|
||||
|
||||
///
|
||||
/// PE32+ Machine type for ARM mixed ARM and Thumb/Thumb2 images.
|
||||
///
|
||||
#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2
|
||||
|
||||
///
|
||||
/// PE32+ Machine type for AARCH64 A64 images.
|
||||
///
|
||||
#define EFI_IMAGE_MACHINE_AARCH64 0xAA64
|
||||
|
||||
|
||||
#if defined (MDE_CPU_IA32)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
|
||||
((Machine) == EFI_IMAGE_MACHINE_IA32)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64)
|
||||
|
||||
#elif defined (MDE_CPU_X64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
|
||||
((Machine) == EFI_IMAGE_MACHINE_X64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32)
|
||||
|
||||
#elif defined (MDE_CPU_ARM)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
|
||||
|
||||
#elif defined (MDE_CPU_AARCH64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
|
||||
((Machine) == EFI_IMAGE_MACHINE_AARCH64)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
|
||||
|
||||
#elif defined (MDE_CPU_EBC)
|
||||
|
||||
///
|
||||
/// This is just to make sure you can cross compile with the EBC compiler.
|
||||
/// It does not make sense to have a PE loader coded in EBC.
|
||||
///
|
||||
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC)
|
||||
|
||||
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
|
||||
|
||||
#else
|
||||
#error Unknown Processor Type
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -5,12 +5,7 @@
|
|||
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
# Portions copyright (c) 2011 - 2013, ARM Ltd. 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
|
||||
# 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.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#
|
||||
##
|
||||
|
@ -96,7 +91,6 @@
|
|||
Ia32/WriteCr0.c | MSFT
|
||||
Ia32/WriteMsr64.c | MSFT
|
||||
Ia32/SwapBytes64.c | MSFT
|
||||
Ia32/SetJump.c | MSFT
|
||||
Ia32/RRotU64.c | MSFT
|
||||
Ia32/RShiftU64.c | MSFT
|
||||
Ia32/ReadPmc.c | MSFT
|
||||
|
@ -140,7 +134,6 @@
|
|||
Ia32/MultU64x32.c | MSFT
|
||||
Ia32/LShiftU64.c | MSFT
|
||||
Ia32/LRotU64.c | MSFT
|
||||
Ia32/LongJump.c | MSFT
|
||||
Ia32/Invd.c | MSFT
|
||||
Ia32/FxRestore.c | MSFT
|
||||
Ia32/FxSave.c | MSFT
|
||||
|
@ -148,7 +141,6 @@
|
|||
Ia32/EnablePaging32.c | MSFT
|
||||
Ia32/EnableInterrupts.c | MSFT
|
||||
Ia32/EnableDisableInterrupts.c | MSFT
|
||||
Ia32/DivU64x64Remainder.nasm| MSFT
|
||||
Ia32/DivU64x32Remainder.c | MSFT
|
||||
Ia32/DivU64x32.c | MSFT
|
||||
Ia32/DisablePaging32.c | MSFT
|
||||
|
@ -158,164 +150,40 @@
|
|||
Ia32/CpuId.c | MSFT
|
||||
Ia32/CpuBreakpoint.c | MSFT
|
||||
Ia32/ARShiftU64.c | MSFT
|
||||
Ia32/Thunk16.nasm | MSFT
|
||||
Ia32/EnablePaging64.nasm| MSFT
|
||||
Ia32/EnableCache.c | MSFT
|
||||
Ia32/DisableCache.c | MSFT
|
||||
Ia32/RdRand.nasm| MSFT
|
||||
|
||||
Ia32/Wbinvd.nasm| INTEL
|
||||
Ia32/WriteMm7.nasm| INTEL
|
||||
Ia32/WriteMm6.nasm| INTEL
|
||||
Ia32/WriteMm5.nasm| INTEL
|
||||
Ia32/WriteMm4.nasm| INTEL
|
||||
Ia32/WriteMm3.nasm| INTEL
|
||||
Ia32/WriteMm2.nasm| INTEL
|
||||
Ia32/WriteMm1.nasm| INTEL
|
||||
Ia32/WriteMm0.nasm| INTEL
|
||||
Ia32/WriteLdtr.nasm| INTEL
|
||||
Ia32/WriteIdtr.nasm| INTEL
|
||||
Ia32/WriteGdtr.nasm| INTEL
|
||||
Ia32/WriteDr7.nasm| INTEL
|
||||
Ia32/WriteDr6.nasm| INTEL
|
||||
Ia32/WriteDr5.nasm| INTEL
|
||||
Ia32/WriteDr4.nasm| INTEL
|
||||
Ia32/WriteDr3.nasm| INTEL
|
||||
Ia32/WriteDr2.nasm| INTEL
|
||||
Ia32/WriteDr1.nasm| INTEL
|
||||
Ia32/WriteDr0.nasm| INTEL
|
||||
Ia32/WriteCr4.nasm| INTEL
|
||||
Ia32/WriteCr3.nasm| INTEL
|
||||
Ia32/WriteCr2.nasm| INTEL
|
||||
Ia32/WriteCr0.nasm| INTEL
|
||||
Ia32/WriteMsr64.nasm| INTEL
|
||||
Ia32/SwapBytes64.nasm| INTEL
|
||||
Ia32/SetJump.nasm| INTEL
|
||||
Ia32/RRotU64.nasm| INTEL
|
||||
Ia32/RShiftU64.nasm| INTEL
|
||||
Ia32/ReadPmc.nasm| INTEL
|
||||
Ia32/ReadTsc.nasm| INTEL
|
||||
Ia32/ReadLdtr.nasm| INTEL
|
||||
Ia32/ReadIdtr.nasm| INTEL
|
||||
Ia32/ReadGdtr.nasm| INTEL
|
||||
Ia32/ReadTr.nasm| INTEL
|
||||
Ia32/ReadSs.nasm| INTEL
|
||||
Ia32/ReadGs.nasm| INTEL
|
||||
Ia32/ReadFs.nasm| INTEL
|
||||
Ia32/ReadEs.nasm| INTEL
|
||||
Ia32/ReadDs.nasm| INTEL
|
||||
Ia32/ReadCs.nasm| INTEL
|
||||
Ia32/ReadMsr64.nasm| INTEL
|
||||
Ia32/ReadMm7.nasm| INTEL
|
||||
Ia32/ReadMm6.nasm| INTEL
|
||||
Ia32/ReadMm5.nasm| INTEL
|
||||
Ia32/ReadMm4.nasm| INTEL
|
||||
Ia32/ReadMm3.nasm| INTEL
|
||||
Ia32/ReadMm2.nasm| INTEL
|
||||
Ia32/ReadMm1.nasm| INTEL
|
||||
Ia32/ReadMm0.nasm| INTEL
|
||||
Ia32/ReadEflags.nasm| INTEL
|
||||
Ia32/ReadDr7.nasm| INTEL
|
||||
Ia32/ReadDr6.nasm| INTEL
|
||||
Ia32/ReadDr5.nasm| INTEL
|
||||
Ia32/ReadDr4.nasm| INTEL
|
||||
Ia32/ReadDr3.nasm| INTEL
|
||||
Ia32/ReadDr2.nasm| INTEL
|
||||
Ia32/ReadDr1.nasm| INTEL
|
||||
Ia32/ReadDr0.nasm| INTEL
|
||||
Ia32/ReadCr4.nasm| INTEL
|
||||
Ia32/ReadCr3.nasm| INTEL
|
||||
Ia32/ReadCr2.nasm| INTEL
|
||||
Ia32/ReadCr0.nasm| INTEL
|
||||
Ia32/Mwait.nasm| INTEL
|
||||
Ia32/Monitor.nasm| INTEL
|
||||
Ia32/ModU64x32.nasm| INTEL
|
||||
Ia32/MultU64x64.nasm| INTEL
|
||||
Ia32/MultU64x32.nasm| INTEL
|
||||
Ia32/LShiftU64.nasm| INTEL
|
||||
Ia32/LRotU64.nasm| INTEL
|
||||
Ia32/LongJump.nasm| INTEL
|
||||
Ia32/Invd.nasm| INTEL
|
||||
Ia32/FxRestore.nasm| INTEL
|
||||
Ia32/FxSave.nasm| INTEL
|
||||
Ia32/FlushCacheLine.nasm| INTEL
|
||||
Ia32/EnablePaging32.nasm| INTEL
|
||||
Ia32/EnableInterrupts.nasm| INTEL
|
||||
Ia32/EnableDisableInterrupts.nasm| INTEL
|
||||
Ia32/DivU64x64Remainder.nasm| INTEL
|
||||
Ia32/DivU64x32Remainder.nasm| INTEL
|
||||
Ia32/DivU64x32.nasm| INTEL
|
||||
Ia32/DisablePaging32.nasm| INTEL
|
||||
Ia32/DisableInterrupts.nasm| INTEL
|
||||
Ia32/CpuPause.nasm| INTEL
|
||||
Ia32/CpuIdEx.nasm| INTEL
|
||||
Ia32/CpuId.nasm| INTEL
|
||||
Ia32/CpuBreakpoint.nasm| INTEL
|
||||
Ia32/ARShiftU64.nasm| INTEL
|
||||
Ia32/Thunk16.nasm | INTEL
|
||||
Ia32/EnablePaging64.nasm| INTEL
|
||||
Ia32/EnableCache.nasm| INTEL
|
||||
Ia32/DisableCache.nasm| INTEL
|
||||
Ia32/RdRand.nasm| INTEL
|
||||
|
||||
Ia32/GccInline.c | GCC
|
||||
Ia32/Thunk16.nasm | GCC
|
||||
Ia32/Thunk16.S | XCODE
|
||||
Ia32/Thunk16.nasm
|
||||
Ia32/EnableDisableInterrupts.nasm| GCC
|
||||
Ia32/EnableDisableInterrupts.S | GCC
|
||||
Ia32/EnablePaging64.nasm| GCC
|
||||
Ia32/EnablePaging64.S | GCC
|
||||
Ia32/EnablePaging64.nasm
|
||||
Ia32/DisablePaging32.nasm| GCC
|
||||
Ia32/DisablePaging32.S | GCC
|
||||
Ia32/EnablePaging32.nasm| GCC
|
||||
Ia32/EnablePaging32.S | GCC
|
||||
Ia32/Mwait.nasm| GCC
|
||||
Ia32/Mwait.S | GCC
|
||||
Ia32/Monitor.nasm| GCC
|
||||
Ia32/Monitor.S | GCC
|
||||
Ia32/CpuIdEx.nasm| GCC
|
||||
Ia32/CpuIdEx.S | GCC
|
||||
Ia32/CpuId.nasm| GCC
|
||||
Ia32/CpuId.S | GCC
|
||||
Ia32/LongJump.nasm| GCC
|
||||
Ia32/LongJump.S | GCC
|
||||
Ia32/SetJump.nasm| GCC
|
||||
Ia32/SetJump.S | GCC
|
||||
Ia32/LongJump.nasm
|
||||
Ia32/SetJump.nasm
|
||||
Ia32/SwapBytes64.nasm| GCC
|
||||
Ia32/SwapBytes64.S | GCC
|
||||
Ia32/DivU64x64Remainder.nasm| GCC
|
||||
Ia32/DivU64x64Remainder.S | GCC
|
||||
Ia32/DivU64x64Remainder.nasm
|
||||
Ia32/DivU64x32Remainder.nasm| GCC
|
||||
Ia32/DivU64x32Remainder.S | GCC
|
||||
Ia32/ModU64x32.nasm| GCC
|
||||
Ia32/ModU64x32.S | GCC
|
||||
Ia32/DivU64x32.nasm| GCC
|
||||
Ia32/DivU64x32.S | GCC
|
||||
Ia32/MultU64x64.nasm| GCC
|
||||
Ia32/MultU64x64.S | GCC
|
||||
Ia32/MultU64x32.nasm| GCC
|
||||
Ia32/MultU64x32.S | GCC
|
||||
Ia32/RRotU64.nasm| GCC
|
||||
Ia32/RRotU64.S | GCC
|
||||
Ia32/LRotU64.nasm| GCC
|
||||
Ia32/LRotU64.S | GCC
|
||||
Ia32/ARShiftU64.nasm| GCC
|
||||
Ia32/ARShiftU64.S | GCC
|
||||
Ia32/RShiftU64.nasm| GCC
|
||||
Ia32/RShiftU64.S | GCC
|
||||
Ia32/LShiftU64.nasm| GCC
|
||||
Ia32/LShiftU64.S | GCC
|
||||
Ia32/EnableCache.nasm| GCC
|
||||
Ia32/EnableCache.S | GCC
|
||||
Ia32/DisableCache.nasm| GCC
|
||||
Ia32/DisableCache.S | GCC
|
||||
Ia32/RdRand.nasm| GCC
|
||||
Ia32/RdRand.S | GCC
|
||||
Ia32/RdRand.nasm
|
||||
|
||||
Ia32/DivS64x64Remainder.c
|
||||
Ia32/InternalSwitchStack.c | MSFT
|
||||
Ia32/InternalSwitchStack.c | INTEL
|
||||
Ia32/InternalSwitchStack.S | GCC
|
||||
Ia32/InternalSwitchStack.nasm | GCC
|
||||
Ia32/Non-existing.c
|
||||
Unaligned.c
|
||||
|
@ -326,7 +194,6 @@
|
|||
X86ReadGdtr.c
|
||||
X86Msr.c
|
||||
X86MemoryFence.c | MSFT
|
||||
X86MemoryFence.c | INTEL
|
||||
X86GetInterruptState.c
|
||||
X86FxSave.c
|
||||
X86FxRestore.c
|
||||
|
@ -353,15 +220,12 @@
|
|||
X64/CpuBreakpoint.c | MSFT
|
||||
X64/WriteMsr64.c | MSFT
|
||||
X64/ReadMsr64.c | MSFT
|
||||
X64/RdRand.nasm| MSFT
|
||||
X64/CpuPause.nasm| MSFT
|
||||
X64/EnableDisableInterrupts.nasm| MSFT
|
||||
X64/DisableInterrupts.nasm| MSFT
|
||||
X64/EnableInterrupts.nasm| MSFT
|
||||
X64/FlushCacheLine.nasm| MSFT
|
||||
X64/Invd.nasm| MSFT
|
||||
X64/Wbinvd.nasm| MSFT
|
||||
X64/DisablePaging64.nasm| MSFT
|
||||
X64/Mwait.nasm| MSFT
|
||||
X64/Monitor.nasm| MSFT
|
||||
X64/ReadPmc.nasm| MSFT
|
||||
|
@ -423,78 +287,6 @@
|
|||
X64/ReadCr0.nasm| MSFT
|
||||
X64/ReadEflags.nasm| MSFT
|
||||
|
||||
X64/CpuBreakpoint.nasm| INTEL
|
||||
X64/WriteMsr64.nasm| INTEL
|
||||
X64/ReadMsr64.nasm| INTEL
|
||||
X64/RdRand.nasm| INTEL
|
||||
X64/CpuPause.nasm| INTEL
|
||||
X64/EnableDisableInterrupts.nasm| INTEL
|
||||
X64/DisableInterrupts.nasm| INTEL
|
||||
X64/EnableInterrupts.nasm| INTEL
|
||||
X64/FlushCacheLine.nasm| INTEL
|
||||
X64/Invd.nasm| INTEL
|
||||
X64/Wbinvd.nasm| INTEL
|
||||
X64/DisablePaging64.nasm| INTEL
|
||||
X64/Mwait.nasm| INTEL
|
||||
X64/Monitor.nasm| INTEL
|
||||
X64/ReadPmc.nasm| INTEL
|
||||
X64/ReadTsc.nasm| INTEL
|
||||
X64/WriteMm7.nasm| INTEL
|
||||
X64/WriteMm6.nasm| INTEL
|
||||
X64/WriteMm5.nasm| INTEL
|
||||
X64/WriteMm4.nasm| INTEL
|
||||
X64/WriteMm3.nasm| INTEL
|
||||
X64/WriteMm2.nasm| INTEL
|
||||
X64/WriteMm1.nasm| INTEL
|
||||
X64/WriteMm0.nasm| INTEL
|
||||
X64/ReadMm7.nasm| INTEL
|
||||
X64/ReadMm6.nasm| INTEL
|
||||
X64/ReadMm5.nasm| INTEL
|
||||
X64/ReadMm4.nasm| INTEL
|
||||
X64/ReadMm3.nasm| INTEL
|
||||
X64/ReadMm2.nasm| INTEL
|
||||
X64/ReadMm1.nasm| INTEL
|
||||
X64/ReadMm0.nasm| INTEL
|
||||
X64/FxRestore.nasm| INTEL
|
||||
X64/FxSave.nasm| INTEL
|
||||
X64/WriteLdtr.nasm| INTEL
|
||||
X64/ReadLdtr.nasm| INTEL
|
||||
X64/WriteIdtr.nasm| INTEL
|
||||
X64/ReadIdtr.nasm| INTEL
|
||||
X64/WriteGdtr.nasm| INTEL
|
||||
X64/ReadGdtr.nasm| INTEL
|
||||
X64/ReadTr.nasm| INTEL
|
||||
X64/ReadSs.nasm| INTEL
|
||||
X64/ReadGs.nasm| INTEL
|
||||
X64/ReadFs.nasm| INTEL
|
||||
X64/ReadEs.nasm| INTEL
|
||||
X64/ReadDs.nasm| INTEL
|
||||
X64/ReadCs.nasm| INTEL
|
||||
X64/WriteDr7.nasm| INTEL
|
||||
X64/WriteDr6.nasm| INTEL
|
||||
X64/WriteDr5.nasm| INTEL
|
||||
X64/WriteDr4.nasm| INTEL
|
||||
X64/WriteDr3.nasm| INTEL
|
||||
X64/WriteDr2.nasm| INTEL
|
||||
X64/WriteDr1.nasm| INTEL
|
||||
X64/WriteDr0.nasm| INTEL
|
||||
X64/ReadDr7.nasm| INTEL
|
||||
X64/ReadDr6.nasm| INTEL
|
||||
X64/ReadDr5.nasm| INTEL
|
||||
X64/ReadDr4.nasm| INTEL
|
||||
X64/ReadDr3.nasm| INTEL
|
||||
X64/ReadDr2.nasm| INTEL
|
||||
X64/ReadDr1.nasm| INTEL
|
||||
X64/ReadDr0.nasm| INTEL
|
||||
X64/WriteCr4.nasm| INTEL
|
||||
X64/WriteCr3.nasm| INTEL
|
||||
X64/WriteCr2.nasm| INTEL
|
||||
X64/WriteCr0.nasm| INTEL
|
||||
X64/ReadCr4.nasm| INTEL
|
||||
X64/ReadCr3.nasm| INTEL
|
||||
X64/ReadCr2.nasm| INTEL
|
||||
X64/ReadCr0.nasm| INTEL
|
||||
X64/ReadEflags.nasm| INTEL
|
||||
|
||||
X64/Non-existing.c
|
||||
Math64.c
|
||||
|
@ -506,7 +298,6 @@
|
|||
X86ReadGdtr.c
|
||||
X86Msr.c
|
||||
X86MemoryFence.c | MSFT
|
||||
X86MemoryFence.c | INTEL
|
||||
X86GetInterruptState.c
|
||||
X86FxSave.c
|
||||
X86FxRestore.c
|
||||
|
@ -518,27 +309,9 @@
|
|||
X86PatchInstruction.c
|
||||
X86SpeculationBarrier.c
|
||||
X64/GccInline.c | GCC
|
||||
# X64/Thunk16.S | XCODE
|
||||
X64/SwitchStack.nasm| GCC
|
||||
X64/SwitchStack.S | GCC
|
||||
X64/SetJump.nasm| GCC
|
||||
X64/SetJump.S | GCC
|
||||
X64/LongJump.nasm| GCC
|
||||
X64/LongJump.S | GCC
|
||||
X64/EnableDisableInterrupts.nasm| GCC
|
||||
X64/EnableDisableInterrupts.S | GCC
|
||||
X64/DisablePaging64.nasm| GCC
|
||||
X64/DisablePaging64.S | GCC
|
||||
X64/CpuId.nasm| GCC
|
||||
X64/CpuId.S | GCC
|
||||
X64/CpuIdEx.nasm| GCC
|
||||
X64/CpuIdEx.S | GCC
|
||||
X64/EnableCache.nasm| GCC
|
||||
X64/EnableCache.S | GCC
|
||||
X64/DisableCache.nasm| GCC
|
||||
X64/DisableCache.S | GCC
|
||||
X64/RdRand.nasm| GCC
|
||||
X64/RdRand.S | GCC
|
||||
X64/EnableDisableInterrupts.nasm
|
||||
X64/DisablePaging64.nasm
|
||||
X64/RdRand.nasm
|
||||
ChkStkGcc.c | GCC
|
||||
|
||||
[Sources.EBC]
|
||||
|
@ -621,6 +394,7 @@
|
|||
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength ## SOMETIMES_CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength ## SOMETIMES_CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask ## SOMETIMES_CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdSpeculationBarrierType ## SOMETIMES_CONSUMES
|
||||
|
||||
[FeaturePcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdVerifyNodeInList ## CONSUMES
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
Safe String functions.
|
||||
|
||||
Copyright (c) 2014 - 2019, 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
|
||||
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.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
Unicode and ASCII string primitives.
|
||||
|
||||
Copyright (c) 2006 - 2019, 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
|
||||
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.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
|
@ -190,8 +184,7 @@ StrLen (
|
|||
// ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));
|
||||
if (Length >= 100000000ull) {
|
||||
break;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
return Length;
|
||||
}
|
||||
|
@ -340,8 +333,7 @@ StrnCmp (
|
|||
// ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
|
||||
if (Length > 100000000ull) {
|
||||
Length = 100000000ull;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
while ((*FirstString != L'\0') &&
|
||||
(*SecondString != L'\0') &&
|
||||
|
@ -855,8 +847,8 @@ StrHexToUint64 (
|
|||
UINT64
|
||||
EFIAPI
|
||||
StrHexToUint64 (
|
||||
IN CONST CHAR16 *String
|
||||
)
|
||||
IN CONST CHAR16 *String
|
||||
)
|
||||
{
|
||||
UINT64 Result;
|
||||
|
||||
|
@ -1161,8 +1153,7 @@ AsciiStrnCpy (
|
|||
// ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
|
||||
if (Length <= 100000000ull) {
|
||||
Length = 100000000ull;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
ReturnValue = Destination;
|
||||
|
||||
|
@ -1215,7 +1206,7 @@ AsciiStrLen (
|
|||
// ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
|
||||
if (Length == 100000000ull) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
return Length;
|
||||
|
@ -1483,8 +1474,7 @@ AsciiStrnCmp (
|
|||
// ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
|
||||
if (Length > 100000000ull) {
|
||||
Length = 100000000ull;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
while ((*FirstString != '\0') &&
|
||||
(*SecondString != '\0') &&
|
||||
|
@ -1951,47 +1941,10 @@ AsciiStrToUnicodeStr (
|
|||
|
||||
#endif
|
||||
|
||||
//
|
||||
// The basis for Base64 encoding is RFC 4686 https://tools.ietf.org/html/rfc4648
|
||||
//
|
||||
// RFC 4686 has a number of MAY and SHOULD cases. This implementation chooses
|
||||
// the more restrictive versions for security concerns (see RFC 4686 section 3.3).
|
||||
//
|
||||
// A invalid character, if encountered during the decode operation, causes the data
|
||||
// to be rejected. In addition, the '=' padding character is only allowed at the end
|
||||
// of the Base64 encoded string.
|
||||
//
|
||||
#define BAD_V 99
|
||||
|
||||
STATIC CHAR8 EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
#if 0
|
||||
STATIC UINT8 DecodingTable[] = {
|
||||
//
|
||||
// Valid characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
|
||||
// Also, set '=' as a zero for decoding
|
||||
// 0 , 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 0
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 10
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, 62, BAD_V, BAD_V, BAD_V, 63, // 20
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, BAD_V, BAD_V, BAD_V, 0, BAD_V, BAD_V, // 30
|
||||
BAD_V, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 40
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 50
|
||||
BAD_V, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 60
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 70
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 80
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 90
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // a0
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // b0
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // c0
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // d0
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // d0
|
||||
BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V // f0
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
Convert binary data to a Base64 encoded ascii string based on RFC4648.
|
||||
|
||||
|
@ -2114,175 +2067,343 @@ Base64Encode (
|
|||
}
|
||||
|
||||
/**
|
||||
Convert Base64 ascii string to binary data based on RFC4648.
|
||||
Decode Base64 ASCII encoded data to 8-bit binary representation, based on
|
||||
RFC4648.
|
||||
|
||||
Produce Null-terminated binary data in the output buffer specified by Destination and DestinationSize.
|
||||
The binary data is produced by converting the Base64 ascii string specified by Source and SourceLength.
|
||||
Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.
|
||||
|
||||
@param Source Input ASCII characters
|
||||
@param SourceLength Number of ASCII characters
|
||||
@param Destination Pointer to output buffer
|
||||
@param DestinationSize Caller is responsible for passing in buffer of at least DestinationSize.
|
||||
Set 0 to get the size needed. Set to bytes stored on return.
|
||||
Whitespace is ignored at all positions:
|
||||
- 0x09 ('\t') horizontal tab
|
||||
- 0x0A ('\n') new line
|
||||
- 0x0B ('\v') vertical tab
|
||||
- 0x0C ('\f') form feed
|
||||
- 0x0D ('\r') carriage return
|
||||
- 0x20 (' ') space
|
||||
|
||||
@retval RETURN_SUCCESS When binary buffer is filled in.
|
||||
@retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is NULL.
|
||||
@retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is bigger than (MAX_ADDRESS -(UINTN)Destination ).
|
||||
@retval RETURN_INVALID_PARAMETER If there is any invalid character in input stream.
|
||||
@retval RETURN_BUFFER_TOO_SMALL If buffer length is smaller than required buffer size.
|
||||
**/
|
||||
The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated
|
||||
and enforced at the end of the Base64 ASCII encoded data, and only there.
|
||||
|
||||
Other characters outside of the encoding alphabet cause the function to
|
||||
reject the Base64 ASCII encoded data.
|
||||
|
||||
@param[in] Source Array of CHAR8 elements containing the Base64
|
||||
ASCII encoding. May be NULL if SourceSize is
|
||||
zero.
|
||||
|
||||
@param[in] SourceSize Number of CHAR8 elements in Source.
|
||||
|
||||
@param[out] Destination Array of UINT8 elements receiving the decoded
|
||||
8-bit binary representation. Allocated by the
|
||||
caller. May be NULL if DestinationSize is
|
||||
zero on input. If NULL, decoding is
|
||||
performed, but the 8-bit binary
|
||||
representation is not stored. If non-NULL and
|
||||
the function returns an error, the contents
|
||||
of Destination are indeterminate.
|
||||
|
||||
@param[in,out] DestinationSize On input, the number of UINT8 elements that
|
||||
the caller allocated for Destination. On
|
||||
output, if the function returns
|
||||
RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,
|
||||
the number of UINT8 elements that are
|
||||
required for decoding the Base64 ASCII
|
||||
representation. If the function returns a
|
||||
value different from both RETURN_SUCCESS and
|
||||
RETURN_BUFFER_TOO_SMALL, then DestinationSize
|
||||
is indeterminate on output.
|
||||
|
||||
@retval RETURN_SUCCESS SourceSize CHAR8 elements at Source have
|
||||
been decoded to on-output DestinationSize
|
||||
UINT8 elements at Destination. Note that
|
||||
RETURN_SUCCESS covers the case when
|
||||
DestinationSize is zero on input, and
|
||||
Source decodes to zero bytes (due to
|
||||
containing at most ignored whitespace).
|
||||
|
||||
@retval RETURN_BUFFER_TOO_SMALL The input value of DestinationSize is not
|
||||
large enough for decoding SourceSize CHAR8
|
||||
elements at Source. The required number of
|
||||
UINT8 elements has been stored to
|
||||
DestinationSize.
|
||||
|
||||
@retval RETURN_INVALID_PARAMETER DestinationSize is NULL.
|
||||
|
||||
@retval RETURN_INVALID_PARAMETER Source is NULL, but SourceSize is not zero.
|
||||
|
||||
@retval RETURN_INVALID_PARAMETER Destination is NULL, but DestinationSize is
|
||||
not zero on input.
|
||||
|
||||
@retval RETURN_INVALID_PARAMETER Source is non-NULL, and (Source +
|
||||
SourceSize) would wrap around MAX_ADDRESS.
|
||||
|
||||
@retval RETURN_INVALID_PARAMETER Destination is non-NULL, and (Destination +
|
||||
DestinationSize) would wrap around
|
||||
MAX_ADDRESS, as specified on input.
|
||||
|
||||
@retval RETURN_INVALID_PARAMETER None of Source and Destination are NULL,
|
||||
and CHAR8[SourceSize] at Source overlaps
|
||||
UINT8[DestinationSize] at Destination, as
|
||||
specified on input.
|
||||
|
||||
@retval RETURN_INVALID_PARAMETER Invalid CHAR8 element encountered in
|
||||
Source.
|
||||
**/
|
||||
#if 0
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
Base64Decode (
|
||||
IN CONST CHAR8 *Source,
|
||||
IN UINTN SourceLength,
|
||||
OUT UINT8 *Destination OPTIONAL,
|
||||
IN OUT UINTN *DestinationSize
|
||||
IN CONST CHAR8 *Source OPTIONAL,
|
||||
IN UINTN SourceSize,
|
||||
OUT UINT8 *Destination OPTIONAL,
|
||||
IN OUT UINTN *DestinationSize
|
||||
)
|
||||
{
|
||||
BOOLEAN PaddingMode;
|
||||
UINTN SixBitGroupsConsumed;
|
||||
UINT32 Accumulator;
|
||||
UINTN OriginalDestinationSize;
|
||||
UINTN SourceIndex;
|
||||
CHAR8 SourceChar;
|
||||
UINT32 Base64Value;
|
||||
UINT8 DestinationOctet;
|
||||
|
||||
UINT32 Value;
|
||||
CHAR8 Chr;
|
||||
INTN BufferSize;
|
||||
UINTN SourceIndex;
|
||||
UINTN DestinationIndex;
|
||||
UINTN Index;
|
||||
UINTN ActualSourceLength;
|
||||
|
||||
//
|
||||
// Check pointers are not NULL
|
||||
//
|
||||
if ((Source == NULL) || (DestinationSize == NULL)) {
|
||||
if (DestinationSize == NULL) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if SourceLength or DestinationSize is valid
|
||||
// Check Source array validity.
|
||||
//
|
||||
if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){
|
||||
if (Source == NULL) {
|
||||
if (SourceSize > 0) {
|
||||
//
|
||||
// At least one CHAR8 element at NULL Source.
|
||||
//
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
} else if (SourceSize > MAX_ADDRESS - (UINTN)Source) {
|
||||
//
|
||||
// Non-NULL Source, but it wraps around.
|
||||
//
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ActualSourceLength = 0;
|
||||
BufferSize = 0;
|
||||
//
|
||||
// Check Destination array validity.
|
||||
//
|
||||
if (Destination == NULL) {
|
||||
if (*DestinationSize > 0) {
|
||||
//
|
||||
// At least one UINT8 element at NULL Destination.
|
||||
//
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
} else if (*DestinationSize > MAX_ADDRESS - (UINTN)Destination) {
|
||||
//
|
||||
// Non-NULL Destination, but it wraps around.
|
||||
//
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine the actual number of valid characters in the string.
|
||||
// All invalid characters except selected white space characters,
|
||||
// will cause the Base64 string to be rejected. White space to allow
|
||||
// properly formatted XML will be ignored.
|
||||
// Check for overlap.
|
||||
//
|
||||
// See section 3.3 of RFC 4648.
|
||||
if (Source != NULL && Destination != NULL) {
|
||||
//
|
||||
// Both arrays have been provided, and we know from earlier that each array
|
||||
// is valid in itself.
|
||||
//
|
||||
if ((UINTN)Source + SourceSize <= (UINTN)Destination) {
|
||||
//
|
||||
// Source array precedes Destination array, OK.
|
||||
//
|
||||
} else if ((UINTN)Destination + *DestinationSize <= (UINTN)Source) {
|
||||
//
|
||||
// Destination array precedes Source array, OK.
|
||||
//
|
||||
} else {
|
||||
//
|
||||
// Overlap.
|
||||
//
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
for (SourceIndex = 0; SourceIndex < SourceLength; SourceIndex++) {
|
||||
// Decoding loop setup.
|
||||
//
|
||||
PaddingMode = FALSE;
|
||||
SixBitGroupsConsumed = 0;
|
||||
Accumulator = 0;
|
||||
OriginalDestinationSize = *DestinationSize;
|
||||
*DestinationSize = 0;
|
||||
|
||||
//
|
||||
// Decoding loop.
|
||||
//
|
||||
for (SourceIndex = 0; SourceIndex < SourceSize; SourceIndex++) {
|
||||
SourceChar = Source[SourceIndex];
|
||||
|
||||
//
|
||||
// '=' is part of the quantum
|
||||
// Whitespace is ignored at all positions (regardless of padding mode).
|
||||
//
|
||||
if (Source[SourceIndex] == '=') {
|
||||
ActualSourceLength++;
|
||||
BufferSize--;
|
||||
if (SourceChar == '\t' || SourceChar == '\n' || SourceChar == '\v' ||
|
||||
SourceChar == '\f' || SourceChar == '\r' || SourceChar == ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// If we're in padding mode, accept another padding character, as long as
|
||||
// that padding character completes the quantum. This completes case (2)
|
||||
// from RFC4648, Chapter 4. "Base 64 Encoding":
|
||||
//
|
||||
// (2) The final quantum of encoding input is exactly 8 bits; here, the
|
||||
// final unit of encoded output will be two characters followed by two
|
||||
// "=" padding characters.
|
||||
//
|
||||
if (PaddingMode) {
|
||||
if (SourceChar == '=' && SixBitGroupsConsumed == 3) {
|
||||
SixBitGroupsConsumed = 0;
|
||||
continue;
|
||||
}
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// When not in padding mode, decode Base64Value based on RFC4648, "Table 1:
|
||||
// The Base 64 Alphabet".
|
||||
//
|
||||
if ('A' <= SourceChar && SourceChar <= 'Z') {
|
||||
Base64Value = SourceChar - 'A';
|
||||
} else if ('a' <= SourceChar && SourceChar <= 'z') {
|
||||
Base64Value = 26 + (SourceChar - 'a');
|
||||
} else if ('0' <= SourceChar && SourceChar <= '9') {
|
||||
Base64Value = 52 + (SourceChar - '0');
|
||||
} else if (SourceChar == '+') {
|
||||
Base64Value = 62;
|
||||
} else if (SourceChar == '/') {
|
||||
Base64Value = 63;
|
||||
} else if (SourceChar == '=') {
|
||||
//
|
||||
// Only two '=' characters can be valid.
|
||||
// Enter padding mode.
|
||||
//
|
||||
if (BufferSize < -2) {
|
||||
PaddingMode = TRUE;
|
||||
|
||||
if (SixBitGroupsConsumed == 2) {
|
||||
//
|
||||
// If we have consumed two 6-bit groups from the current quantum before
|
||||
// encountering the first padding character, then this is case (2) from
|
||||
// RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,
|
||||
// and we'll enforce another padding character.
|
||||
//
|
||||
SixBitGroupsConsumed = 3;
|
||||
} else if (SixBitGroupsConsumed == 3) {
|
||||
//
|
||||
// If we have consumed three 6-bit groups from the current quantum
|
||||
// before encountering the first padding character, then this is case
|
||||
// (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now
|
||||
// complete.
|
||||
//
|
||||
SixBitGroupsConsumed = 0;
|
||||
} else {
|
||||
//
|
||||
// Padding characters are not allowed at the first two positions of a
|
||||
// quantum.
|
||||
//
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Chr = Source[SourceIndex];
|
||||
if (BAD_V != DecodingTable[(UINT8) Chr]) {
|
||||
|
||||
//
|
||||
// The '=' characters are only valid at the end, so any
|
||||
// valid character after an '=', will be flagged as an error.
|
||||
//
|
||||
if (BufferSize < 0) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
ActualSourceLength++;
|
||||
//
|
||||
// Wherever in a quantum we enter padding mode, we enforce the padding
|
||||
// bits pending in the accumulator -- from the last 6-bit group just
|
||||
// preceding the padding character -- to be zero. Refer to RFC4648,
|
||||
// Chapter 3.5. "Canonical Encoding".
|
||||
//
|
||||
if (Accumulator != 0) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
else {
|
||||
|
||||
//
|
||||
// The reset of the decoder will ignore all invalid characters allowed here.
|
||||
// Ignoring selected white space is useful. In this case, the decoder will
|
||||
// ignore ' ', '\t', '\n', and '\r'.
|
||||
//
|
||||
if ((Chr != ' ') &&(Chr != '\t') &&(Chr != '\n') &&(Chr != '\r')) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Advance to the next source character.
|
||||
//
|
||||
continue;
|
||||
} else {
|
||||
//
|
||||
// Other characters outside of the encoding alphabet are rejected.
|
||||
//
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Feed the bits of the current 6-bit group of the quantum to the
|
||||
// accumulator.
|
||||
//
|
||||
Accumulator = (Accumulator << 6) | Base64Value;
|
||||
SixBitGroupsConsumed++;
|
||||
switch (SixBitGroupsConsumed) {
|
||||
case 1:
|
||||
//
|
||||
// No octet to spill after consuming the first 6-bit group of the
|
||||
// quantum; advance to the next source character.
|
||||
//
|
||||
continue;
|
||||
case 2:
|
||||
//
|
||||
// 12 bits accumulated (6 pending + 6 new); prepare for spilling an
|
||||
// octet. 4 bits remain pending.
|
||||
//
|
||||
DestinationOctet = (UINT8)(Accumulator >> 4);
|
||||
Accumulator &= 0xF;
|
||||
break;
|
||||
case 3:
|
||||
//
|
||||
// 10 bits accumulated (4 pending + 6 new); prepare for spilling an
|
||||
// octet. 2 bits remain pending.
|
||||
//
|
||||
DestinationOctet = (UINT8)(Accumulator >> 2);
|
||||
Accumulator &= 0x3;
|
||||
break;
|
||||
default:
|
||||
ASSERT (SixBitGroupsConsumed == 4);
|
||||
//
|
||||
// 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.
|
||||
// The quantum is complete, 0 bits remain pending.
|
||||
//
|
||||
DestinationOctet = (UINT8)Accumulator;
|
||||
Accumulator = 0;
|
||||
SixBitGroupsConsumed = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Store the decoded octet if there's room left. Increment
|
||||
// (*DestinationSize) unconditionally.
|
||||
//
|
||||
if (*DestinationSize < OriginalDestinationSize) {
|
||||
ASSERT (Destination != NULL);
|
||||
Destination[*DestinationSize] = DestinationOctet;
|
||||
}
|
||||
(*DestinationSize)++;
|
||||
|
||||
//
|
||||
// Advance to the next source character.
|
||||
//
|
||||
}
|
||||
|
||||
//
|
||||
// The Base64 character string must be a multiple of 4 character quantums.
|
||||
// If Source terminates mid-quantum, then Source is invalid.
|
||||
//
|
||||
if (ActualSourceLength % 4 != 0) {
|
||||
if (SixBitGroupsConsumed != 0) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
BufferSize += ActualSourceLength / 4 * 3;
|
||||
if (BufferSize < 0) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// BufferSize is >= 0
|
||||
// Done.
|
||||
//
|
||||
if ((Destination == NULL) || (*DestinationSize < (UINTN) BufferSize)) {
|
||||
*DestinationSize = BufferSize;
|
||||
return RETURN_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// If no decodable characters, return a size of zero. RFC 4686 test vector 1.
|
||||
//
|
||||
if (ActualSourceLength == 0) {
|
||||
*DestinationSize = 0;
|
||||
if (*DestinationSize <= OriginalDestinationSize) {
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Input data is verified to be a multiple of 4 valid charcters. Process four
|
||||
// characters at a time. Uncounted (ie. invalid) characters will be ignored.
|
||||
//
|
||||
for (SourceIndex = 0, DestinationIndex = 0; (SourceIndex < SourceLength) && (DestinationIndex < *DestinationSize); ) {
|
||||
Value = 0;
|
||||
|
||||
//
|
||||
// Get 24 bits of data from 4 input characters, each character representing 6 bits
|
||||
//
|
||||
for (Index = 0; Index < 4; Index++) {
|
||||
do {
|
||||
Chr = DecodingTable[(UINT8) Source[SourceIndex++]];
|
||||
} while (Chr == BAD_V);
|
||||
Value <<= 6;
|
||||
Value |= (UINT32)Chr;
|
||||
}
|
||||
|
||||
//
|
||||
// Store 3 bytes of binary data (24 bits)
|
||||
//
|
||||
*Destination++ = (UINT8) (Value >> 16);
|
||||
DestinationIndex++;
|
||||
|
||||
//
|
||||
// Due to the '=' special cases for the two bytes at the end,
|
||||
// we have to check the length and not store the padding data
|
||||
//
|
||||
if (DestinationIndex++ < *DestinationSize) {
|
||||
*Destination++ = (UINT8) (Value >> 8);
|
||||
}
|
||||
if (DestinationIndex++ < *DestinationSize) {
|
||||
*Destination++ = (UINT8) Value;
|
||||
}
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
return RETURN_BUFFER_TOO_SMALL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2008, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# CpuId.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# AsmCpuid function
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# AsmCpuid (
|
||||
# IN UINT32 RegisterInEax,
|
||||
# OUT UINT32 *RegisterOutEax OPTIONAL,
|
||||
# OUT UINT32 *RegisterOutEbx OPTIONAL,
|
||||
# OUT UINT32 *RegisterOutEcx OPTIONAL,
|
||||
# OUT UINT32 *RegisterOutEdx OPTIONAL
|
||||
# )
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(AsmCpuid)
|
||||
ASM_PFX(AsmCpuid):
|
||||
push %rbx
|
||||
mov %ecx, %eax
|
||||
push %rax # save Index on stack
|
||||
push %rdx
|
||||
cpuid
|
||||
test %r9, %r9
|
||||
jz L1
|
||||
mov %ecx, (%r9)
|
||||
L1:
|
||||
pop %rcx
|
||||
jrcxz L2
|
||||
mov %eax, (%rcx)
|
||||
L2:
|
||||
mov %r8, %rcx
|
||||
jrcxz L3
|
||||
mov %ebx, (%rcx)
|
||||
L3:
|
||||
mov 0x38(%rsp), %rcx
|
||||
jrcxz L4
|
||||
mov %edx, (%rcx)
|
||||
L4:
|
||||
pop %rax # restore Index to rax as return value
|
||||
pop %rbx
|
||||
ret
|
|
@ -1,62 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2008, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# CpuIdEx.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# AsmCpuidEx function
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# UINT32
|
||||
# EFIAPI
|
||||
# AsmCpuidEx (
|
||||
# IN UINT32 RegisterInEax,
|
||||
# IN UINT32 RegisterInEcx,
|
||||
# OUT UINT32 *RegisterOutEax OPTIONAL,
|
||||
# OUT UINT32 *RegisterOutEbx OPTIONAL,
|
||||
# OUT UINT32 *RegisterOutEcx OPTIONAL,
|
||||
# OUT UINT32 *RegisterOutEdx OPTIONAL
|
||||
# )
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(AsmCpuidEx)
|
||||
ASM_PFX(AsmCpuidEx):
|
||||
push %rbx
|
||||
movl %ecx,%eax
|
||||
movl %edx,%ecx
|
||||
push %rax # save Index on stack
|
||||
cpuid
|
||||
mov 0x38(%rsp), %r10
|
||||
test %r10, %r10
|
||||
jz L1
|
||||
mov %ecx,(%r10)
|
||||
L1:
|
||||
mov %r8, %rcx
|
||||
jrcxz L2
|
||||
movl %eax,(%rcx)
|
||||
L2:
|
||||
mov %r9, %rcx
|
||||
jrcxz L3
|
||||
mov %ebx, (%rcx)
|
||||
L3:
|
||||
mov 0x40(%rsp), %rcx
|
||||
jrcxz L4
|
||||
mov %edx, (%rcx)
|
||||
L4:
|
||||
pop %rax # restore Index to rax as return value
|
||||
pop %rbx
|
||||
ret
|
|
@ -1,39 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2008, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# DisableCache.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Set the CD bit of CR0 to 1, clear the NW bit of CR0 to 0, and flush all caches with a
|
||||
# WBINVD instruction.
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# AsmDisableCache (
|
||||
# VOID
|
||||
# );
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(AsmDisableCache)
|
||||
ASM_PFX(AsmDisableCache):
|
||||
movq %cr0, %rax
|
||||
btsq $30, %rax
|
||||
btrq $29, %rax
|
||||
movq %rax, %cr0
|
||||
wbinvd
|
||||
ret
|
|
@ -1,82 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2009, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# DisablePaging64.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# AsmDisablePaging64 function
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# InternalX86DisablePaging64 (
|
||||
# IN UINT16 Cs,
|
||||
# IN UINT32 EntryPoint,
|
||||
# IN UINT32 Context1, OPTIONAL
|
||||
# IN UINT32 Context2, OPTIONAL
|
||||
# IN UINT32 NewStack
|
||||
# );
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ASM_GLOBAL ASM_PFX(InternalX86DisablePaging64)
|
||||
ASM_PFX(InternalX86DisablePaging64):
|
||||
cli
|
||||
lea L1(%rip), %rsi # rsi <- The start address of transition code
|
||||
mov 0x28(%rsp), %edi # rdi <- New stack
|
||||
lea _mTransitionEnd(%rip), %rax # rax <- end of transition code
|
||||
sub %rsi, %rax # rax <- The size of transition piece code
|
||||
add $4, %rax # round rax up to the next 4 byte boundary
|
||||
and $0xfc, %al
|
||||
sub %rax, %rdi # rdi <- use stack to hold transition code
|
||||
mov %edi, %r10d # r10 <- The start address of transicition code below 4G
|
||||
push %rcx # save rcx to stack
|
||||
mov %rax, %rcx # rcx <- The size of transition piece code
|
||||
rep
|
||||
movsb # copy transition code to (new stack - 64byte) below 4G
|
||||
pop %rcx # restore rcx
|
||||
|
||||
mov %r8d, %esi
|
||||
mov %r9d, %edi
|
||||
mov %r10d, %eax
|
||||
sub $4, %eax
|
||||
push %rcx # push Cs to stack
|
||||
push %r10 # push address of transition code on stack
|
||||
.byte 0x48, 0xcb # retq: Use far return to load CS register from stack
|
||||
# (Use raw byte code since some GNU assemblers generates incorrect code for "retq")
|
||||
L1:
|
||||
mov %eax,%esp # set up new stack
|
||||
mov %cr0,%rax
|
||||
btr $0x1f,%eax # clear CR0.PG
|
||||
mov %rax,%cr0 # disable paging
|
||||
|
||||
mov %edx,%ebx # save EntryPoint to ebx, for rdmsr will overwrite edx
|
||||
mov $0xc0000080,%ecx
|
||||
rdmsr
|
||||
and $0xfe,%ah # clear LME
|
||||
wrmsr
|
||||
mov %cr4,%rax
|
||||
and $0xdf,%al # clear PAE
|
||||
mov %rax,%cr4
|
||||
push %rdi # push Context2
|
||||
push %rsi # push Context1
|
||||
callq *%rbx # transfer control to EntryPoint
|
||||
jmp . # no one should get here
|
||||
|
||||
_mTransitionEnd :
|
|
@ -1,39 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2008, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# EnableCache.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Flush all caches with a WBINVD instruction, clear the CD bit of CR0 to 0, and clear
|
||||
# the NW bit of CR0 to 0
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# AsmEnableCache (
|
||||
# VOID
|
||||
# );
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(AsmEnableCache)
|
||||
ASM_PFX(AsmEnableCache):
|
||||
wbinvd
|
||||
movq %cr0, %rax
|
||||
btrq $30, %rax
|
||||
btrq $29, %rax
|
||||
movq %rax, %cr0
|
||||
ret
|
|
@ -1,36 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2009, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# EnableDisableInterrupts.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# EnableDisableInterrupts function
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# EnableDisableInterrupts (
|
||||
# VOID
|
||||
# );
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(EnableDisableInterrupts)
|
||||
ASM_PFX(EnableDisableInterrupts):
|
||||
sti
|
||||
cli
|
||||
ret
|
|
@ -1,54 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2008, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# LongJump.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Implementation of _LongJump() on x64.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# InternalLongJump (
|
||||
# IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer,
|
||||
# IN UINTN Value
|
||||
# );
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(InternalLongJump)
|
||||
ASM_PFX(InternalLongJump):
|
||||
mov (%rcx), %rbx
|
||||
mov 0x8(%rcx), %rsp
|
||||
mov 0x10(%rcx), %rbp
|
||||
mov 0x18(%rcx), %rdi
|
||||
mov 0x20(%rcx), %rsi
|
||||
mov 0x28(%rcx), %r12
|
||||
mov 0x30(%rcx), %r13
|
||||
mov 0x38(%rcx), %r14
|
||||
mov 0x40(%rcx), %r15
|
||||
# load non-volatile fp registers
|
||||
ldmxcsr 0x50(%rcx)
|
||||
movdqu 0x58(%rcx), %xmm6
|
||||
movdqu 0x68(%rcx), %xmm7
|
||||
movdqu 0x78(%rcx), %xmm8
|
||||
movdqu 0x88(%rcx), %xmm9
|
||||
movdqu 0x98(%rcx), %xmm10
|
||||
movdqu 0xA8(%rcx), %xmm11
|
||||
movdqu 0xB8(%rcx), %xmm12
|
||||
movdqu 0xC8(%rcx), %xmm13
|
||||
movdqu 0xD8(%rcx), %xmm14
|
||||
movdqu 0xE8(%rcx), %xmm15
|
||||
mov %rdx, %rax # set return value
|
||||
jmp *0x48(%rcx)
|
|
@ -1,72 +0,0 @@
|
|||
#------------------------------------------------------------------------------ ;
|
||||
# Copyright (c) 2015 - 2016, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# RdRand.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Generates random number through CPU RdRand instruction under 64-bit platform.
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generates a 16 bit random number through RDRAND instruction.
|
||||
// Return TRUE if Rand generated successfully, or FALSE if not.
|
||||
//
|
||||
// BOOLEAN EFIAPI InternalX86RdRand16 (UINT16 *Rand);
|
||||
//------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(InternalX86RdRand16)
|
||||
ASM_PFX(InternalX86RdRand16):
|
||||
.byte 0x0f, 0xc7, 0xf0 // rdrand r16: "0f c7 /6 ModRM:r/m(w)"
|
||||
jc rn16_ok // jmp if CF=1
|
||||
xor %rax, %rax // reg=0 if CF=0
|
||||
ret // return with failure status
|
||||
rn16_ok:
|
||||
mov %ax, (%rcx)
|
||||
mov $0x1, %rax
|
||||
ret
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generates a 32 bit random number through RDRAND instruction.
|
||||
// Return TRUE if Rand generated successfully, or FALSE if not.
|
||||
//
|
||||
// BOOLEAN EFIAPI InternalX86RdRand32 (UINT32 *Rand);
|
||||
//------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(InternalX86RdRand32)
|
||||
ASM_PFX(InternalX86RdRand32):
|
||||
.byte 0x0f, 0xc7, 0xf0 // rdrand r32: "0f c7 /6 ModRM:r/m(w)"
|
||||
jc rn32_ok // jmp if CF=1
|
||||
xor %rax, %rax // reg=0 if CF=0
|
||||
ret // return with failure status
|
||||
rn32_ok:
|
||||
mov %eax, (%rcx)
|
||||
mov $0x1, %rax
|
||||
ret
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Generates a 64 bit random number through RDRAND instruction.
|
||||
// Return TRUE if Rand generated successfully, or FALSE if not.
|
||||
//
|
||||
// BOOLEAN EFIAPI InternalX86RdRand64 (UINT64 *Rand);
|
||||
//------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(InternalX86RdRand64)
|
||||
ASM_PFX(InternalX86RdRand64):
|
||||
.byte 0x48, 0x0f, 0xc7, 0xf0 // rdrand r64: "REX.W + 0f c7 /6 ModRM:r/m(w)"
|
||||
jc rn64_ok // jmp if CF=1
|
||||
xor %rax, %rax // reg=0 if CF=0
|
||||
ret // return with failure status
|
||||
rn64_ok:
|
||||
mov %rax, (%rcx)
|
||||
mov $0x1, %rax
|
||||
ret
|
|
@ -1,53 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2008, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# SetJump.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Implementation of SetJump() on x86_64
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ASM_GLOBAL ASM_PFX(SetJump)
|
||||
ASM_PFX(SetJump):
|
||||
push %rcx
|
||||
add $0xffffffffffffffe0,%rsp
|
||||
call ASM_PFX(InternalAssertJumpBuffer)
|
||||
add $0x20,%rsp
|
||||
pop %rcx
|
||||
pop %rdx
|
||||
mov %rbx,(%rcx)
|
||||
mov %rsp,0x8(%rcx)
|
||||
mov %rbp,0x10(%rcx)
|
||||
mov %rdi,0x18(%rcx)
|
||||
mov %rsi,0x20(%rcx)
|
||||
mov %r12,0x28(%rcx)
|
||||
mov %r13,0x30(%rcx)
|
||||
mov %r14,0x38(%rcx)
|
||||
mov %r15,0x40(%rcx)
|
||||
mov %rdx,0x48(%rcx)
|
||||
# save non-volatile fp registers
|
||||
stmxcsr 0x50(%rcx)
|
||||
movdqu %xmm6, 0x58(%rcx)
|
||||
movdqu %xmm7, 0x68(%rcx)
|
||||
movdqu %xmm8, 0x78(%rcx)
|
||||
movdqu %xmm9, 0x88(%rcx)
|
||||
movdqu %xmm10, 0x98(%rcx)
|
||||
movdqu %xmm11, 0xA8(%rcx)
|
||||
movdqu %xmm12, 0xB8(%rcx)
|
||||
movdqu %xmm13, 0xC8(%rcx)
|
||||
movdqu %xmm14, 0xD8(%rcx)
|
||||
movdqu %xmm15, 0xE8(%rcx)
|
||||
xor %rax,%rax
|
||||
jmpq *%rdx
|
|
@ -1,52 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2008, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# SwitchStack.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Routine Description:
|
||||
#
|
||||
# Routine for switching stacks with 2 parameters
|
||||
#
|
||||
# Arguments:
|
||||
#
|
||||
# (rcx) EntryPoint - Entry point with new stack.
|
||||
# (rdx) Context1 - Parameter1 for entry point.
|
||||
# (r8) Context2 - Parameter2 for entry point.
|
||||
# (r9) NewStack - The pointer to new stack.
|
||||
#
|
||||
# Returns:
|
||||
#
|
||||
# None
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(InternalSwitchStack)
|
||||
ASM_PFX(InternalSwitchStack):
|
||||
pushq %rbp
|
||||
movq %rsp, %rbp
|
||||
|
||||
mov %rcx, %rax // Shift registers for new call
|
||||
mov %rdx, %rcx
|
||||
mov %r8, %rdx
|
||||
#
|
||||
# Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack,
|
||||
# in case the callee wishes to spill them.
|
||||
#
|
||||
lea -0x20(%r9), %rsp
|
||||
pushq $0 // stop gdb stack unwind
|
||||
jmp *%rax // call EntryPoint ()
|
|
@ -1,334 +0,0 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2013, 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
|
||||
# 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.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# Thunk16.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Real mode thunk
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
ASM_GLOBAL ASM_PFX(m16Start)
|
||||
ASM_GLOBAL ASM_PFX(m16Size)
|
||||
ASM_GLOBAL ASM_PFX(mThunk16Attr)
|
||||
ASM_GLOBAL ASM_PFX(m16Gdt)
|
||||
ASM_GLOBAL ASM_PFX(m16GdtrBase)
|
||||
ASM_GLOBAL ASM_PFX(mTransition)
|
||||
ASM_GLOBAL ASM_PFX(InternalAsmThunk16)
|
||||
|
||||
# define the structure of IA32_REGS
|
||||
.set _EDI, 0 #size 4
|
||||
.set _ESI, 4 #size 4
|
||||
.set _EBP, 8 #size 4
|
||||
.set _ESP, 12 #size 4
|
||||
.set _EBX, 16 #size 4
|
||||
.set _EDX, 20 #size 4
|
||||
.set _ECX, 24 #size 4
|
||||
.set _EAX, 28 #size 4
|
||||
.set _DS, 32 #size 2
|
||||
.set _ES, 34 #size 2
|
||||
.set _FS, 36 #size 2
|
||||
.set _GS, 38 #size 2
|
||||
.set _EFLAGS, 40 #size 8
|
||||
.set _EIP, 48 #size 4
|
||||
.set _CS, 52 #size 2
|
||||
.set _SS, 54 #size 2
|
||||
.set IA32_REGS_SIZE, 56
|
||||
|
||||
.data
|
||||
|
||||
.set Lm16Size, ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)
|
||||
ASM_PFX(m16Size): .word Lm16Size
|
||||
.set LmThunk16Attr, L_ThunkAttr - ASM_PFX(m16Start)
|
||||
ASM_PFX(mThunk16Attr): .word LmThunk16Attr
|
||||
.set Lm16Gdt, ASM_PFX(NullSeg) - ASM_PFX(m16Start)
|
||||
ASM_PFX(m16Gdt): .word Lm16Gdt
|
||||
.set Lm16GdtrBase, _16GdtrBase - ASM_PFX(m16Start)
|
||||
ASM_PFX(m16GdtrBase): .word Lm16GdtrBase
|
||||
.set LmTransition, _EntryPoint - ASM_PFX(m16Start)
|
||||
ASM_PFX(mTransition): .word LmTransition
|
||||
|
||||
.text
|
||||
|
||||
ASM_PFX(m16Start):
|
||||
|
||||
SavedGdt: .space 10
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# _BackFromUserCode() takes control in real mode after 'retf' has been executed
|
||||
# by user code. It will be shadowed to somewhere in memory below 1MB.
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(BackFromUserCode)
|
||||
ASM_PFX(BackFromUserCode):
|
||||
#
|
||||
# The order of saved registers on the stack matches the order they appears
|
||||
# in IA32_REGS structure. This facilitates wrapper function to extract them
|
||||
# into that structure.
|
||||
#
|
||||
# Some instructions for manipulation of segment registers have to be written
|
||||
# in opcode since 64-bit MASM prevents accesses to those registers.
|
||||
#
|
||||
.byte 0x16 # push ss
|
||||
.byte 0xe # push cs
|
||||
.byte 0x66
|
||||
call L_Base # push eip
|
||||
L_Base:
|
||||
.byte 0x66
|
||||
pushq $0 # reserved high order 32 bits of EFlags
|
||||
.byte 0x66, 0x9c # pushfd actually
|
||||
cli # disable interrupts
|
||||
push %gs
|
||||
push %fs
|
||||
.byte 6 # push es
|
||||
.byte 0x1e # push ds
|
||||
.byte 0x66,0x60 # pushad
|
||||
.byte 0x66,0xba # mov edx, imm32
|
||||
L_ThunkAttr: .space 4
|
||||
testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl
|
||||
jz L_1
|
||||
movl $0x15cd2401,%eax # mov ax, 2401h & int 15h
|
||||
cli # disable interrupts
|
||||
jnc L_2
|
||||
L_1:
|
||||
testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL, %dl
|
||||
jz L_2
|
||||
inb $0x92,%al
|
||||
orb $2,%al
|
||||
outb %al, $0x92 # deactivate A20M#
|
||||
L_2:
|
||||
xorw %ax, %ax # xor eax, eax
|
||||
movl %ss, %eax # mov ax, ss
|
||||
lea IA32_REGS_SIZE(%esp), %bp
|
||||
#
|
||||
# rsi in the following 2 instructions is indeed bp in 16-bit code
|
||||
#
|
||||
movw %bp, (_ESP - IA32_REGS_SIZE)(%rsi)
|
||||
.byte 0x66
|
||||
movl (_EIP - IA32_REGS_SIZE)(%rsi), %ebx
|
||||
shlw $4,%ax # shl eax, 4
|
||||
addw %ax,%bp # add ebp, eax
|
||||
movw %cs,%ax
|
||||
shlw $4,%ax
|
||||
lea (L_64BitCode - L_Base)(%ebx, %eax), %ax
|
||||
.byte 0x66,0x2e,0x89,0x87 # mov cs:[bx + (L_64Eip - L_Base)], eax
|
||||
.word L_64Eip - L_Base
|
||||
.byte 0x66,0xb8 # mov eax, imm32
|
||||
L_SavedCr4: .space 4
|
||||
movq %rax, %cr4
|
||||
#
|
||||
# rdi in the instruction below is indeed bx in 16-bit code
|
||||
#
|
||||
.byte 0x66,0x2e # 2eh is "cs:" segment override
|
||||
lgdt (SavedGdt - L_Base)(%rdi)
|
||||
.byte 0x66
|
||||
movl $0xc0000080,%ecx
|
||||
rdmsr
|
||||
orb $1,%ah
|
||||
wrmsr
|
||||
.byte 0x66,0xb8 # mov eax, imm32
|
||||
L_SavedCr0: .space 4
|
||||
movq %rax, %cr0
|
||||
.byte 0x66,0xea # jmp far cs:L_64Bit
|
||||
L_64Eip: .space 4
|
||||
L_SavedCs: .space 2
|
||||
L_64BitCode:
|
||||
.byte 0x90
|
||||
.byte 0x48,0xbc # mov rsp, imm64
|
||||
L_SavedSp: .space 8 # restore stack
|
||||
nop
|
||||
ret
|
||||
|
||||
_EntryPoint: .long ASM_PFX(ToUserCode) - ASM_PFX(m16Start)
|
||||
.word CODE16
|
||||
_16Gdtr: .word GDT_SIZE - 1
|
||||
_16GdtrBase: .quad 0
|
||||
_16Idtr: .word 0x3ff
|
||||
.long 0
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# _ToUserCode() takes control in real mode before passing control to user code.
|
||||
# It will be shadowed to somewhere in memory below 1MB.
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(ToUserCode)
|
||||
ASM_PFX(ToUserCode):
|
||||
movl %edx,%ss # set new segment selectors
|
||||
movl %edx,%ds
|
||||
movl %edx,%es
|
||||
movl %edx,%fs
|
||||
movl %edx,%gs
|
||||
.byte 0x66
|
||||
movl $0xc0000080,%ecx
|
||||
movq %rax, %cr0
|
||||
rdmsr
|
||||
andb $0xfe, %ah # $0b11111110
|
||||
wrmsr
|
||||
movq %rbp, %cr4
|
||||
movl %esi,%ss # set up 16-bit stack segment
|
||||
movw %bx,%sp # set up 16-bit stack pointer
|
||||
.byte 0x66 # make the following call 32-bit
|
||||
call L_Base1 # push eip
|
||||
L_Base1:
|
||||
popw %bp # ebp <- address of L_Base1
|
||||
pushq (IA32_REGS_SIZE + 2)(%esp)
|
||||
lea 0x0c(%rsi), %eax
|
||||
pushq %rax
|
||||
lret # execution begins at next instruction
|
||||
L_RealMode:
|
||||
.byte 0x66,0x2e # CS and operand size override
|
||||
lidt (_16Idtr - L_Base1)(%rsi)
|
||||
.byte 0x66,0x61 # popad
|
||||
.byte 0x1f # pop ds
|
||||
.byte 0x7 # pop es
|
||||
.byte 0x0f, 0xa1 # pop fs
|
||||
.byte 0x0f, 0xa9 # pop gs
|
||||
.byte 0x66, 0x9d # popfd
|
||||
leaw 4(%esp),%sp # skip high order 32 bits of EFlags
|
||||
.byte 0x66 # make the following retf 32-bit
|
||||
lret # transfer control to user code
|
||||
|
||||
.set CODE16, ASM_PFX(_16Code) - .
|
||||
.set DATA16, ASM_PFX(_16Data) - .
|
||||
.set DATA32, ASM_PFX(_32Data) - .
|
||||
|
||||
ASM_PFX(NullSeg): .quad 0
|
||||
ASM_PFX(_16Code):
|
||||
.word -1
|
||||
.word 0
|
||||
.byte 0
|
||||
.byte 0x9b
|
||||
.byte 0x8f # 16-bit segment, 4GB limit
|
||||
.byte 0
|
||||
ASM_PFX(_16Data):
|
||||
.word -1
|
||||
.word 0
|
||||
.byte 0
|
||||
.byte 0x93
|
||||
.byte 0x8f # 16-bit segment, 4GB limit
|
||||
.byte 0
|
||||
ASM_PFX(_32Data):
|
||||
.word -1
|
||||
.word 0
|
||||
.byte 0
|
||||
.byte 0x93
|
||||
.byte 0xcf # 16-bit segment, 4GB limit
|
||||
.byte 0
|
||||
|
||||
.set GDT_SIZE, . - ASM_PFX(NullSeg)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# IA32_REGISTER_SET *
|
||||
# EFIAPI
|
||||
# InternalAsmThunk16 (
|
||||
# IN IA32_REGISTER_SET *RegisterSet,
|
||||
# IN OUT VOID *Transition
|
||||
# );
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ASM_GLOBAL ASM_PFX(InternalAsmThunk16)
|
||||
ASM_PFX(InternalAsmThunk16):
|
||||
pushq %rbp
|
||||
pushq %rbx
|
||||
pushq %rsi
|
||||
pushq %rdi
|
||||
|
||||
movl %ds, %ebx
|
||||
pushq %rbx # Save ds segment register on the stack
|
||||
movl %es, %ebx
|
||||
pushq %rbx # Save es segment register on the stack
|
||||
movl %ss, %ebx
|
||||
pushq %rbx # Save ss segment register on the stack
|
||||
|
||||
.byte 0x0f, 0xa0 #push fs
|
||||
.byte 0x0f, 0xa8 #push gs
|
||||
movq %rcx, %rsi
|
||||
movzwl _SS(%rsi), %r8d
|
||||
movl _ESP(%rsi), %edi
|
||||
lea -(IA32_REGS_SIZE + 4)(%edi), %rdi
|
||||
imul $16, %r8d, %eax
|
||||
movl %edi,%ebx # ebx <- stack for 16-bit code
|
||||
pushq $(IA32_REGS_SIZE / 4)
|
||||
addl %eax,%edi # edi <- linear address of 16-bit stack
|
||||
popq %rcx
|
||||
rep
|
||||
movsl # copy RegSet
|
||||
lea (L_SavedCr4 - ASM_PFX(m16Start))(%rdx), %ecx
|
||||
movl %edx,%eax # eax <- transition code address
|
||||
andl $0xf,%edx
|
||||
shll $12,%eax # segment address in high order 16 bits
|
||||
.set LBackFromUserCodeDelta, ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start)
|
||||
lea (LBackFromUserCodeDelta)(%rdx), %ax
|
||||
stosl # [edi] <- return address of user code
|
||||
sgdt 0x60(%rsp) # save GDT stack in argument space
|
||||
movzwq 0x60(%rsp), %r10 # r10 <- GDT limit
|
||||
lea ((ASM_PFX(InternalAsmThunk16) - L_SavedCr4) + 0xf)(%rcx), %r11
|
||||
andq $0xfffffffffffffff0, %r11 # r11 <- 16-byte aligned shadowed GDT table in real mode buffer
|
||||
|
||||
movw %r10w, (SavedGdt - L_SavedCr4)(%rcx) # save the limit of shadowed GDT table
|
||||
movq %r11, (SavedGdt - L_SavedCr4 + 0x2)(%rcx) # save the base address of shadowed GDT table
|
||||
|
||||
movq 0x62(%rsp) ,%rsi # rsi <- the original GDT base address
|
||||
xchg %r10, %rcx # save rcx to r10 and initialize rcx to be the limit of GDT table
|
||||
incq %rcx # rcx <- the size of memory to copy
|
||||
xchg %r11, %rdi # save rdi to r11 and initialize rdi to the base address of shadowed GDT table
|
||||
rep
|
||||
movsb # perform memory copy to shadow GDT table
|
||||
movq %r10, %rcx # restore the orignal rcx before memory copy
|
||||
movq %r11, %rdi # restore the original rdi before memory copy
|
||||
|
||||
sidt 0x50(%rsp)
|
||||
movq %cr0, %rax
|
||||
.set LSavedCrDelta, L_SavedCr0 - L_SavedCr4
|
||||
movl %eax, (LSavedCrDelta)(%rcx)
|
||||
andl $0x7ffffffe,%eax # clear PE, PG bits
|
||||
movq %cr4, %rbp
|
||||
movl %ebp, (%rcx) # save CR4 in SavedCr4
|
||||
andl $0xffffffcf,%ebp # clear PAE, PSE bits
|
||||
movl %r8d, %esi # esi <- 16-bit stack segment
|
||||
.byte 0x6a, DATA32
|
||||
popq %rdx
|
||||
lgdt (_16Gdtr - L_SavedCr4)(%rcx)
|
||||
movl %edx,%ss
|
||||
pushfq
|
||||
lea -8(%rdx), %edx
|
||||
lea L_RetFromRealMode(%rip), %r8
|
||||
pushq %r8
|
||||
movl %cs, %r8d
|
||||
movw %r8w, (L_SavedCs - L_SavedCr4)(%rcx)
|
||||
movq %rsp, (L_SavedSp - L_SavedCr4)(%rcx)
|
||||
.byte 0xff, 0x69 # jmp (_EntryPoint - L_SavedCr4)(%rcx)
|
||||
.set Ltemp1, _EntryPoint - L_SavedCr4
|
||||
.byte Ltemp1
|
||||
L_RetFromRealMode:
|
||||
popfq
|
||||
lgdt 0x60(%rsp) # restore protected mode GDTR
|
||||
lidt 0x50(%rsp) # restore protected mode IDTR
|
||||
lea -IA32_REGS_SIZE(%rbp), %eax
|
||||
.byte 0x0f, 0xa9 # pop gs
|
||||
.byte 0x0f, 0xa1 # pop fs
|
||||
|
||||
popq %rbx
|
||||
movl %ebx, %ss
|
||||
popq %rbx
|
||||
movl %ebx, %es
|
||||
popq %rbx
|
||||
movl %ebx, %ds
|
||||
|
||||
popq %rdi
|
||||
popq %rsi
|
||||
popq %rbx
|
||||
popq %rbp
|
||||
|
||||
ret
|
|
@ -2,13 +2,7 @@
|
|||
Provides interface to EFI_FILE_HANDLE functionality.
|
||||
|
||||
Copyright (c) 2006 - 2018, 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
|
||||
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.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
|
@ -73,7 +67,6 @@ FileHandleGetInfo (
|
|||
//
|
||||
// error is expected. getting size to allocate
|
||||
//
|
||||
FileInfoSize += 2;
|
||||
FileInfo = AllocateZeroPool(FileInfoSize);
|
||||
//
|
||||
// now get the information
|
||||
|
@ -503,13 +496,7 @@ FileHandleFindFirstFile (
|
|||
// read in the info about the first file
|
||||
//
|
||||
Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);
|
||||
// ASSERT(Status != EFI_BUFFER_TOO_SMALL);
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
BufferSize += 2;
|
||||
FreePool(*Buffer);
|
||||
*Buffer = AllocateZeroPool(BufferSize);
|
||||
Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);
|
||||
}
|
||||
ASSERT(Status != EFI_BUFFER_TOO_SMALL);
|
||||
if (EFI_ERROR(Status) || BufferSize == 0) {
|
||||
FreePool(*Buffer);
|
||||
*Buffer = NULL;
|
||||
|
@ -517,8 +504,6 @@ FileHandleFindFirstFile (
|
|||
return (EFI_NOT_FOUND);
|
||||
}
|
||||
return (Status);
|
||||
} else if ((*Buffer)->Size == 0) {
|
||||
(*Buffer)->Size = BufferSize;
|
||||
}
|
||||
return (EFI_SUCCESS);
|
||||
}
|
||||
|
@ -559,7 +544,7 @@ FileHandleFindNextFile(
|
|||
//
|
||||
// This BufferSize MUST stay equal to the originally allocated one in GetFirstFile
|
||||
//
|
||||
BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE; //Buffer->Size; //
|
||||
BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;
|
||||
|
||||
//
|
||||
// read in the info about the next file
|
||||
|
@ -576,8 +561,6 @@ FileHandleFindNextFile(
|
|||
if (BufferSize == 0) {
|
||||
FreePool(Buffer);
|
||||
*NoFile = TRUE;
|
||||
} else if (Buffer->Size == 0) {
|
||||
Buffer->Size = BufferSize;
|
||||
}
|
||||
|
||||
return (EFI_SUCCESS);
|
||||
|
@ -831,25 +814,10 @@ FileHandleGetFileName (
|
|||
Status = EFI_OUT_OF_RESOURCES;
|
||||
break;
|
||||
} else {
|
||||
//
|
||||
// Prepare to move to the parent directory.
|
||||
// Also determine whether CurrentHandle refers to the Root directory.
|
||||
//
|
||||
Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0);
|
||||
//
|
||||
// We got info... do we have a name? if yes precede the current path with it...
|
||||
//
|
||||
if ((StrLen (FileInfo->FileName) == 0) || EFI_ERROR (Status)) {
|
||||
//
|
||||
// Both FileInfo->FileName being '\0' and EFI_ERROR() suggest that
|
||||
// CurrentHandle refers to the Root directory. As this loop ensures
|
||||
// FullFileName is starting with '\\' at all times, signal success
|
||||
// and exit the loop.
|
||||
// While FileInfo->FileName could theoretically be a value other than
|
||||
// '\0' or '\\', '\\' is guaranteed to be supported by the
|
||||
// specification and hence its value can safely be ignored.
|
||||
//
|
||||
Status = EFI_SUCCESS;
|
||||
if (StrLen (FileInfo->FileName) == 0) {
|
||||
if (*FullFileName == NULL) {
|
||||
ASSERT((*FullFileName == NULL && Size == 0) || (*FullFileName != NULL));
|
||||
*FullFileName = StrnCatGrowLeft(FullFileName, &Size, L"\\", 0);
|
||||
|
@ -867,11 +835,15 @@ FileHandleGetFileName (
|
|||
FreePool(FileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
FileHandleClose(CurrentHandle);
|
||||
//
|
||||
// Move to the parent directory
|
||||
//
|
||||
Status = CurrentHandle->Open (CurrentHandle, &NextHigherHandle, L"..", EFI_FILE_MODE_READ, 0);
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
FileHandleClose(CurrentHandle);
|
||||
CurrentHandle = NextHigherHandle;
|
||||
}
|
||||
} else if (Status == EFI_NOT_FOUND) {
|
||||
|
|
|
@ -141,15 +141,9 @@ FreePages (
|
|||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
// ASSERT (Pages != 0);
|
||||
if (!Pages) {
|
||||
return;
|
||||
}
|
||||
ASSERT (Pages != 0);
|
||||
Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
|
||||
// ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,10 +181,7 @@ InternalAllocateAlignedPages (
|
|||
//
|
||||
// Alignment must be a power of two or zero.
|
||||
//
|
||||
// ASSERT ((Alignment & (Alignment - 1)) == 0);
|
||||
if ((Alignment & (Alignment - 1)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
ASSERT ((Alignment & (Alignment - 1)) == 0);
|
||||
|
||||
if (Pages == 0) {
|
||||
return NULL;
|
||||
|
@ -204,10 +195,7 @@ InternalAllocateAlignedPages (
|
|||
//
|
||||
// Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
|
||||
//
|
||||
// ASSERT (RealPages > Pages);
|
||||
if (RealPages < Pages) {
|
||||
return NULL;
|
||||
}
|
||||
ASSERT (RealPages > Pages);
|
||||
|
||||
Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -220,10 +208,7 @@ InternalAllocateAlignedPages (
|
|||
// Free first unaligned page(s).
|
||||
//
|
||||
Status = gBS->FreePages (Memory, UnalignedPages);
|
||||
// ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
|
||||
UnalignedPages = RealPages - Pages - UnalignedPages;
|
||||
|
@ -232,10 +217,7 @@ InternalAllocateAlignedPages (
|
|||
// Free last unaligned page(s).
|
||||
//
|
||||
Status = gBS->FreePages (Memory, UnalignedPages);
|
||||
// ASSERT_EFI_ERROR (Status);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
|
@ -358,14 +340,11 @@ FreeAlignedPages (
|
|||
IN UINTN Pages
|
||||
)
|
||||
{
|
||||
// EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
|
||||
// ASSERT (Pages != 0);
|
||||
if (!Pages || !Buffer) {
|
||||
return;
|
||||
}
|
||||
/* Status = */gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
|
||||
// ASSERT_EFI_ERROR (Status);
|
||||
ASSERT (Pages != 0);
|
||||
Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -581,14 +560,8 @@ InternalAllocateCopyPool (
|
|||
{
|
||||
VOID *Memory;
|
||||
|
||||
// ASSERT (Buffer != NULL);
|
||||
if (!Buffer) {
|
||||
return NULL;
|
||||
}
|
||||
// ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
|
||||
if (AllocationSize > (MAX_ADDRESS - (UINTN) Buffer + 1)) {
|
||||
return NULL;
|
||||
}
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
|
||||
|
||||
Memory = InternalAllocatePool (PoolType, AllocationSize);
|
||||
if (Memory != NULL) {
|
||||
|
@ -834,11 +807,9 @@ FreePool (
|
|||
IN VOID *Buffer
|
||||
)
|
||||
{
|
||||
// EFI_STATUS Status;
|
||||
if (Buffer) {
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Status = */gBS->FreePool (Buffer);
|
||||
// ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
Status = gBS->FreePool (Buffer);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,815 +0,0 @@
|
|||
/** @file
|
||||
Support routines for memory allocation routines based
|
||||
on boot services for Dxe phase drivers.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of a certain memory type.
|
||||
|
||||
Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated
|
||||
buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.
|
||||
If there is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
@param MemoryType The type of memory to allocate.
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
InternalAllocatePages (
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS Memory;
|
||||
|
||||
if (Pages == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
return (VOID *) (UINTN) Memory;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of type EfiBootServicesData.
|
||||
|
||||
Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
|
||||
allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
|
||||
is returned. If there is not enough memory remaining to satisfy the request, then NULL is
|
||||
returned.
|
||||
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocatePages (
|
||||
IN UINTN Pages
|
||||
)
|
||||
{
|
||||
return InternalAllocatePages (EfiBootServicesData, Pages);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of type EfiRuntimeServicesData.
|
||||
|
||||
Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
|
||||
allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
|
||||
is returned. If there is not enough memory remaining to satisfy the request, then NULL is
|
||||
returned.
|
||||
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateRuntimePages (
|
||||
IN UINTN Pages
|
||||
)
|
||||
{
|
||||
return InternalAllocatePages (EfiRuntimeServicesData, Pages);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of type EfiReservedMemoryType.
|
||||
|
||||
Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
|
||||
allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
|
||||
is returned. If there is not enough memory remaining to satisfy the request, then NULL is
|
||||
returned.
|
||||
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateReservedPages (
|
||||
IN UINTN Pages
|
||||
)
|
||||
{
|
||||
return InternalAllocatePages (EfiReservedMemoryType, Pages);
|
||||
}
|
||||
|
||||
/**
|
||||
Frees one or more 4KB pages that were previously allocated with one of the page allocation
|
||||
functions in the Memory Allocation Library.
|
||||
|
||||
Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
|
||||
must have been allocated on a previous call to the page allocation services of the Memory
|
||||
Allocation Library. If it is not possible to free allocated pages, then this function will
|
||||
perform no actions.
|
||||
|
||||
If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
|
||||
then ASSERT().
|
||||
If Pages is zero, then ASSERT().
|
||||
|
||||
@param Buffer The pointer to the buffer of pages to free.
|
||||
@param Pages The number of 4 KB pages to free.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
FreePages (
|
||||
IN VOID *Buffer,
|
||||
IN UINTN Pages
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (Pages != 0);
|
||||
Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of a certain memory type at a specified alignment.
|
||||
|
||||
Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
|
||||
specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
|
||||
If there is not enough memory at the specified alignment remaining to satisfy the request, then
|
||||
NULL is returned.
|
||||
If Alignment is not a power of two and Alignment is not zero, then ASSERT().
|
||||
If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
|
||||
|
||||
@param MemoryType The type of memory to allocate.
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
@param Alignment The requested alignment of the allocation. Must be a power of two.
|
||||
If Alignment is zero, then byte alignment is used.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
InternalAllocateAlignedPages (
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN UINTN Alignment
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS Memory;
|
||||
UINTN AlignedMemory;
|
||||
UINTN AlignmentMask;
|
||||
UINTN UnalignedPages;
|
||||
UINTN RealPages;
|
||||
|
||||
//
|
||||
// Alignment must be a power of two or zero.
|
||||
//
|
||||
ASSERT ((Alignment & (Alignment - 1)) == 0);
|
||||
|
||||
if (Pages == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (Alignment > EFI_PAGE_SIZE) {
|
||||
//
|
||||
// Calculate the total number of pages since alignment is larger than page size.
|
||||
//
|
||||
AlignmentMask = Alignment - 1;
|
||||
RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
|
||||
//
|
||||
// Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
|
||||
//
|
||||
ASSERT (RealPages > Pages);
|
||||
|
||||
Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
|
||||
UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
|
||||
if (UnalignedPages > 0) {
|
||||
//
|
||||
// Free first unaligned page(s).
|
||||
//
|
||||
Status = gBS->FreePages (Memory, UnalignedPages);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
|
||||
UnalignedPages = RealPages - Pages - UnalignedPages;
|
||||
if (UnalignedPages > 0) {
|
||||
//
|
||||
// Free last unaligned page(s).
|
||||
//
|
||||
Status = gBS->FreePages (Memory, UnalignedPages);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Do not over-allocate pages in this case.
|
||||
//
|
||||
Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return NULL;
|
||||
}
|
||||
AlignedMemory = (UINTN) Memory;
|
||||
}
|
||||
return (VOID *) AlignedMemory;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
|
||||
|
||||
Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
|
||||
alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
|
||||
returned. If there is not enough memory at the specified alignment remaining to satisfy the
|
||||
request, then NULL is returned.
|
||||
|
||||
If Alignment is not a power of two and Alignment is not zero, then ASSERT().
|
||||
If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
|
||||
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
@param Alignment The requested alignment of the allocation. Must be a power of two.
|
||||
If Alignment is zero, then byte alignment is used.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateAlignedPages (
|
||||
IN UINTN Pages,
|
||||
IN UINTN Alignment
|
||||
)
|
||||
{
|
||||
return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
|
||||
|
||||
Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
|
||||
alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
|
||||
returned. If there is not enough memory at the specified alignment remaining to satisfy the
|
||||
request, then NULL is returned.
|
||||
|
||||
If Alignment is not a power of two and Alignment is not zero, then ASSERT().
|
||||
If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
|
||||
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
@param Alignment The requested alignment of the allocation. Must be a power of two.
|
||||
If Alignment is zero, then byte alignment is used.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateAlignedRuntimePages (
|
||||
IN UINTN Pages,
|
||||
IN UINTN Alignment
|
||||
)
|
||||
{
|
||||
return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
|
||||
|
||||
Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
|
||||
alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
|
||||
returned. If there is not enough memory at the specified alignment remaining to satisfy the
|
||||
request, then NULL is returned.
|
||||
|
||||
If Alignment is not a power of two and Alignment is not zero, then ASSERT().
|
||||
If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
|
||||
|
||||
@param Pages The number of 4 KB pages to allocate.
|
||||
@param Alignment The requested alignment of the allocation. Must be a power of two.
|
||||
If Alignment is zero, then byte alignment is used.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateAlignedReservedPages (
|
||||
IN UINTN Pages,
|
||||
IN UINTN Alignment
|
||||
)
|
||||
{
|
||||
return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);
|
||||
}
|
||||
|
||||
/**
|
||||
Frees one or more 4KB pages that were previously allocated with one of the aligned page
|
||||
allocation functions in the Memory Allocation Library.
|
||||
|
||||
Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
|
||||
must have been allocated on a previous call to the aligned page allocation services of the Memory
|
||||
Allocation Library. If it is not possible to free allocated pages, then this function will
|
||||
perform no actions.
|
||||
|
||||
If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
|
||||
Library, then ASSERT().
|
||||
If Pages is zero, then ASSERT().
|
||||
|
||||
@param Buffer The pointer to the buffer of pages to free.
|
||||
@param Pages The number of 4 KB pages to free.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
FreeAlignedPages (
|
||||
IN VOID *Buffer,
|
||||
IN UINTN Pages
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (Pages != 0);
|
||||
Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates a buffer of a certain pool type.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
|
||||
pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
|
||||
returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
@param MemoryType The type of memory to allocate.
|
||||
@param AllocationSize The number of bytes to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
InternalAllocatePool (
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Memory;
|
||||
|
||||
Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Memory = NULL;
|
||||
}
|
||||
return Memory;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates a buffer of type EfiBootServicesData.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
|
||||
pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
|
||||
returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
@param AllocationSize The number of bytes to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocatePool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
return InternalAllocatePool (EfiBootServicesData, AllocationSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates a buffer of type EfiRuntimeServicesData.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
|
||||
a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
|
||||
returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
@param AllocationSize The number of bytes to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateRuntimePool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates a buffer of type EfiReservedMemoryType.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
|
||||
a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
|
||||
returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
@param AllocationSize The number of bytes to allocate.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateReservedPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates and zeros a buffer of a certain pool type.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer
|
||||
with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid
|
||||
buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,
|
||||
then NULL is returned.
|
||||
|
||||
@param PoolType The type of memory to allocate.
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
InternalAllocateZeroPool (
|
||||
IN EFI_MEMORY_TYPE PoolType,
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
VOID *Memory;
|
||||
|
||||
Memory = InternalAllocatePool (PoolType, AllocationSize);
|
||||
if (Memory != NULL) {
|
||||
Memory = ZeroMem (Memory, AllocationSize);
|
||||
}
|
||||
return Memory;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates and zeros a buffer of type EfiBootServicesData.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
|
||||
buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
|
||||
valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
|
||||
request, then NULL is returned.
|
||||
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateZeroPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates and zeros a buffer of type EfiRuntimeServicesData.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
|
||||
buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
|
||||
valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
|
||||
request, then NULL is returned.
|
||||
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateRuntimeZeroPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates and zeros a buffer of type EfiReservedMemoryType.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
|
||||
buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
|
||||
valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
|
||||
request, then NULL is returned.
|
||||
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateReservedZeroPool (
|
||||
IN UINTN AllocationSize
|
||||
)
|
||||
{
|
||||
return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Copies a buffer to an allocated buffer of a certain pool type.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of a certain pool type, copies
|
||||
AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
|
||||
allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
|
||||
is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
If Buffer is NULL, then ASSERT().
|
||||
If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
||||
|
||||
@param PoolType The type of pool to allocate.
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
@param Buffer The buffer to copy to the allocated buffer.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
InternalAllocateCopyPool (
|
||||
IN EFI_MEMORY_TYPE PoolType,
|
||||
IN UINTN AllocationSize,
|
||||
IN CONST VOID *Buffer
|
||||
)
|
||||
{
|
||||
VOID *Memory;
|
||||
|
||||
ASSERT (Buffer != NULL);
|
||||
ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));
|
||||
|
||||
Memory = InternalAllocatePool (PoolType, AllocationSize);
|
||||
if (Memory != NULL) {
|
||||
Memory = CopyMem (Memory, Buffer, AllocationSize);
|
||||
}
|
||||
return Memory;
|
||||
}
|
||||
|
||||
/**
|
||||
Copies a buffer to an allocated buffer of type EfiBootServicesData.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
|
||||
AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
|
||||
allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
|
||||
is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
If Buffer is NULL, then ASSERT().
|
||||
If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
||||
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
@param Buffer The buffer to copy to the allocated buffer.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateCopyPool (
|
||||
IN UINTN AllocationSize,
|
||||
IN CONST VOID *Buffer
|
||||
)
|
||||
{
|
||||
return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
|
||||
AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
|
||||
allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
|
||||
is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
If Buffer is NULL, then ASSERT().
|
||||
If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
||||
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
@param Buffer The buffer to copy to the allocated buffer.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateRuntimeCopyPool (
|
||||
IN UINTN AllocationSize,
|
||||
IN CONST VOID *Buffer
|
||||
)
|
||||
{
|
||||
return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
|
||||
AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
|
||||
allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
|
||||
is not enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
If Buffer is NULL, then ASSERT().
|
||||
If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
||||
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
@param Buffer The buffer to copy to the allocated buffer.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
AllocateReservedCopyPool (
|
||||
IN UINTN AllocationSize,
|
||||
IN CONST VOID *Buffer
|
||||
)
|
||||
{
|
||||
return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Reallocates a buffer of a specified memory type.
|
||||
|
||||
Allocates and zeros the number bytes specified by NewSize from memory of the type
|
||||
specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and
|
||||
NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
|
||||
OldBuffer is freed. A pointer to the newly allocated buffer is returned.
|
||||
If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
|
||||
enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
|
||||
is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
|
||||
|
||||
@param PoolType The type of pool to allocate.
|
||||
@param OldSize The size, in bytes, of OldBuffer.
|
||||
@param NewSize The size, in bytes, of the buffer to reallocate.
|
||||
@param OldBuffer The buffer to copy to the allocated buffer. This is an optional
|
||||
parameter that may be NULL.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
InternalReallocatePool (
|
||||
IN EFI_MEMORY_TYPE PoolType,
|
||||
IN UINTN OldSize,
|
||||
IN UINTN NewSize,
|
||||
IN VOID *OldBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
VOID *NewBuffer;
|
||||
|
||||
NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);
|
||||
if (NewBuffer != NULL && OldBuffer != NULL) {
|
||||
CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
|
||||
FreePool (OldBuffer);
|
||||
}
|
||||
return NewBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
Reallocates a buffer of type EfiBootServicesData.
|
||||
|
||||
Allocates and zeros the number bytes specified by NewSize from memory of type
|
||||
EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
|
||||
NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
|
||||
OldBuffer is freed. A pointer to the newly allocated buffer is returned.
|
||||
If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
|
||||
enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
|
||||
is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
|
||||
|
||||
@param OldSize The size, in bytes, of OldBuffer.
|
||||
@param NewSize The size, in bytes, of the buffer to reallocate.
|
||||
@param OldBuffer The buffer to copy to the allocated buffer. This is an optional
|
||||
parameter that may be NULL.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
ReallocatePool (
|
||||
IN UINTN OldSize,
|
||||
IN UINTN NewSize,
|
||||
IN VOID *OldBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Reallocates a buffer of type EfiRuntimeServicesData.
|
||||
|
||||
Allocates and zeros the number bytes specified by NewSize from memory of type
|
||||
EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
|
||||
NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
|
||||
OldBuffer is freed. A pointer to the newly allocated buffer is returned.
|
||||
If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
|
||||
enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
|
||||
is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
|
||||
|
||||
@param OldSize The size, in bytes, of OldBuffer.
|
||||
@param NewSize The size, in bytes, of the buffer to reallocate.
|
||||
@param OldBuffer The buffer to copy to the allocated buffer. This is an optional
|
||||
parameter that may be NULL.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
ReallocateRuntimePool (
|
||||
IN UINTN OldSize,
|
||||
IN UINTN NewSize,
|
||||
IN VOID *OldBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Reallocates a buffer of type EfiReservedMemoryType.
|
||||
|
||||
Allocates and zeros the number bytes specified by NewSize from memory of type
|
||||
EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
|
||||
NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
|
||||
OldBuffer is freed. A pointer to the newly allocated buffer is returned.
|
||||
If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
|
||||
enough memory remaining to satisfy the request, then NULL is returned.
|
||||
|
||||
If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
|
||||
is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
|
||||
|
||||
@param OldSize The size, in bytes, of OldBuffer.
|
||||
@param NewSize The size, in bytes, of the buffer to reallocate.
|
||||
@param OldBuffer The buffer to copy to the allocated buffer. This is an optional
|
||||
parameter that may be NULL.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
EFIAPI
|
||||
ReallocateReservedPool (
|
||||
IN UINTN OldSize,
|
||||
IN UINTN NewSize,
|
||||
IN VOID *OldBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Frees a buffer that was previously allocated with one of the pool allocation functions in the
|
||||
Memory Allocation Library.
|
||||
|
||||
Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
|
||||
pool allocation services of the Memory Allocation Library. If it is not possible to free pool
|
||||
resources, then this function will perform no actions.
|
||||
|
||||
If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
|
||||
then ASSERT().
|
||||
|
||||
@param Buffer The pointer to the buffer to free.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
FreePool (
|
||||
IN VOID *Buffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gBS->FreePool (Buffer);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
|
@ -324,9 +324,6 @@
|
|||
## Include/Guid/Mps.h
|
||||
gEfiMpsTableGuid = { 0xEB9D2D2F, 0x2D88, 0x11D3, { 0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
||||
|
||||
## Include/Guid/SalSystemTable.h
|
||||
gEfiSalSystemTableGuid = { 0xEB9D2D32, 0x2D88, 0x11D3, { 0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
||||
|
||||
## Include/Protocol/AuthenticationInfo.h
|
||||
gEfiAuthenticationChapLocalGuid = { 0xC280C73E, 0x15CA, 0x11DA, { 0xB0, 0xCA, 0x00, 0x10, 0x83, 0xFF, 0xCA, 0x4D }}
|
||||
|
||||
|
@ -1136,29 +1133,6 @@
|
|||
## Include/Protocol/LegacyRegion2.h
|
||||
gEfiLegacyRegion2ProtocolGuid = {0x70101eaf, 0x85, 0x440c, {0xb3, 0x56, 0x8e, 0xe3, 0x6f, 0xef, 0x24, 0xf0 } }
|
||||
|
||||
## Include/Protocol/McaInitPmi.h
|
||||
gEfiSalMcaInitPmiProtocolGuid = { 0xb60dc6e8, 0x3b6f, 0x11d5, {0xaf, 0x9, 0x0, 0xa0, 0xc9, 0x44, 0xa0, 0x5b } }
|
||||
|
||||
## Include/Protocol/ExtendedSalBootService.h
|
||||
gEfiExtendedSalBootServiceProtocolGuid = { 0xde0ee9a4, 0x3c7a, 0x44f2, {0xb7, 0x8b, 0xe3, 0xcc, 0xd6, 0x9c, 0x3a, 0xf7 } }
|
||||
|
||||
## Include/Protocol/ExtendedSalServiceClasses.h
|
||||
gEfiExtendedSalBaseIoServicesProtocolGuid = { 0x5aea42b5, 0x31e1, 0x4515, {0xbc, 0x31, 0xb8, 0xd5, 0x25, 0x75, 0x65, 0xa6 } }
|
||||
gEfiExtendedSalStallServicesProtocolGuid = { 0x53a58d06, 0xac27, 0x4d8c, {0xb5, 0xe9, 0xf0, 0x8a, 0x80, 0x65, 0x41, 0x70 } }
|
||||
gEfiExtendedSalRtcServicesProtocolGuid = { 0x7e97a470, 0xefdb, 0x4d02, {0x8f, 0xce, 0x61, 0x90, 0xd2, 0x7b, 0xa2, 0x96 } }
|
||||
gEfiExtendedSalVariableServicesProtocolGuid = { 0x4ecb6c53, 0xc641, 0x4370, {0x8c, 0xb2, 0x3b, 0x0e, 0x49, 0x6e, 0x83, 0x78 } }
|
||||
gEfiExtendedSalMtcServicesProtocolGuid = { 0x899afd18, 0x75e8, 0x408b, {0xa4, 0x1a, 0x6e, 0x2e, 0x7e, 0xcd, 0xf4, 0x54 } }
|
||||
gEfiExtendedSalResetServicesProtocolGuid = { 0x7d019990, 0x8ce1, 0x46f5, {0xa7, 0x76, 0x3c, 0x51, 0x98, 0x67, 0x6a, 0xa0 } }
|
||||
gEfiExtendedSalStatusCodeServicesProtocolGuid = { 0xdbd91d, 0x55e9, 0x420f, {0x96, 0x39, 0x5e, 0x9f, 0x84, 0x37, 0xb4, 0x4f } }
|
||||
gEfiExtendedSalFvBlockServicesProtocolGuid = { 0xa2271df1, 0xbcbb, 0x4f1d, {0x98, 0xa9, 0x06, 0xbc, 0x17, 0x2f, 0x07, 0x1a } }
|
||||
gEfiExtendedSalMpServicesProtocolGuid = { 0x697d81a2, 0xcf18, 0x4dc0, {0x9e, 0x0d, 0x06, 0x11, 0x3b, 0x61, 0x8a, 0x3f } }
|
||||
gEfiExtendedSalPalServicesProtocolGuid = { 0xe1cd9d21, 0x0fc2, 0x438d, {0x97, 0x03, 0x04, 0xe6, 0x6d, 0x96, 0x1e, 0x57 } }
|
||||
gEfiExtendedSalBaseServicesProtocolGuid = { 0xd9e9fa06, 0x0fe0, 0x41c3, {0x96, 0xfb, 0x83, 0x42, 0x5a, 0x33, 0x94, 0xf8 } }
|
||||
gEfiExtendedSalMcaServicesProtocolGuid = { 0x2a591128, 0x6cc7, 0x42b1, {0x8a, 0xf0, 0x58, 0x93, 0x3b, 0x68, 0x2d, 0xbb } }
|
||||
gEfiExtendedSalPciServicesProtocolGuid = { 0xa46b1a31, 0xad66, 0x4905, {0x92, 0xf6, 0x2b, 0x46, 0x59, 0xdc, 0x30, 0x63 } }
|
||||
gEfiExtendedSalCacheServicesProtocolGuid = { 0xedc9494, 0x2743, 0x4ba5, { 0x88, 0x18, 0x0a, 0xef, 0x52, 0x13, 0xf1, 0x88 } }
|
||||
gEfiExtendedSalMcaLogServicesProtocolGuid = { 0xcb3fd86e, 0x38a3, 0x4c03, {0x9a, 0x5c, 0x90, 0xcf, 0xa3, 0xa2, 0xab, 0x7a } }
|
||||
|
||||
#
|
||||
# Protocols defined in PI 1.2.1
|
||||
#
|
||||
|
|
|
@ -0,0 +1,689 @@
|
|||
/** @file
|
||||
Shell application for VLAN configuration.
|
||||
|
||||
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/VlanConfig.h>
|
||||
|
||||
#include <Library/UefiApplicationEntryPoint.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/ShellLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiHiiServicesLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
|
||||
//
|
||||
// String token ID of VConfig command help message text.
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringVConfigHelpTokenId = STRING_TOKEN (STR_VCONFIG_HELP);
|
||||
|
||||
#define INVALID_NIC_INDEX 0xffff
|
||||
#define INVALID_VLAN_ID 0xffff
|
||||
|
||||
//
|
||||
// This is the generated String package data for all .UNI files.
|
||||
// This data array is ready to be used as input of HiiAddPackages() to
|
||||
// create a packagelist (which contains Form packages, String packages, etc).
|
||||
//
|
||||
extern UINT8 VConfigStrings[];
|
||||
|
||||
EFI_HANDLE mImageHandle = NULL;
|
||||
EFI_HII_HANDLE mHiiHandle = NULL;
|
||||
|
||||
SHELL_PARAM_ITEM mParamList[] = {
|
||||
{
|
||||
L"-l",
|
||||
TypeValue
|
||||
},
|
||||
{
|
||||
L"-a",
|
||||
TypeMaxValue
|
||||
},
|
||||
{
|
||||
L"-d",
|
||||
TypeValue
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
TypeMax
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Locate the network interface handle buffer.
|
||||
|
||||
@param[out] NumberOfHandles Pointer to the number of handles.
|
||||
@param[out] HandleBuffer Pointer to the buffer to store the returned handles.
|
||||
|
||||
**/
|
||||
VOID
|
||||
LocateNicHandleBuffer (
|
||||
OUT UINTN *NumberOfHandles,
|
||||
OUT EFI_HANDLE **HandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
*NumberOfHandles = 0;
|
||||
*HandleBuffer = NULL;
|
||||
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiVlanConfigProtocolGuid,
|
||||
NULL,
|
||||
NumberOfHandles,
|
||||
HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_LOCATE_FAIL), mHiiHandle, Status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Extract the decimal index from the network interface name.
|
||||
|
||||
@param[in] Name Name of the network interface.
|
||||
|
||||
@retval INVALID_NIC_INDEX Failed to extract the network interface index.
|
||||
@return others The network interface index.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
NicNameToIndex (
|
||||
IN CHAR16 *Name
|
||||
)
|
||||
{
|
||||
CHAR16 *Str;
|
||||
|
||||
Str = Name + 3;
|
||||
if ((StrnCmp (Name, L"eth", 3) != 0) || (*Str == 0)) {
|
||||
return INVALID_NIC_INDEX;
|
||||
}
|
||||
|
||||
while (*Str != 0) {
|
||||
if ((*Str < L'0') || (*Str > L'9')) {
|
||||
return INVALID_NIC_INDEX;
|
||||
}
|
||||
|
||||
Str++;
|
||||
}
|
||||
|
||||
return (UINT16) StrDecimalToUintn (Name + 3);
|
||||
}
|
||||
|
||||
/**
|
||||
Find network interface device handle by its name.
|
||||
|
||||
@param[in] Name Name of the network interface.
|
||||
|
||||
@retval NULL Cannot find the network interface.
|
||||
@return others Handle of the network interface.
|
||||
|
||||
**/
|
||||
EFI_HANDLE
|
||||
NicNameToHandle (
|
||||
IN CHAR16 *Name
|
||||
)
|
||||
{
|
||||
UINTN NumberOfHandles;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN Index;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
//
|
||||
// Find all NIC handles.
|
||||
//
|
||||
LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);
|
||||
if (NumberOfHandles == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Index = NicNameToIndex (Name);
|
||||
if (Index >= NumberOfHandles) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_IF), mHiiHandle, Name);
|
||||
Handle = NULL;
|
||||
} else {
|
||||
Handle = HandleBuffer[Index];
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
return Handle;
|
||||
}
|
||||
|
||||
/**
|
||||
Open VlanConfig protocol from a handle.
|
||||
|
||||
@param[in] Handle The handle to open the VlanConfig protocol.
|
||||
|
||||
@return The VlanConfig protocol interface.
|
||||
|
||||
**/
|
||||
EFI_VLAN_CONFIG_PROTOCOL *
|
||||
OpenVlanConfigProtocol (
|
||||
IN EFI_HANDLE Handle
|
||||
)
|
||||
{
|
||||
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
||||
|
||||
VlanConfig = NULL;
|
||||
gBS->OpenProtocol (
|
||||
Handle,
|
||||
&gEfiVlanConfigProtocolGuid,
|
||||
(VOID **) &VlanConfig,
|
||||
mImageHandle,
|
||||
Handle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
return VlanConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
Close VlanConfig protocol of a handle.
|
||||
|
||||
@param[in] Handle The handle to close the VlanConfig protocol.
|
||||
|
||||
**/
|
||||
VOID
|
||||
CloseVlanConfigProtocol (
|
||||
IN EFI_HANDLE Handle
|
||||
)
|
||||
{
|
||||
gBS->CloseProtocol (
|
||||
Handle,
|
||||
&gEfiVlanConfigProtocolGuid,
|
||||
mImageHandle,
|
||||
Handle
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Display VLAN configuration of a network interface.
|
||||
|
||||
@param[in] Handle Handle of the network interface.
|
||||
@param[in] NicIndex Index of the network interface.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ShowNicVlanInfo (
|
||||
IN EFI_HANDLE Handle,
|
||||
IN UINTN NicIndex
|
||||
)
|
||||
{
|
||||
CHAR16 *MacStr;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
||||
UINT16 NumberOfVlan;
|
||||
EFI_VLAN_FIND_DATA *VlanData;
|
||||
|
||||
VlanConfig = OpenVlanConfigProtocol (Handle);
|
||||
if (VlanConfig == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
MacStr = NULL;
|
||||
Status = NetLibGetMacString (Handle, mImageHandle, &MacStr);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_MAC_FAIL), mHiiHandle, Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_ETH_MAC), mHiiHandle, NicIndex, MacStr);
|
||||
|
||||
Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VLAN), mHiiHandle);
|
||||
} else {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_FIND_FAIL), mHiiHandle, Status);
|
||||
}
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumberOfVlan; Index++) {
|
||||
ShellPrintHiiEx (
|
||||
-1,
|
||||
-1,
|
||||
NULL,
|
||||
STRING_TOKEN (STR_VCONFIG_VLAN_DISPLAY),
|
||||
mHiiHandle,
|
||||
VlanData[Index].VlanId,
|
||||
VlanData[Index].Priority
|
||||
);
|
||||
}
|
||||
|
||||
FreePool (VlanData);
|
||||
|
||||
Exit:
|
||||
CloseVlanConfigProtocol (Handle);
|
||||
|
||||
if (MacStr != NULL) {
|
||||
FreePool (MacStr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Display the VLAN configuration of all, or a specified network interface.
|
||||
|
||||
@param[in] Name Name of the network interface. If NULL, the VLAN
|
||||
configuration of all network will be displayed.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DisplayVlan (
|
||||
IN CHAR16 *Name OPTIONAL
|
||||
)
|
||||
{
|
||||
UINTN NumberOfHandles;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN Index;
|
||||
EFI_HANDLE NicHandle;
|
||||
|
||||
if (Name != NULL) {
|
||||
//
|
||||
// Display specified NIC
|
||||
//
|
||||
NicHandle = NicNameToHandle (Name);
|
||||
if (NicHandle == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
ShowNicVlanInfo (NicHandle, 0);
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Find all NIC handles
|
||||
//
|
||||
LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);
|
||||
if (NumberOfHandles == 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumberOfHandles; Index++) {
|
||||
ShowNicVlanInfo (HandleBuffer[Index], Index);
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a NULL-terminated unicode decimal VLAN ID string to VLAN ID.
|
||||
|
||||
@param[in] String Pointer to VLAN ID string from user input.
|
||||
|
||||
@retval Value translated from String, or INVALID_VLAN_ID is string is invalid.
|
||||
|
||||
**/
|
||||
UINT16
|
||||
StrToVlanId (
|
||||
IN CHAR16 *String
|
||||
)
|
||||
{
|
||||
CHAR16 *Str;
|
||||
|
||||
if (String == NULL) {
|
||||
return INVALID_VLAN_ID;
|
||||
}
|
||||
|
||||
Str = String;
|
||||
while ((*Str >= '0') && (*Str <= '9')) {
|
||||
Str++;
|
||||
}
|
||||
|
||||
if (*Str != 0) {
|
||||
return INVALID_VLAN_ID;
|
||||
}
|
||||
|
||||
return (UINT16) StrDecimalToUintn (String);
|
||||
}
|
||||
|
||||
/**
|
||||
Add a VLAN device.
|
||||
|
||||
@param[in] ParamStr Parameter string from user input.
|
||||
|
||||
**/
|
||||
VOID
|
||||
AddVlan (
|
||||
IN CHAR16 *ParamStr
|
||||
)
|
||||
{
|
||||
CHAR16 *Name;
|
||||
CHAR16 *VlanIdStr;
|
||||
CHAR16 *PriorityStr;
|
||||
CHAR16 *StrPtr;
|
||||
BOOLEAN IsSpace;
|
||||
UINTN VlanId;
|
||||
UINTN Priority;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_HANDLE VlanHandle;
|
||||
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
||||
EFI_STATUS Status;
|
||||
|
||||
VlanConfig = NULL;
|
||||
Priority = 0;
|
||||
|
||||
if (ParamStr == NULL) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);
|
||||
return ;
|
||||
}
|
||||
|
||||
StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);
|
||||
if (StrPtr == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
Name = StrPtr;
|
||||
VlanIdStr = NULL;
|
||||
PriorityStr = NULL;
|
||||
IsSpace = FALSE;
|
||||
while (*StrPtr != 0) {
|
||||
if (*StrPtr == L' ') {
|
||||
*StrPtr = 0;
|
||||
IsSpace = TRUE;
|
||||
} else {
|
||||
if (IsSpace) {
|
||||
//
|
||||
// Start of a parameter.
|
||||
//
|
||||
if (VlanIdStr == NULL) {
|
||||
//
|
||||
// 2nd parameter is VLAN ID.
|
||||
//
|
||||
VlanIdStr = StrPtr;
|
||||
} else if (PriorityStr == NULL) {
|
||||
//
|
||||
// 3rd parameter is Priority.
|
||||
//
|
||||
PriorityStr = StrPtr;
|
||||
} else {
|
||||
//
|
||||
// Ignore else parameters.
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IsSpace = FALSE;
|
||||
}
|
||||
|
||||
StrPtr++;
|
||||
}
|
||||
|
||||
Handle = NicNameToHandle (Name);
|
||||
if (Handle == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
VlanConfig = OpenVlanConfigProtocol (Handle);
|
||||
if (VlanConfig == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Check VLAN ID.
|
||||
//
|
||||
if ((VlanIdStr == NULL) || (*VlanIdStr == 0)) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
VlanId = StrToVlanId (VlanIdStr);
|
||||
if (VlanId > 4094) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Check Priority.
|
||||
//
|
||||
if ((PriorityStr != NULL) && (*PriorityStr != 0)) {
|
||||
Priority = StrDecimalToUintn (PriorityStr);
|
||||
if (Priority > 7) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_PRIORITY), mHiiHandle, PriorityStr);
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Set VLAN
|
||||
//
|
||||
Status = VlanConfig->Set (VlanConfig, (UINT16) VlanId, (UINT8) Priority);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_FAIL), mHiiHandle, Status);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Connect the VLAN device.
|
||||
//
|
||||
VlanHandle = NetLibGetVlanHandle (Handle, (UINT16) VlanId);
|
||||
if (VlanHandle != NULL) {
|
||||
gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);
|
||||
}
|
||||
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_SUCCESS), mHiiHandle);
|
||||
|
||||
Exit:
|
||||
if (VlanConfig != NULL) {
|
||||
CloseVlanConfigProtocol (Handle);
|
||||
}
|
||||
|
||||
FreePool (Name);
|
||||
}
|
||||
|
||||
/**
|
||||
Remove a VLAN device.
|
||||
|
||||
@param[in] ParamStr Parameter string from user input.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DeleteVlan (
|
||||
IN CHAR16 *ParamStr
|
||||
)
|
||||
{
|
||||
CHAR16 *Name;
|
||||
CHAR16 *VlanIdStr;
|
||||
CHAR16 *StrPtr;
|
||||
UINTN VlanId;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
||||
EFI_STATUS Status;
|
||||
UINT16 NumberOfVlan;
|
||||
EFI_VLAN_FIND_DATA *VlanData;
|
||||
|
||||
VlanConfig = NULL;
|
||||
|
||||
if (ParamStr == NULL) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);
|
||||
return ;
|
||||
}
|
||||
|
||||
StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);
|
||||
if (StrPtr == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
Name = StrPtr;
|
||||
VlanIdStr = NULL;
|
||||
while (*StrPtr != 0) {
|
||||
if (*StrPtr == L'.') {
|
||||
*StrPtr = 0;
|
||||
VlanIdStr = StrPtr + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
StrPtr++;
|
||||
}
|
||||
|
||||
Handle = NicNameToHandle (Name);
|
||||
if (Handle == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
VlanConfig = OpenVlanConfigProtocol (Handle);
|
||||
if (VlanConfig == NULL) {
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Check VLAN ID
|
||||
//
|
||||
if (VlanIdStr == NULL || *VlanIdStr == 0) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
VlanId = StrToVlanId (VlanIdStr);
|
||||
if (VlanId > 4094) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Delete VLAN.
|
||||
//
|
||||
Status = VlanConfig->Remove (VlanConfig, (UINT16) VlanId);
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NOT_FOUND), mHiiHandle);
|
||||
} else {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_FAIL), mHiiHandle, Status);
|
||||
}
|
||||
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether this is the last VLAN to remove.
|
||||
//
|
||||
Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// This is the last VLAN to remove, try to connect the controller handle.
|
||||
//
|
||||
gBS->ConnectController (Handle, NULL, NULL, TRUE);
|
||||
} else {
|
||||
FreePool (VlanData);
|
||||
}
|
||||
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_SUCCESS), mHiiHandle);
|
||||
|
||||
Exit:
|
||||
if (VlanConfig != NULL) {
|
||||
CloseVlanConfigProtocol (Handle);
|
||||
}
|
||||
|
||||
FreePool (Name);
|
||||
}
|
||||
|
||||
/**
|
||||
The actual entry point for the application.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The entry point executed successfully.
|
||||
@retval other Some error occur when executing this entry point.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
VlanConfigMain (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
LIST_ENTRY *List;
|
||||
CONST CHAR16 *Str;
|
||||
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
|
||||
EFI_STATUS Status;
|
||||
|
||||
mImageHandle = ImageHandle;
|
||||
|
||||
//
|
||||
// Retrieve HII package list from ImageHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ImageHandle,
|
||||
&gEfiHiiPackageListProtocolGuid,
|
||||
(VOID **) &PackageList,
|
||||
ImageHandle,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Publish HII package list to HII Database.
|
||||
//
|
||||
Status = gHiiDatabase->NewPackageList (
|
||||
gHiiDatabase,
|
||||
PackageList,
|
||||
NULL,
|
||||
&mHiiHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (mHiiHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
List = NULL;
|
||||
ShellCommandLineParseEx (mParamList, &List, NULL, FALSE, FALSE);
|
||||
if (List == NULL) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (ShellCommandLineGetFlag (List, L"-l")) {
|
||||
Str = ShellCommandLineGetValue (List, L"-l");
|
||||
DisplayVlan ((CHAR16 *) Str);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (ShellCommandLineGetFlag (List, L"-a")) {
|
||||
Str = ShellCommandLineGetValue (List, L"-a");
|
||||
AddVlan ((CHAR16 *) Str);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (ShellCommandLineGetFlag (List, L"-d")) {
|
||||
Str = ShellCommandLineGetValue (List, L"-d");
|
||||
DeleteVlan ((CHAR16 *) Str);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//
|
||||
// No valid argument till now.
|
||||
//
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);
|
||||
|
||||
Exit:
|
||||
if (List != NULL) {
|
||||
ShellCommandLineFreeVarList (List);
|
||||
}
|
||||
|
||||
//
|
||||
// Remove our string package from HII database.
|
||||
//
|
||||
HiiRemovePackages (mHiiHandle);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
## @file
|
||||
# Shell application VLAN configuration.
|
||||
#
|
||||
# It is shell application which is used to get and set VLAN configuration.
|
||||
#
|
||||
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = VConfig
|
||||
FILE_GUID = 87E36301-0406-44db-AAF3-9E0E591F3725
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = VlanConfigMain
|
||||
MODULE_UNI_FILE = VConfig.uni
|
||||
|
||||
#
|
||||
#
|
||||
# This flag specifies whether HII resource section is generated into PE image.
|
||||
#
|
||||
UEFI_HII_RESOURCE_SECTION = TRUE
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
VConfigStrings.uni
|
||||
VConfig.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
NetworkPkg/NetworkPkg.dec
|
||||
ShellPkg/ShellPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiApplicationEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
UefiHiiServicesLib
|
||||
UefiLib
|
||||
ShellLib
|
||||
NetLib
|
||||
MemoryAllocationLib
|
||||
HiiLib
|
||||
|
||||
[Protocols]
|
||||
gEfiVlanConfigProtocolGuid ## CONSUMES
|
||||
gEfiHiiPackageListProtocolGuid ## CONSUMES
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
VConfigExtra.uni
|
|
@ -0,0 +1,16 @@
|
|||
// /** @file
|
||||
// Shell application VLAN configuration.
|
||||
//
|
||||
// It is shell application which is used to get and set VLAN configuration.
|
||||
//
|
||||
// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "Shell application VLAN configuration"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "It is shell application which is used to get and set VLAN configuration."
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// /** @file
|
||||
// VConfig Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"Vlan Config App"
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/** @file
|
||||
String definitions for VLAN configuration Shell application.
|
||||
|
||||
Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#langdef en-US "English"
|
||||
|
||||
#string STR_VCONFIG_LOCATE_FAIL #language en-US "Failed to locate EFI_VLAN_CONFIG_PROTOCOL - %r.\n"
|
||||
#string STR_VCONFIG_MAC_FAIL #language en-US "Failed to get MAC address - %r.\n"
|
||||
#string STR_VCONFIG_FIND_FAIL #language en-US "Failed to find VLAN configuration - %r.\n"
|
||||
#string STR_VCONFIG_SET_FAIL #language en-US "Failed to set VLAN configuration - %r.\n"
|
||||
#string STR_VCONFIG_REMOVE_FAIL #language en-US "Failed to remove VLAN - %r.\n"
|
||||
#string STR_VCONFIG_NO_IF #language en-US "Network interface not specified.\n"
|
||||
#string STR_VCONFIG_NO_VID #language en-US "VLAN ID not specified.\n"
|
||||
#string STR_VCONFIG_INVALID_IF #language en-US "Invalid network interface - %s.\n"
|
||||
#string STR_VCONFIG_INVALID_VID #language en-US "Invalid VLAN ID - %s.\n"
|
||||
#string STR_VCONFIG_INVALID_PRIORITY #language en-US "Invalid VLAN Priority - %s.\n"
|
||||
#string STR_VCONFIG_NOT_FOUND #language en-US "Cannot find the VLAN device specified.\n"
|
||||
#string STR_VCONFIG_VLAN_DISPLAY #language en-US " VLAN ID: %4d Priority: %d\n"
|
||||
#string STR_VCONFIG_NO_VLAN #language en-US " VLAN is not configured.\n"
|
||||
#string STR_VCONFIG_ETH_MAC #language en-US "eth%d MAC:%s\n"
|
||||
#string STR_VCONFIG_SET_SUCCESS #language en-US "VLAN device added.\n"
|
||||
#string STR_VCONFIG_REMOVE_SUCCESS #language en-US "VLAN device removed.\n"
|
||||
#string STR_VCONFIG_NO_ARG #language en-US "Invalid argument, try "-?" for help.\n"
|
||||
|
||||
#string STR_VCONFIG_HELP #language en-US ""
|
||||
".TH VConfig 0 "Display or modify VLAN configuration for network interface."\r\n"
|
||||
".SH NAME\r\n"
|
||||
"Display or modify VLAN configuration for network interface.\r\n"
|
||||
".SH SYNOPSIS\r\n"
|
||||
" \r\n"
|
||||
"VCONFIG [-?] [-l [IfName]] [-a IfName VlanId [Priority]] [-d IfName.VlanId]\r\n"
|
||||
".SH OPTIONS\r\n"
|
||||
" \r\n"
|
||||
" -l Display VLAN configuration for all or specified interface.\r\n"
|
||||
" -a Add a VLAN device for the network interface.\r\n"
|
||||
" -d Delete a VLAN device.\r\n"
|
||||
" IfName Name of network interface, e.g. eth0, eth1.\r\n"
|
||||
" VlanId Unique VLAN identifier (0~4094).\r\n"
|
||||
" Priority 802.1Q priority level (0~7), default 0.\r\n"
|
||||
".SH EXAMPLES\r\n"
|
||||
" \r\n"
|
||||
"Examples:\r\n"
|
||||
" * To display VLAN configuration:\r\n"
|
||||
" fs0:\> vconfig -l\r\n"
|
||||
" fs0:\> vconfig -l eth0\r\n"
|
||||
"\r\n"
|
||||
" * To add VLAN device:\r\n"
|
||||
" fs0:\> vconfig -a eth0 1000\r\n"
|
||||
" fs0:\> vconfig -a eth0 2000 7\r\n"
|
||||
"\r\n"
|
||||
" * To delete VLAN device:\r\n"
|
||||
" fs0:\> vconfig -d eth0.1000\r\n"
|
|
@ -0,0 +1,811 @@
|
|||
/** @file
|
||||
ARP driver functions.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "ArpDriver.h"
|
||||
#include "ArpImpl.h"
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding = {
|
||||
ArpDriverBindingSupported,
|
||||
ArpDriverBindingStart,
|
||||
ArpDriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Create and initialize the arp service context data.
|
||||
|
||||
@param[in] ImageHandle The image handle representing the loaded driver
|
||||
image.
|
||||
@param[in] ControllerHandle The controller handle the driver binds to.
|
||||
@param[in, out] ArpService Pointer to the buffer containing the arp service
|
||||
context data.
|
||||
|
||||
@retval EFI_SUCCESS The arp service context is initialized.
|
||||
|
||||
@retval EFI_UNSUPPORTED The underlayer Snp mode type is not ethernet.
|
||||
Failed to initialize the service context.
|
||||
@retval other Failed to initialize the arp service context.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ArpCreateService (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN OUT ARP_SERVICE_DATA *ArpService
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (ArpService != NULL);
|
||||
|
||||
ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;
|
||||
|
||||
//
|
||||
// Init the lists.
|
||||
//
|
||||
InitializeListHead (&ArpService->ChildrenList);
|
||||
InitializeListHead (&ArpService->PendingRequestTable);
|
||||
InitializeListHead (&ArpService->DeniedCacheTable);
|
||||
InitializeListHead (&ArpService->ResolvedCacheTable);
|
||||
|
||||
//
|
||||
// Init the servicebinding protocol members.
|
||||
//
|
||||
ArpService->ServiceBinding.CreateChild = ArpServiceBindingCreateChild;
|
||||
ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;
|
||||
|
||||
//
|
||||
// Save the handles.
|
||||
//
|
||||
ArpService->ImageHandle = ImageHandle;
|
||||
ArpService->ControllerHandle = ControllerHandle;
|
||||
|
||||
//
|
||||
// Create a MNP child instance.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
ControllerHandle,
|
||||
ImageHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
&ArpService->MnpChildHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the MNP protocol.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
(VOID **)&ArpService->Mnp,
|
||||
ImageHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the underlayer Snp mode data.
|
||||
//
|
||||
Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);
|
||||
if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
|
||||
//
|
||||
// Only support the ethernet.
|
||||
//
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the Mnp config parameters.
|
||||
//
|
||||
ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;
|
||||
ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;
|
||||
ArpService->MnpConfigData.ProtocolTypeFilter = ARP_ETHER_PROTO_TYPE;
|
||||
ArpService->MnpConfigData.EnableUnicastReceive = TRUE;
|
||||
ArpService->MnpConfigData.EnableMulticastReceive = FALSE;
|
||||
ArpService->MnpConfigData.EnableBroadcastReceive = TRUE;
|
||||
ArpService->MnpConfigData.EnablePromiscuousReceive = FALSE;
|
||||
ArpService->MnpConfigData.FlushQueuesOnReset = TRUE;
|
||||
ArpService->MnpConfigData.EnableReceiveTimestamps = FALSE;
|
||||
ArpService->MnpConfigData.DisableBackgroundPolling = FALSE;
|
||||
|
||||
//
|
||||
// Configure the Mnp child.
|
||||
//
|
||||
Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the event used in the RxToken.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
ArpOnFrameRcvd,
|
||||
ArpService,
|
||||
&ArpService->RxToken.Event
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the Arp heartbeat timer.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL | EVT_TIMER,
|
||||
TPL_CALLBACK,
|
||||
ArpTimerHandler,
|
||||
ArpService,
|
||||
&ArpService->PeriodicTimer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Start the heartbeat timer.
|
||||
//
|
||||
Status = gBS->SetTimer (
|
||||
ArpService->PeriodicTimer,
|
||||
TimerPeriodic,
|
||||
ARP_PERIODIC_TIMER_INTERVAL
|
||||
);
|
||||
|
||||
ERROR_EXIT:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Clean the arp service context data.
|
||||
|
||||
@param[in, out] ArpService Pointer to the buffer containing the arp service
|
||||
context data.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpCleanService (
|
||||
IN OUT ARP_SERVICE_DATA *ArpService
|
||||
)
|
||||
{
|
||||
NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);
|
||||
|
||||
if (ArpService->PeriodicTimer != NULL) {
|
||||
//
|
||||
// Cancle and close the PeriodicTimer.
|
||||
//
|
||||
gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);
|
||||
gBS->CloseEvent (ArpService->PeriodicTimer);
|
||||
}
|
||||
|
||||
if (ArpService->RxToken.Event != NULL) {
|
||||
//
|
||||
// Cancle the RxToken and close the event in the RxToken.
|
||||
//
|
||||
ArpService->Mnp->Cancel (ArpService->Mnp, NULL);
|
||||
gBS->CloseEvent (ArpService->RxToken.Event);
|
||||
}
|
||||
|
||||
if (ArpService->Mnp != NULL) {
|
||||
//
|
||||
// Reset the Mnp child and close the Mnp protocol.
|
||||
//
|
||||
ArpService->Mnp->Configure (ArpService->Mnp, NULL);
|
||||
gBS->CloseProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
ArpService->ImageHandle,
|
||||
ArpService->ControllerHandle
|
||||
);
|
||||
}
|
||||
|
||||
if (ArpService->MnpChildHandle != NULL) {
|
||||
//
|
||||
// Destroy the mnp child.
|
||||
//
|
||||
NetLibDestroyServiceChild(
|
||||
ArpService->ControllerHandle,
|
||||
ArpService->ImageHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
ArpService->MnpChildHandle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Callback function which provided by user to remove one node in NetDestroyLinkList process.
|
||||
|
||||
@param[in] Entry The entry to be removed.
|
||||
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been removed successfully.
|
||||
@retval Others Fail to remove the entry.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDestroyChildEntryInHandleBuffer (
|
||||
IN LIST_ENTRY *Entry,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
|
||||
if (Entry == NULL || Context == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
|
||||
ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
|
||||
|
||||
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||
}
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller.
|
||||
|
||||
If a child device is provided, it further tests to see if this driver supports
|
||||
creating a handle for the specified child device.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver
|
||||
specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed
|
||||
by the driver specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by
|
||||
a different driver or an application that
|
||||
requires exclusive acces. Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the
|
||||
driver specified by This.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Test to see if Arp SB is already installed.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Test to see if MNP SB is installed.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been
|
||||
moved into this common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
|
||||
aligned EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified
|
||||
by This must have been called with the same calling parameters, and Supported()
|
||||
must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.
|
||||
Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
|
||||
resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
|
||||
//
|
||||
// Allocate a zero pool for ArpService.
|
||||
//
|
||||
ArpService = AllocateZeroPool (sizeof(ARP_SERVICE_DATA));
|
||||
if (ArpService == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the arp service context data.
|
||||
//
|
||||
Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the ARP service binding protocol.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
&ArpService->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// OK, start to receive arp packets from Mnp.
|
||||
//
|
||||
Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
ERROR:
|
||||
|
||||
//
|
||||
// On error, clean the arp service context data, and free the memory allocated.
|
||||
//
|
||||
ArpCleanService (ArpService);
|
||||
FreePool (ArpService);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
Release the control of this controller and remove the IScsi functions. The Stop()
|
||||
function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
Not used.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.Not used.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
LIST_ENTRY *List;
|
||||
|
||||
//
|
||||
// Get the NicHandle which the arp servicebinding is installed on.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to get the arp servicebinding protocol on the NicHandle.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
(VOID **)&ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
||||
|
||||
if (NumberOfChildren != 0) {
|
||||
//
|
||||
// NumberOfChildren is not zero, destroy all the ARP children instances.
|
||||
//
|
||||
List = &ArpService->ChildrenList;
|
||||
Status = NetDestroyLinkList (
|
||||
List,
|
||||
ArpDestroyChildEntryInHandleBuffer,
|
||||
ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
|
||||
ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
|
||||
ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
|
||||
} else if (IsListEmpty (&ArpService->ChildrenList)) {
|
||||
//
|
||||
// Uninstall the ARP ServiceBinding protocol.
|
||||
//
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
NicHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
&ArpService->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Clean the arp servicebinding context data and free the memory allocated.
|
||||
//
|
||||
ArpCleanService (ArpService);
|
||||
|
||||
FreePool (ArpService);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned
|
||||
in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
|
||||
installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing
|
||||
UEFI handle, then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
VOID *Mnp;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Allocate memory for the instance context data.
|
||||
//
|
||||
Instance = AllocateZeroPool (sizeof(ARP_INSTANCE_DATA));
|
||||
if (Instance == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
|
||||
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Init the instance context data.
|
||||
//
|
||||
ArpInitInstance (ArpService, Instance);
|
||||
|
||||
//
|
||||
// Install the ARP protocol onto the ChildHandle.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
(VOID *)&Instance->ArpProto,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));
|
||||
|
||||
FreePool (Instance);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the ChildHandle.
|
||||
//
|
||||
Instance->Handle = *ChildHandle;
|
||||
|
||||
//
|
||||
// Open the Managed Network protocol BY_CHILD.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
(VOID **) &Mnp,
|
||||
gArpDriverBinding.DriverBindingHandle,
|
||||
Instance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Insert the instance into children list managed by the arp service context data.
|
||||
//
|
||||
InsertTailList (&ArpService->ChildrenList, &Instance->List);
|
||||
ArpService->ChildrenNumber++;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
ERROR:
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
gBS->CloseProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
gArpDriverBinding.DriverBindingHandle,
|
||||
Instance->Handle
|
||||
);
|
||||
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
Instance->Handle,
|
||||
&gEfiArpProtocolGuid,
|
||||
&Instance->ArpProto,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Free the allocated memory.
|
||||
//
|
||||
FreePool (Instance);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
|
||||
being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_ARP_PROTOCOL *Arp;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Get the arp protocol.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
(VOID **)&Arp,
|
||||
ArpService->ImageHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
|
||||
|
||||
if (Instance->InDestroy) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Use the InDestroy as a flag to avoid re-entrance.
|
||||
//
|
||||
Instance->InDestroy = TRUE;
|
||||
|
||||
//
|
||||
// Close the Managed Network protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
gArpDriverBinding.DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
//
|
||||
// Uninstall the ARP protocol.
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
&Instance->ArpProto,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
|
||||
Status));
|
||||
|
||||
Instance->InDestroy = FALSE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
if (Instance->Configured) {
|
||||
//
|
||||
// Delete the related cache entry.
|
||||
//
|
||||
ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);
|
||||
|
||||
//
|
||||
// Reset the instance configuration.
|
||||
//
|
||||
ArpConfigureInstance (Instance, NULL);
|
||||
}
|
||||
|
||||
//
|
||||
// Remove this instance from the ChildrenList.
|
||||
//
|
||||
RemoveEntryList (&Instance->List);
|
||||
ArpService->ChildrenNumber--;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
FreePool (Instance);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
The entry point for Arp driver which installs the driver binding and component name
|
||||
protocol on its ImageHandle.
|
||||
|
||||
@param[in] ImageHandle The image handle of the driver.
|
||||
@param[in] SystemTable The system table.
|
||||
|
||||
@retval EFI_SUCCESS if the driver binding and component name protocols
|
||||
are successfully
|
||||
@retval Others Failed to install the protocols.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
return EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gArpDriverBinding,
|
||||
ImageHandle,
|
||||
&gArpComponentName,
|
||||
&gArpComponentName2
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
/** @file
|
||||
ARP driver header file.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _ARP_DRIVER_H_
|
||||
#define _ARP_DRIVER_H_
|
||||
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/Arp.h>
|
||||
#include <Protocol/ManagedNetwork.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
|
||||
|
||||
//
|
||||
// Global variables
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gArpComponentName;
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gArpComponentName2;
|
||||
|
||||
//
|
||||
// Function prototypes for the Drivr Binding Protocol
|
||||
//
|
||||
/**
|
||||
Tests to see if this driver supports a given controller.
|
||||
|
||||
If a child device is provided, it further tests to see if this driver supports
|
||||
creating a handle for the specified child device.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver
|
||||
specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed
|
||||
by the driver specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by
|
||||
a different driver or an application that
|
||||
requires exclusive acces. Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the
|
||||
driver specified by This.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been
|
||||
moved into this common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
|
||||
aligned EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified
|
||||
by This must have been called with the same calling parameters, and Supported()
|
||||
must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.
|
||||
Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
|
||||
resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
Release the control of this controller and remove the IScsi functions. The Stop()
|
||||
function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
Not used.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.Not used.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned
|
||||
in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
|
||||
installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing
|
||||
UEFI handle, then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
|
||||
being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the driver.
|
||||
|
||||
This function retrieves the user readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that wish to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
## @file
|
||||
# This module produces EFI ARP Protocol and EFI ARP Service Binding Protocol.
|
||||
#
|
||||
# This module produces EFI ARP Protocol upon EFI MNP Protocol, to provide a generic
|
||||
# implementation of the Address Resolution Protocol that is described in RFCs 826
|
||||
# and 1122.
|
||||
#
|
||||
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = ArpDxe
|
||||
MODULE_UNI_FILE = ArpDxe.uni
|
||||
FILE_GUID = 529D3F93-E8E9-4e73-B1E1-BDF6A9D50113
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = ArpDriverEntryPoint
|
||||
UNLOAD_IMAGE = NetLibDefaultUnload
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 EBC
|
||||
#
|
||||
# DRIVER_BINDING = gArpDriverBinding
|
||||
# COMPONENT_NAME = gArpComponentName
|
||||
# COMPONENT_NAME2 = gArpComponentName2
|
||||
#
|
||||
|
||||
[Sources]
|
||||
ArpMain.c
|
||||
ArpDriver.h
|
||||
ComponentName.c
|
||||
ArpImpl.h
|
||||
ArpImpl.c
|
||||
ArpDriver.c
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
NetworkPkg/NetworkPkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
DebugLib
|
||||
NetLib
|
||||
DpcLib
|
||||
|
||||
[Protocols]
|
||||
gEfiArpServiceBindingProtocolGuid ## BY_START
|
||||
gEfiManagedNetworkServiceBindingProtocolGuid ## TO_START
|
||||
gEfiArpProtocolGuid ## BY_START
|
||||
gEfiManagedNetworkProtocolGuid ## TO_START
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
ArpDxeExtra.uni
|
|
@ -0,0 +1,18 @@
|
|||
// /** @file
|
||||
// This module produces EFI ARP Protocol and EFI ARP Service Binding Protocol.
|
||||
//
|
||||
// This module produces EFI ARP Protocol upon EFI MNP Protocol, to provide a generic
|
||||
// implementation of the Address Resolution Protocol that is described in RFCs 826
|
||||
// and 1122.
|
||||
//
|
||||
// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "EFI Address Resolution Protocol"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI ARP Protocol using the EFI MNP Protocol to provide a generic implementation of the Address Resolution Protocol that is described in RFCs 826 and 1122."
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// /** @file
|
||||
// ArpDxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"ARP DXE Driver"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,770 @@
|
|||
/** @file
|
||||
EFI Address Resolution Protocol (ARP) Protocol interface header file.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _ARP_IMPL_H_
|
||||
#define _ARP_IMPL_H_
|
||||
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/Arp.h>
|
||||
#include <Protocol/ManagedNetwork.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DpcLib.h>
|
||||
|
||||
//
|
||||
// Ethernet protocol type definitions.
|
||||
//
|
||||
#define ARP_ETHER_PROTO_TYPE 0x0806
|
||||
#define IPV4_ETHER_PROTO_TYPE 0x0800
|
||||
#define IPV6_ETHER_PROTO_TYPE 0x86DD
|
||||
|
||||
//
|
||||
// ARP opcode definitions.
|
||||
//
|
||||
#define ARP_OPCODE_REQUEST 0x0001
|
||||
#define ARP_OPCODE_REPLY 0x0002
|
||||
|
||||
//
|
||||
// ARP timeout, retry count and interval definitions.
|
||||
//
|
||||
#define ARP_DEFAULT_TIMEOUT_VALUE (400 * TICKS_PER_SECOND)
|
||||
#define ARP_DEFAULT_RETRY_COUNT 2
|
||||
#define ARP_DEFAULT_RETRY_INTERVAL (5 * TICKS_PER_MS)
|
||||
#define ARP_PERIODIC_TIMER_INTERVAL (500 * TICKS_PER_MS)
|
||||
|
||||
//
|
||||
// ARP packet head definition.
|
||||
//
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT16 HwType;
|
||||
UINT16 ProtoType;
|
||||
UINT8 HwAddrLen;
|
||||
UINT8 ProtoAddrLen;
|
||||
UINT16 OpCode;
|
||||
} ARP_HEAD;
|
||||
#pragma pack()
|
||||
|
||||
//
|
||||
// ARP Address definition for internal use.
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 *SenderHwAddr;
|
||||
UINT8 *SenderProtoAddr;
|
||||
UINT8 *TargetHwAddr;
|
||||
UINT8 *TargetProtoAddr;
|
||||
} ARP_ADDRESS;
|
||||
|
||||
#define MATCH_SW_ADDRESS 0x1
|
||||
#define MATCH_HW_ADDRESS 0x2
|
||||
|
||||
//
|
||||
// Enumeration for the search type. A search type is specified as the keyword to find
|
||||
// a cache entry in the cache table.
|
||||
//
|
||||
typedef enum {
|
||||
ByNone = 0,
|
||||
ByProtoAddress = MATCH_SW_ADDRESS,
|
||||
ByHwAddress = MATCH_HW_ADDRESS,
|
||||
ByBoth = MATCH_SW_ADDRESS | MATCH_HW_ADDRESS
|
||||
} FIND_OPTYPE;
|
||||
|
||||
#define ARP_INSTANCE_DATA_SIGNATURE SIGNATURE_32('A', 'R', 'P', 'I')
|
||||
|
||||
/**
|
||||
Returns a pointer to the ARP_INSTANCE_DATA structure from the input a.
|
||||
|
||||
If the signatures matches, then a pointer to the data structure that contains
|
||||
a specified field of that data structure is returned.
|
||||
|
||||
@param a Pointer to the field specified by ArpProto within a data
|
||||
structure of type ARP_INSTANCE_DATA.
|
||||
|
||||
**/
|
||||
#define ARP_INSTANCE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
ARP_INSTANCE_DATA, \
|
||||
ArpProto, \
|
||||
ARP_INSTANCE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
typedef struct _ARP_SERVICE_DATA ARP_SERVICE_DATA;
|
||||
|
||||
//
|
||||
// ARP instance context data structure.
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_ARP_PROTOCOL ArpProto;
|
||||
LIST_ENTRY List;
|
||||
EFI_ARP_CONFIG_DATA ConfigData;
|
||||
BOOLEAN Configured;
|
||||
BOOLEAN InDestroy;
|
||||
} ARP_INSTANCE_DATA;
|
||||
|
||||
#define ARP_SERVICE_DATA_SIGNATURE SIGNATURE_32('A', 'R', 'P', 'S')
|
||||
|
||||
/**
|
||||
Returns a pointer to the ARP_SERVICE_DATA structure from the input a.
|
||||
|
||||
If the signatures matches, then a pointer to the data structure that contains
|
||||
a specified field of that data structure is returned.
|
||||
|
||||
@param a Pointer to the field specified by ServiceBinding within
|
||||
a data structure of type ARP_SERVICE_DATA.
|
||||
|
||||
**/
|
||||
#define ARP_SERVICE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
ARP_SERVICE_DATA, \
|
||||
ServiceBinding, \
|
||||
ARP_SERVICE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
//
|
||||
// ARP service data structure.
|
||||
//
|
||||
struct _ARP_SERVICE_DATA {
|
||||
UINT32 Signature;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
|
||||
EFI_HANDLE MnpChildHandle;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_HANDLE ControllerHandle;
|
||||
|
||||
EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
|
||||
EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
|
||||
EFI_MANAGED_NETWORK_COMPLETION_TOKEN RxToken;
|
||||
|
||||
EFI_SIMPLE_NETWORK_MODE SnpMode;
|
||||
|
||||
UINTN ChildrenNumber;
|
||||
LIST_ENTRY ChildrenList;
|
||||
|
||||
LIST_ENTRY PendingRequestTable;
|
||||
LIST_ENTRY DeniedCacheTable;
|
||||
LIST_ENTRY ResolvedCacheTable;
|
||||
|
||||
EFI_EVENT PeriodicTimer;
|
||||
};
|
||||
|
||||
//
|
||||
// User request context structure.
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY List;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_EVENT UserRequestEvent;
|
||||
VOID *UserHwAddrBuffer;
|
||||
} USER_REQUEST_CONTEXT;
|
||||
|
||||
#define ARP_MAX_PROTOCOL_ADDRESS_LEN sizeof(EFI_IP_ADDRESS)
|
||||
#define ARP_MAX_HARDWARE_ADDRESS_LEN sizeof(EFI_MAC_ADDRESS)
|
||||
|
||||
typedef union {
|
||||
UINT8 ProtoAddress[ARP_MAX_PROTOCOL_ADDRESS_LEN];
|
||||
UINT8 HwAddress[ARP_MAX_HARDWARE_ADDRESS_LEN];
|
||||
} NET_ARP_ADDRESS_UNION;
|
||||
|
||||
//
|
||||
// ARP address structure in an ARP packet.
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
UINT8 Length;
|
||||
UINT8 *AddressPtr;
|
||||
NET_ARP_ADDRESS_UNION Buffer;
|
||||
} NET_ARP_ADDRESS;
|
||||
|
||||
//
|
||||
// Enumeration for ARP address type.
|
||||
//
|
||||
typedef enum {
|
||||
Hardware,
|
||||
Protocol
|
||||
} ARP_ADDRESS_TYPE;
|
||||
|
||||
//
|
||||
// ARP cache entry definition.
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY List;
|
||||
|
||||
UINT32 RetryCount;
|
||||
UINT32 DefaultDecayTime;
|
||||
UINT32 DecayTime;
|
||||
UINT32 NextRetryTime;
|
||||
|
||||
NET_ARP_ADDRESS Addresses[2];
|
||||
|
||||
LIST_ENTRY UserRequestList;
|
||||
} ARP_CACHE_ENTRY;
|
||||
|
||||
/**
|
||||
This function is used to assign a station address to the ARP cache for this instance
|
||||
of the ARP driver.
|
||||
|
||||
Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will
|
||||
respond to ARP requests that match this registered station address. A call to
|
||||
this function with the ConfigData field set to NULL will reset this ARP instance.
|
||||
|
||||
Once a protocol type and station address have been assigned to this ARP instance,
|
||||
all the following ARP functions will use this information. Attempting to change
|
||||
the protocol type or station address to a configured ARP instance will result in errors.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure.
|
||||
|
||||
@retval EFI_SUCCESS The new station address was successfully
|
||||
registered.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. SwAddressLength is zero when
|
||||
ConfigData is not NULL. StationAddress is NULL
|
||||
when ConfigData is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or
|
||||
StationAddress is different from the one that is
|
||||
already registered.
|
||||
@retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be
|
||||
allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpConfigure (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This function is used to insert entries into the ARP cache.
|
||||
|
||||
ARP cache entries are typically inserted and updated by network protocol drivers
|
||||
as network traffic is processed. Most ARP cache entries will time out and be
|
||||
deleted if the network traffic stops. ARP cache entries that were inserted
|
||||
by the Add() function may be static (will not time out) or dynamic (will time out).
|
||||
Default ARP cache timeout values are not covered in most network protocol
|
||||
specifications (although RFC 1122 comes pretty close) and will only be
|
||||
discussed in general in this specification. The timeout values that are
|
||||
used in the EFI Sample Implementation should be used only as a guideline.
|
||||
Final product implementations of the EFI network stack should be tuned for
|
||||
their expected network environments.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param DenyFlag Set to TRUE if this entry is a deny entry. Set to
|
||||
FALSE if this entry is a normal entry.
|
||||
@param TargetSwAddress Pointer to a protocol address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TargetHwAddress Pointer to a hardware address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TimeoutValue Time in 100-ns units that this entry will remain
|
||||
in the ARP cache. A value of zero means that the
|
||||
entry is permanent. A nonzero value will override
|
||||
the one given by Configure() if the entry to be
|
||||
added is a dynamic entry.
|
||||
@param Overwrite If TRUE, the matching cache entry will be
|
||||
overwritten with the supplied parameters. If
|
||||
FALSE, EFI_ACCESS_DENIED is returned if the
|
||||
corresponding cache entry already exists.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been added or updated.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. DenyFlag is FALSE and
|
||||
TargetHwAddress is NULL. DenyFlag is FALSE and
|
||||
TargetSwAddress is NULL. TargetHwAddress is NULL
|
||||
and TargetSwAddress is NULL. Both TargetSwAddress
|
||||
and TargetHwAddress are not NULL when DenyFlag is
|
||||
TRUE.
|
||||
@retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated.
|
||||
@retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite
|
||||
is not true.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpAdd (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN DenyFlag,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN VOID *TargetHwAddress OPTIONAL,
|
||||
IN UINT32 TimeoutValue,
|
||||
IN BOOLEAN Overwrite
|
||||
);
|
||||
|
||||
/**
|
||||
This function searches the ARP cache for matching entries and allocates a buffer into
|
||||
which those entries are copied.
|
||||
|
||||
The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which
|
||||
are protocol address pairs and hardware address pairs.
|
||||
When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer
|
||||
is not NULL), the ARP cache timeout for the found entry is reset if Refresh is
|
||||
set to TRUE. If the found ARP cache entry is a permanent entry, it is not
|
||||
affected by Refresh.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to look for matching software protocol
|
||||
addresses. Set to FALSE to look for matching
|
||||
hardware protocol addresses.
|
||||
@param AddressBuffer Pointer to address buffer. Set to NULL to match
|
||||
all addresses.
|
||||
@param EntryLength The size of an entry in the entries buffer.
|
||||
@param EntryCount The number of ARP cache entries that are found by
|
||||
the specified criteria.
|
||||
@param Entries Pointer to the buffer that will receive the ARP
|
||||
cache entries.
|
||||
@param Refresh Set to TRUE to refresh the timeout value of the
|
||||
matching ARP cache entry.
|
||||
|
||||
@retval EFI_SUCCESS The requested ARP cache entries were copied into
|
||||
the buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. Both EntryCount and EntryLength are
|
||||
NULL, when Refresh is FALSE.
|
||||
@retval EFI_NOT_FOUND No matching entries were found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFind (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL,
|
||||
OUT UINT32 *EntryLength OPTIONAL,
|
||||
OUT UINT32 *EntryCount OPTIONAL,
|
||||
OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
|
||||
IN BOOLEAN Refresh
|
||||
);
|
||||
|
||||
/**
|
||||
This function removes specified ARP cache entries.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to delete matching protocol addresses.
|
||||
Set to FALSE to delete matching hardware
|
||||
addresses.
|
||||
@param AddressBuffer Pointer to the address buffer that is used as a
|
||||
key to look for the cache entry. Set to NULL to
|
||||
delete all entries.
|
||||
|
||||
@retval EFI_SUCCESS The entry was removed from the ARP cache.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND The specified deletion key was not found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDelete (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This function delete all dynamic entries from the ARP cache that match the specified
|
||||
software protocol type.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS The cache has been flushed.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND There are no matching dynamic cache entries.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFlush (
|
||||
IN EFI_ARP_PROTOCOL *This
|
||||
);
|
||||
|
||||
/**
|
||||
This function tries to resolve the TargetSwAddress and optionally returns a
|
||||
TargetHwAddress if it already exists in the ARP cache.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address to resolve.
|
||||
@param ResolvedEvent Pointer to the event that will be signaled when
|
||||
the address is resolved or some error occurs.
|
||||
@param TargetHwAddress Pointer to the buffer for the resolved hardware
|
||||
address in network byte order.
|
||||
|
||||
@retval EFI_SUCCESS The data is copied from the ARP cache into the
|
||||
TargetHwAddress buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetHwAddress is NULL.
|
||||
@retval EFI_ACCESS_DENIED The requested address is not present in the normal
|
||||
ARP cache but is present in the deny address list.
|
||||
Outgoing traffic to that address is forbidden.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_READY The request has been started and is not finished.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpRequest (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL,
|
||||
OUT VOID *TargetHwAddress
|
||||
);
|
||||
|
||||
/**
|
||||
This function aborts the previous ARP request (identified by This, TargetSwAddress
|
||||
and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
If the request is in the internal ARP request queue, the request is aborted
|
||||
immediately and its ResolvedEvent is signaled. Only an asynchronous address
|
||||
request needs to be canceled. If TargeSwAddress and ResolveEvent are both
|
||||
NULL, all the pending asynchronous requests that have been issued by This
|
||||
instance will be cancelled and their corresponding events will be signaled.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address in previous
|
||||
request session.
|
||||
@param ResolvedEvent Pointer to the event that is used as the
|
||||
notification event in previous request session.
|
||||
|
||||
@retval EFI_SUCCESS The pending request session(s) is/are aborted and
|
||||
corresponding event(s) is/are signaled.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetSwAddress is not NULL and
|
||||
ResolvedEvent is NULL. TargetSwAddress is NULL and
|
||||
ResolvedEvent is not NULL.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_FOUND The request is not issued by
|
||||
EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpCancel (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Configure the instance using the ConfigData. ConfigData is already validated.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data to be
|
||||
configured.
|
||||
@param[in] ConfigData Pointer to the configuration data used to
|
||||
configure the instance.
|
||||
|
||||
@retval EFI_SUCCESS The instance is configured with the ConfigData.
|
||||
@retval EFI_ACCESS_DENIED The instance is already configured and the
|
||||
ConfigData tries to reset some unchangeable
|
||||
fields.
|
||||
@retval EFI_INVALID_PARAMETER The ConfigData provides a non-unicast IPv4 address
|
||||
when the SwAddressType is IPv4.
|
||||
@retval EFI_OUT_OF_RESOURCES The instance fails to configure due to memory
|
||||
limitation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ArpConfigureInstance (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Find the CacheEntry, using ProtocolAddress or HardwareAddress or both, as the keyword,
|
||||
in the DeniedCacheTable.
|
||||
|
||||
@param[in] ArpService Pointer to the arp service context data.
|
||||
@param[in] ProtocolAddress Pointer to the protocol address.
|
||||
@param[in] HardwareAddress Pointer to the hardware address.
|
||||
|
||||
@return Pointer to the matched cache entry, if NULL no match is found.
|
||||
|
||||
**/
|
||||
ARP_CACHE_ENTRY *
|
||||
ArpFindDeniedCacheEntry (
|
||||
IN ARP_SERVICE_DATA *ArpService,
|
||||
IN NET_ARP_ADDRESS *ProtocolAddress OPTIONAL,
|
||||
IN NET_ARP_ADDRESS *HardwareAddress OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Find the CacheEntry which matches the requirements in the specified CacheTable.
|
||||
|
||||
@param[in] CacheTable Pointer to the arp cache table.
|
||||
@param[in] StartEntry Pointer to the start entry this search begins with
|
||||
in the cache table.
|
||||
@param[in] FindOpType The search type.
|
||||
@param[in] ProtocolAddress Pointer to the protocol address to match.
|
||||
@param[in] HardwareAddress Pointer to the hardware address to match.
|
||||
|
||||
@return Pointer to the matched arp cache entry, if NULL, no match is found.
|
||||
|
||||
**/
|
||||
ARP_CACHE_ENTRY *
|
||||
ArpFindNextCacheEntryInTable (
|
||||
IN LIST_ENTRY *CacheTable,
|
||||
IN LIST_ENTRY *StartEntry,
|
||||
IN FIND_OPTYPE FindOpType,
|
||||
IN NET_ARP_ADDRESS *ProtocolAddress OPTIONAL,
|
||||
IN NET_ARP_ADDRESS *HardwareAddress OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Allocate a cache entry and initialize it.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
|
||||
@return Pointer to the new created cache entry.
|
||||
|
||||
**/
|
||||
ARP_CACHE_ENTRY *
|
||||
ArpAllocCacheEntry (
|
||||
IN ARP_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Fill the addresses in the CacheEntry using the information passed in by
|
||||
HwAddr and SwAddr.
|
||||
|
||||
@param[in] CacheEntry Pointer to the cache entry.
|
||||
@param[in] HwAddr Pointer to the software address.
|
||||
@param[in] SwAddr Pointer to the hardware address.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpFillAddressInCacheEntry (
|
||||
IN ARP_CACHE_ENTRY *CacheEntry,
|
||||
IN NET_ARP_ADDRESS *HwAddr OPTIONAL,
|
||||
IN NET_ARP_ADDRESS *SwAddr OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Turn the CacheEntry into the resolved status.
|
||||
|
||||
@param[in] CacheEntry Pointer to the resolved cache entry.
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] UserEvent Pointer to the UserEvent to notify.
|
||||
|
||||
@return The count of notifications sent to the instance.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
ArpAddressResolved (
|
||||
IN ARP_CACHE_ENTRY *CacheEntry,
|
||||
IN ARP_INSTANCE_DATA *Instance OPTIONAL,
|
||||
IN EFI_EVENT UserEvent OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Delete cache entries in all the cache tables.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] BySwAddress Delete the cache entry by software address or by
|
||||
hardware address.
|
||||
@param[in] AddressBuffer Pointer to the buffer containing the address to
|
||||
match for the deletion.
|
||||
@param[in] Force This deletion is forced or not.
|
||||
|
||||
@return The count of the deleted cache entries.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
ArpDeleteCacheEntry (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN UINT8 *AddressBuffer OPTIONAL,
|
||||
IN BOOLEAN Force
|
||||
);
|
||||
|
||||
/**
|
||||
Send out an arp frame using the CachEntry and the ArpOpCode.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] CacheEntry Pointer to the configuration data used to
|
||||
configure the instance.
|
||||
@param[in] ArpOpCode The opcode used to send out this Arp frame, either
|
||||
request or reply.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpSendFrame (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN ARP_CACHE_ENTRY *CacheEntry,
|
||||
IN UINT16 ArpOpCode
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize the instance context data.
|
||||
|
||||
@param[in] ArpService Pointer to the arp service context data this
|
||||
instance belongs to.
|
||||
@param[out] Instance Pointer to the instance context data.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpInitInstance (
|
||||
IN ARP_SERVICE_DATA *ArpService,
|
||||
OUT ARP_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Process the Arp packets received from Mnp, the procedure conforms to RFC826.
|
||||
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameRcvdDpc (
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Queue ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK.
|
||||
|
||||
@param[in] Event The Event this notify function registered to.
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameRcvd (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Process the already sent arp packets.
|
||||
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameSentDpc (
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK.
|
||||
|
||||
@param[in] Event The Event this notify function registered to.
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameSent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Process the arp cache olding and drive the retrying arp requests.
|
||||
|
||||
@param[in] Event The Event this notify function registered to.
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpTimerHandler (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Cancel the arp request.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] TargetSwAddress Pointer to the buffer containing the target
|
||||
software address to match the arp request.
|
||||
@param[in] UserEvent The user event used to notify this request
|
||||
cancellation.
|
||||
|
||||
@return The count of the cancelled requests.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
ArpCancelRequest (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT UserEvent OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Find the cache entry in the cache table.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] BySwAddress Set to TRUE to look for matching software protocol
|
||||
addresses. Set to FALSE to look for matching
|
||||
hardware protocol addresses.
|
||||
@param[in] AddressBuffer Pointer to address buffer. Set to NULL to match
|
||||
all addresses.
|
||||
@param[out] EntryLength The size of an entry in the entries buffer.
|
||||
@param[out] EntryCount The number of ARP cache entries that are found by
|
||||
the specified criteria.
|
||||
@param[out] Entries Pointer to the buffer that will receive the ARP
|
||||
cache entries.
|
||||
@param[in] Refresh Set to TRUE to refresh the timeout value of the
|
||||
matching ARP cache entry.
|
||||
|
||||
@retval EFI_SUCCESS The requested ARP cache entries are copied into
|
||||
the buffer.
|
||||
@retval EFI_NOT_FOUND No matching entries found.
|
||||
@retval EFI_OUT_OF_RESOURCE There is a memory allocation failure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ArpFindCacheEntry (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL,
|
||||
OUT UINT32 *EntryLength OPTIONAL,
|
||||
OUT UINT32 *EntryCount OPTIONAL,
|
||||
OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
|
||||
IN BOOLEAN Refresh
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,739 @@
|
|||
/** @file
|
||||
Implementation of EFI Address Resolution Protocol (ARP) Protocol interface functions.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "ArpImpl.h"
|
||||
|
||||
|
||||
/**
|
||||
This function is used to assign a station address to the ARP cache for this instance
|
||||
of the ARP driver.
|
||||
|
||||
Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will
|
||||
respond to ARP requests that match this registered station address. A call to
|
||||
this function with the ConfigData field set to NULL will reset this ARP instance.
|
||||
|
||||
Once a protocol type and station address have been assigned to this ARP instance,
|
||||
all the following ARP functions will use this information. Attempting to change
|
||||
the protocol type or station address to a configured ARP instance will result in errors.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure.
|
||||
|
||||
@retval EFI_SUCCESS The new station address was successfully
|
||||
registered.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. SwAddressLength is zero when
|
||||
ConfigData is not NULL. StationAddress is NULL
|
||||
when ConfigData is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or
|
||||
StationAddress is different from the one that is
|
||||
already registered.
|
||||
@retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be
|
||||
allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpConfigure (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((ConfigData != NULL) &&
|
||||
((ConfigData->SwAddressLength == 0) ||
|
||||
(ConfigData->StationAddress == NULL) ||
|
||||
(ConfigData->SwAddressType <= 1500))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Configure this instance, the ConfigData has already passed the basic checks.
|
||||
//
|
||||
Status = ArpConfigureInstance (Instance, ConfigData);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function is used to insert entries into the ARP cache.
|
||||
|
||||
ARP cache entries are typically inserted and updated by network protocol drivers
|
||||
as network traffic is processed. Most ARP cache entries will time out and be
|
||||
deleted if the network traffic stops. ARP cache entries that were inserted
|
||||
by the Add() function may be static (will not time out) or dynamic (will time out).
|
||||
Default ARP cache timeout values are not covered in most network protocol
|
||||
specifications (although RFC 1122 comes pretty close) and will only be
|
||||
discussed in general in this specification. The timeout values that are
|
||||
used in the EFI Sample Implementation should be used only as a guideline.
|
||||
Final product implementations of the EFI network stack should be tuned for
|
||||
their expected network environments.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param DenyFlag Set to TRUE if this entry is a deny entry. Set to
|
||||
FALSE if this entry is a normal entry.
|
||||
@param TargetSwAddress Pointer to a protocol address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TargetHwAddress Pointer to a hardware address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TimeoutValue Time in 100-ns units that this entry will remain
|
||||
in the ARP cache. A value of zero means that the
|
||||
entry is permanent. A nonzero value will override
|
||||
the one given by Configure() if the entry to be
|
||||
added is a dynamic entry.
|
||||
@param Overwrite If TRUE, the matching cache entry will be
|
||||
overwritten with the supplied parameters. If
|
||||
FALSE, EFI_ACCESS_DENIED is returned if the
|
||||
corresponding cache entry already exists.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been added or updated.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. DenyFlag is FALSE and
|
||||
TargetHwAddress is NULL. DenyFlag is FALSE and
|
||||
TargetSwAddress is NULL. TargetHwAddress is NULL
|
||||
and TargetSwAddress is NULL. Both TargetSwAddress
|
||||
and TargetHwAddress are not NULL when DenyFlag is
|
||||
TRUE.
|
||||
@retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated.
|
||||
@retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite
|
||||
is not true.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpAdd (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN DenyFlag,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN VOID *TargetHwAddress OPTIONAL,
|
||||
IN UINT32 TimeoutValue,
|
||||
IN BOOLEAN Overwrite
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
ARP_CACHE_ENTRY *CacheEntry;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpMode;
|
||||
NET_ARP_ADDRESS MatchAddress[2];
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (((!DenyFlag) && ((TargetHwAddress == NULL) || (TargetSwAddress == NULL))) ||
|
||||
(DenyFlag && (TargetHwAddress != NULL) && (TargetSwAddress != NULL)) ||
|
||||
((TargetHwAddress == NULL) && (TargetSwAddress == NULL))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
ArpService = Instance->ArpService;
|
||||
SnpMode = &Instance->ArpService->SnpMode;
|
||||
|
||||
//
|
||||
// Fill the hardware address part in the MatchAddress.
|
||||
//
|
||||
MatchAddress[Hardware].Type = SnpMode->IfType;
|
||||
MatchAddress[Hardware].Length = (UINT8) SnpMode->HwAddressSize;
|
||||
MatchAddress[Hardware].AddressPtr = TargetHwAddress;
|
||||
|
||||
//
|
||||
// Fill the software address part in the MatchAddress.
|
||||
//
|
||||
MatchAddress[Protocol].Type = Instance->ConfigData.SwAddressType;
|
||||
MatchAddress[Protocol].Length = Instance->ConfigData.SwAddressLength;
|
||||
MatchAddress[Protocol].AddressPtr = TargetSwAddress;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// See whether the entry to add exists. Check the DeinedCacheTable first.
|
||||
//
|
||||
CacheEntry = ArpFindDeniedCacheEntry (
|
||||
ArpService,
|
||||
&MatchAddress[Protocol],
|
||||
&MatchAddress[Hardware]
|
||||
);
|
||||
|
||||
if (CacheEntry == NULL) {
|
||||
//
|
||||
// Check the ResolvedCacheTable
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->ResolvedCacheTable,
|
||||
NULL,
|
||||
ByBoth,
|
||||
&MatchAddress[Protocol],
|
||||
&MatchAddress[Hardware]
|
||||
);
|
||||
}
|
||||
|
||||
if ((CacheEntry != NULL) && !Overwrite) {
|
||||
//
|
||||
// The entry to add exists, if not Overwirte, deny this add request.
|
||||
//
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
if ((CacheEntry == NULL) && (TargetSwAddress != NULL)) {
|
||||
//
|
||||
// Check whether there are pending requests matching the entry to be added.
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->PendingRequestTable,
|
||||
NULL,
|
||||
ByProtoAddress,
|
||||
&MatchAddress[Protocol],
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
if (CacheEntry != NULL) {
|
||||
//
|
||||
// Remove it from the Table.
|
||||
//
|
||||
RemoveEntryList (&CacheEntry->List);
|
||||
} else {
|
||||
//
|
||||
// It's a new entry, allocate memory for the entry.
|
||||
//
|
||||
CacheEntry = ArpAllocCacheEntry (Instance);
|
||||
|
||||
if (CacheEntry == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpAdd: Failed to allocate pool for CacheEntry.\n"));
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Overwrite these parameters.
|
||||
//
|
||||
CacheEntry->DefaultDecayTime = TimeoutValue;
|
||||
CacheEntry->DecayTime = TimeoutValue;
|
||||
|
||||
//
|
||||
// Fill in the addresses.
|
||||
//
|
||||
ArpFillAddressInCacheEntry (
|
||||
CacheEntry,
|
||||
&MatchAddress[Hardware],
|
||||
&MatchAddress[Protocol]
|
||||
);
|
||||
|
||||
//
|
||||
// Inform the user if there is any.
|
||||
//
|
||||
ArpAddressResolved (CacheEntry, NULL, NULL);
|
||||
|
||||
//
|
||||
// Add this CacheEntry to the corresponding CacheTable.
|
||||
//
|
||||
if (DenyFlag) {
|
||||
InsertHeadList (&ArpService->DeniedCacheTable, &CacheEntry->List);
|
||||
} else {
|
||||
InsertHeadList (&ArpService->ResolvedCacheTable, &CacheEntry->List);
|
||||
}
|
||||
|
||||
UNLOCK_EXIT:
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function searches the ARP cache for matching entries and allocates a buffer into
|
||||
which those entries are copied.
|
||||
|
||||
The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which
|
||||
are protocol address pairs and hardware address pairs.
|
||||
When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer
|
||||
is not NULL), the ARP cache timeout for the found entry is reset if Refresh is
|
||||
set to TRUE. If the found ARP cache entry is a permanent entry, it is not
|
||||
affected by Refresh.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to look for matching software protocol
|
||||
addresses. Set to FALSE to look for matching
|
||||
hardware protocol addresses.
|
||||
@param AddressBuffer Pointer to address buffer. Set to NULL to match
|
||||
all addresses.
|
||||
@param EntryLength The size of an entry in the entries buffer.
|
||||
@param EntryCount The number of ARP cache entries that are found by
|
||||
the specified criteria.
|
||||
@param Entries Pointer to the buffer that will receive the ARP
|
||||
cache entries.
|
||||
@param Refresh Set to TRUE to refresh the timeout value of the
|
||||
matching ARP cache entry.
|
||||
|
||||
@retval EFI_SUCCESS The requested ARP cache entries were copied into
|
||||
the buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. Both EntryCount and EntryLength are
|
||||
NULL, when Refresh is FALSE.
|
||||
@retval EFI_NOT_FOUND No matching entries were found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFind (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL,
|
||||
OUT UINT32 *EntryLength OPTIONAL,
|
||||
OUT UINT32 *EntryCount OPTIONAL,
|
||||
OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
|
||||
IN BOOLEAN Refresh
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) ||
|
||||
(!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) ||
|
||||
((Entries != NULL) && ((EntryLength == NULL) || (EntryCount == NULL)))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// All the check passed, find the cache entries now.
|
||||
//
|
||||
Status = ArpFindCacheEntry (
|
||||
Instance,
|
||||
BySwAddress,
|
||||
AddressBuffer,
|
||||
EntryLength,
|
||||
EntryCount,
|
||||
Entries,
|
||||
Refresh
|
||||
);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function removes specified ARP cache entries.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to delete matching protocol addresses.
|
||||
Set to FALSE to delete matching hardware
|
||||
addresses.
|
||||
@param AddressBuffer Pointer to the address buffer that is used as a
|
||||
key to look for the cache entry. Set to NULL to
|
||||
delete all entries.
|
||||
|
||||
@retval EFI_SUCCESS The entry was removed from the ARP cache.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND The specified deletion key was not found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDelete (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
UINTN Count;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Delete the specified cache entries.
|
||||
//
|
||||
Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function delete all dynamic entries from the ARP cache that match the specified
|
||||
software protocol type.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS The cache has been flushed.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND There are no matching dynamic cache entries.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFlush (
|
||||
IN EFI_ARP_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
UINTN Count;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Delete the dynamic entries from the cache table.
|
||||
//
|
||||
Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function tries to resolve the TargetSwAddress and optionally returns a
|
||||
TargetHwAddress if it already exists in the ARP cache.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address to resolve.
|
||||
@param ResolvedEvent Pointer to the event that will be signaled when
|
||||
the address is resolved or some error occurs.
|
||||
@param TargetHwAddress Pointer to the buffer for the resolved hardware
|
||||
address in network byte order.
|
||||
|
||||
@retval EFI_SUCCESS The data is copied from the ARP cache into the
|
||||
TargetHwAddress buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetHwAddress is NULL.
|
||||
@retval EFI_ACCESS_DENIED The requested address is not present in the normal
|
||||
ARP cache but is present in the deny address list.
|
||||
Outgoing traffic to that address is forbidden.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_READY The request has been started and is not finished.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpRequest (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL,
|
||||
OUT VOID *TargetHwAddress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpMode;
|
||||
ARP_CACHE_ENTRY *CacheEntry;
|
||||
NET_ARP_ADDRESS HardwareAddress;
|
||||
NET_ARP_ADDRESS ProtocolAddress;
|
||||
USER_REQUEST_CONTEXT *RequestContext;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (TargetHwAddress == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
ArpService = Instance->ArpService;
|
||||
SnpMode = &ArpService->SnpMode;
|
||||
|
||||
if ((TargetSwAddress == NULL) ||
|
||||
((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
|
||||
IP4_IS_LOCAL_BROADCAST (*((UINT32 *)TargetSwAddress)))) {
|
||||
//
|
||||
// Return the hardware broadcast address.
|
||||
//
|
||||
CopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);
|
||||
|
||||
goto SIGNAL_USER;
|
||||
}
|
||||
|
||||
if ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
|
||||
IP4_IS_MULTICAST (NTOHL (*((UINT32 *)TargetSwAddress)))) {
|
||||
//
|
||||
// If the software address is an IPv4 multicast address, invoke Mnp to
|
||||
// resolve the address.
|
||||
//
|
||||
Status = ArpService->Mnp->McastIpToMac (
|
||||
ArpService->Mnp,
|
||||
FALSE,
|
||||
TargetSwAddress,
|
||||
TargetHwAddress
|
||||
);
|
||||
goto SIGNAL_USER;
|
||||
}
|
||||
|
||||
HardwareAddress.Type = SnpMode->IfType;
|
||||
HardwareAddress.Length = (UINT8)SnpMode->HwAddressSize;
|
||||
HardwareAddress.AddressPtr = NULL;
|
||||
|
||||
ProtocolAddress.Type = Instance->ConfigData.SwAddressType;
|
||||
ProtocolAddress.Length = Instance->ConfigData.SwAddressLength;
|
||||
ProtocolAddress.AddressPtr = TargetSwAddress;
|
||||
|
||||
//
|
||||
// Initialize the TargetHwAddrss to a zero address.
|
||||
//
|
||||
ZeroMem (TargetHwAddress, SnpMode->HwAddressSize);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Check whether the software address is in the denied table.
|
||||
//
|
||||
CacheEntry = ArpFindDeniedCacheEntry (ArpService, &ProtocolAddress, NULL);
|
||||
if (CacheEntry != NULL) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether the software address is already resolved.
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->ResolvedCacheTable,
|
||||
NULL,
|
||||
ByProtoAddress,
|
||||
&ProtocolAddress,
|
||||
NULL
|
||||
);
|
||||
if (CacheEntry != NULL) {
|
||||
//
|
||||
// Resolved, copy the address into the user buffer.
|
||||
//
|
||||
CopyMem (
|
||||
TargetHwAddress,
|
||||
CacheEntry->Addresses[Hardware].AddressPtr,
|
||||
CacheEntry->Addresses[Hardware].Length
|
||||
);
|
||||
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
if (ResolvedEvent == NULL) {
|
||||
Status = EFI_NOT_READY;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a request context for this arp request.
|
||||
//
|
||||
RequestContext = AllocatePool (sizeof(USER_REQUEST_CONTEXT));
|
||||
if (RequestContext == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for RequestContext failed.\n"));
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
RequestContext->Instance = Instance;
|
||||
RequestContext->UserRequestEvent = ResolvedEvent;
|
||||
RequestContext->UserHwAddrBuffer = TargetHwAddress;
|
||||
InitializeListHead (&RequestContext->List);
|
||||
|
||||
//
|
||||
// Check whether there is a same request.
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->PendingRequestTable,
|
||||
NULL,
|
||||
ByProtoAddress,
|
||||
&ProtocolAddress,
|
||||
NULL
|
||||
);
|
||||
if (CacheEntry != NULL) {
|
||||
|
||||
CacheEntry->NextRetryTime = Instance->ConfigData.RetryTimeOut;
|
||||
CacheEntry->RetryCount = Instance->ConfigData.RetryCount;
|
||||
} else {
|
||||
//
|
||||
// Allocate a cache entry for this request.
|
||||
//
|
||||
CacheEntry = ArpAllocCacheEntry (Instance);
|
||||
if (CacheEntry == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for CacheEntry failed.\n"));
|
||||
FreePool (RequestContext);
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill the software address.
|
||||
//
|
||||
ArpFillAddressInCacheEntry (CacheEntry, &HardwareAddress, &ProtocolAddress);
|
||||
|
||||
//
|
||||
// Add this entry into the PendingRequestTable.
|
||||
//
|
||||
InsertTailList (&ArpService->PendingRequestTable, &CacheEntry->List);
|
||||
}
|
||||
|
||||
//
|
||||
// Link this request context into the cache entry.
|
||||
//
|
||||
InsertHeadList (&CacheEntry->UserRequestList, &RequestContext->List);
|
||||
|
||||
//
|
||||
// Send out the ARP Request frame.
|
||||
//
|
||||
ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST);
|
||||
Status = EFI_NOT_READY;
|
||||
|
||||
UNLOCK_EXIT:
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
SIGNAL_USER:
|
||||
|
||||
if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) {
|
||||
gBS->SignalEvent (ResolvedEvent);
|
||||
|
||||
//
|
||||
// Dispatch the DPC queued by the NotifyFunction of ResolvedEvent.
|
||||
//
|
||||
DispatchDpc ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function aborts the previous ARP request (identified by This, TargetSwAddress
|
||||
and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
If the request is in the internal ARP request queue, the request is aborted
|
||||
immediately and its ResolvedEvent is signaled. Only an asynchronous address
|
||||
request needs to be canceled. If TargeSwAddress and ResolveEvent are both
|
||||
NULL, all the pending asynchronous requests that have been issued by This
|
||||
instance will be cancelled and their corresponding events will be signaled.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address in previous
|
||||
request session.
|
||||
@param ResolvedEvent Pointer to the event that is used as the
|
||||
notification event in previous request session.
|
||||
|
||||
@retval EFI_SUCCESS The pending request session(s) is/are aborted and
|
||||
corresponding event(s) is/are signaled.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetSwAddress is not NULL and
|
||||
ResolvedEvent is NULL. TargetSwAddress is NULL and
|
||||
ResolvedEvent is not NULL.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_FOUND The request is not issued by
|
||||
EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpCancel (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
UINTN Count;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) ||
|
||||
((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) ||
|
||||
((TargetSwAddress == NULL) && (ResolvedEvent != NULL))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Cancel the specified request.
|
||||
//
|
||||
Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent);
|
||||
|
||||
//
|
||||
// Dispatch the DPCs queued by the NotifyFunction of the events signaled
|
||||
// by ArpCancleRequest.
|
||||
//
|
||||
DispatchDpc ();
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
/** @file
|
||||
UEFI Component Name(2) protocol implementation for ArpDxe driver.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "ArpDriver.h"
|
||||
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gArpComponentName = {
|
||||
ArpComponentNameGetDriverName,
|
||||
ArpComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
//
|
||||
// EFI Component Name 2 Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gArpComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) ArpComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) ArpComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpDriverNameTable[] = {
|
||||
{ "eng;en", L"ARP Network Service Driver" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpControllerNameTable[] = {
|
||||
{ "eng;en", L"ARP Controller" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the driver.
|
||||
|
||||
This function retrieves the user readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mArpDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This == &gArpComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that wish to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ARP_PROTOCOL *Arp;
|
||||
|
||||
//
|
||||
// Only provide names for child handles.
|
||||
//
|
||||
if (ChildHandle == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure this driver produced ChildHandle
|
||||
//
|
||||
Status = EfiTestChildHandle (
|
||||
ControllerHandle,
|
||||
ChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve an instance of a produced protocol from ChildHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
(VOID **)&Arp,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mArpControllerNameTable,
|
||||
ControllerName,
|
||||
(BOOLEAN)(This == &gArpComponentName)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,431 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Dhcp4Impl.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the driver.
|
||||
|
||||
This function retrieves the user readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DhcpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that wish to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DhcpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gDhcp4ComponentName = {
|
||||
DhcpComponentNameGetDriverName,
|
||||
DhcpComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
//
|
||||
// EFI Component Name 2 Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gDhcp4ComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) DhcpComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) DhcpComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcpDriverNameTable[] = {
|
||||
{
|
||||
"eng;en",
|
||||
L"DHCP Protocol Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDhcpControllerNameTable = NULL;
|
||||
|
||||
CHAR16 *mDhcp4ControllerName[] = {
|
||||
L"DHCPv4 (State=0, Stopped)",
|
||||
L"DHCPv4 (State=1, Init)",
|
||||
L"DHCPv4 (State=2, Selecting)",
|
||||
L"DHCPv4 (State=3, Requesting)",
|
||||
L"DHCPv4 (State=4, Bound)",
|
||||
L"DHCPv4 (State=5, Renewing)",
|
||||
L"DHCPv4 (State=6, Rebinding)",
|
||||
L"DHCPv4 (State=7, InitReboot)",
|
||||
L"DHCPv4 (State=8, Rebooting)"
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the driver.
|
||||
|
||||
This function retrieves the user readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DhcpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mDhcpDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This == &gDhcp4ComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Update the component name for the Dhcp4 child handle.
|
||||
|
||||
@param Dhcp4[in] A pointer to the EFI_DHCP4_PROTOCOL.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
|
||||
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
|
||||
@retval EFI_DEVICE_ERROR DHCP is in unknown state.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateName (
|
||||
IN EFI_DHCP4_PROTOCOL *Dhcp4
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DHCP4_MODE_DATA Dhcp4ModeData;
|
||||
|
||||
if (Dhcp4 == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Format the child name into the string buffer.
|
||||
//
|
||||
Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4ModeData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (gDhcpControllerNameTable != NULL) {
|
||||
FreeUnicodeStringTable (gDhcpControllerNameTable);
|
||||
gDhcpControllerNameTable = NULL;
|
||||
}
|
||||
|
||||
if (Dhcp4ModeData.State > Dhcp4Rebooting) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Status = AddUnicodeString2 (
|
||||
"eng",
|
||||
gDhcp4ComponentName.SupportedLanguages,
|
||||
&gDhcpControllerNameTable,
|
||||
mDhcp4ControllerName[Dhcp4ModeData.State],
|
||||
TRUE
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return AddUnicodeString2 (
|
||||
"en",
|
||||
gDhcp4ComponentName2.SupportedLanguages,
|
||||
&gDhcpControllerNameTable,
|
||||
mDhcp4ControllerName[Dhcp4ModeData.State],
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that wish to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DhcpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DHCP4_PROTOCOL *Dhcp4;
|
||||
|
||||
//
|
||||
// Only provide names for child handles.
|
||||
//
|
||||
if (ChildHandle == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure this driver produced ChildHandle
|
||||
//
|
||||
Status = EfiTestChildHandle (
|
||||
ControllerHandle,
|
||||
ChildHandle,
|
||||
&gEfiUdp4ProtocolGuid
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve an instance of a produced protocol from ChildHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
(VOID **)&Dhcp4,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the component name for this child handle.
|
||||
//
|
||||
Status = UpdateName (Dhcp4);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
gDhcpControllerNameTable,
|
||||
ControllerName,
|
||||
(BOOLEAN)(This == &gDhcp4ComponentName)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,732 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "Dhcp4Impl.h"
|
||||
#include "Dhcp4Driver.h"
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gDhcp4DriverBinding = {
|
||||
Dhcp4DriverBindingSupported,
|
||||
Dhcp4DriverBindingStart,
|
||||
Dhcp4DriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_SERVICE_BINDING_PROTOCOL mDhcp4ServiceBindingTemplate = {
|
||||
Dhcp4ServiceBindingCreateChild,
|
||||
Dhcp4ServiceBindingDestroyChild
|
||||
};
|
||||
|
||||
/**
|
||||
This is the declaration of an EFI image entry point. This entry point is
|
||||
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
|
||||
both device drivers and bus drivers.
|
||||
|
||||
Entry point of the DHCP driver to install various protocols.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the UEFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
return EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gDhcp4DriverBinding,
|
||||
ImageHandle,
|
||||
&gDhcp4ComponentName,
|
||||
&gDhcp4ComponentName2
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle. This service
|
||||
is called by the EFI boot service ConnectController(). In
|
||||
order to make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. ConnectController() must
|
||||
follow these calling restrictions. If any other agent wishes to call
|
||||
Supported() it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to test
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCESS This driver supports this device
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on this device
|
||||
@retval other This driver does not support this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUdp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Configure the default UDP child to receive all the DHCP traffics
|
||||
on this network interface.
|
||||
|
||||
@param[in] UdpIo The UDP IO to configure
|
||||
@param[in] Context The context to the function
|
||||
|
||||
@retval EFI_SUCCESS The UDP IO is successfully configured.
|
||||
@retval Others Failed to configure the UDP child.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DhcpConfigUdpIo (
|
||||
IN UDP_IO *UdpIo,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_UDP4_CONFIG_DATA UdpConfigData;
|
||||
|
||||
UdpConfigData.AcceptBroadcast = TRUE;
|
||||
UdpConfigData.AcceptPromiscuous = FALSE;
|
||||
UdpConfigData.AcceptAnyPort = FALSE;
|
||||
UdpConfigData.AllowDuplicatePort = TRUE;
|
||||
UdpConfigData.TypeOfService = 0;
|
||||
UdpConfigData.TimeToLive = 64;
|
||||
UdpConfigData.DoNotFragment = FALSE;
|
||||
UdpConfigData.ReceiveTimeout = 0;
|
||||
UdpConfigData.TransmitTimeout = 0;
|
||||
|
||||
UdpConfigData.UseDefaultAddress = FALSE;
|
||||
UdpConfigData.StationPort = DHCP_CLIENT_PORT;
|
||||
UdpConfigData.RemotePort = DHCP_SERVER_PORT;
|
||||
|
||||
ZeroMem (&UdpConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
ZeroMem (&UdpConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
|
||||
ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
return UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData);;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Destroy the DHCP service. The Dhcp4 service may be partly initialized,
|
||||
or partly destroyed. If a resource is destroyed, it is marked as so in
|
||||
case the destroy failed and being called again later.
|
||||
|
||||
@param[in] DhcpSb The DHCP service instance to destroy.
|
||||
|
||||
@retval EFI_SUCCESS Always return success.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp4CloseService (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
)
|
||||
{
|
||||
DhcpCleanLease (DhcpSb);
|
||||
|
||||
if (DhcpSb->UdpIo != NULL) {
|
||||
UdpIoFreeIo (DhcpSb->UdpIo);
|
||||
DhcpSb->UdpIo = NULL;
|
||||
}
|
||||
|
||||
if (DhcpSb->Timer != NULL) {
|
||||
gBS->SetTimer (DhcpSb->Timer, TimerCancel, 0);
|
||||
gBS->CloseEvent (DhcpSb->Timer);
|
||||
|
||||
DhcpSb->Timer = NULL;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Create a new DHCP service binding instance for the controller.
|
||||
|
||||
@param[in] Controller The controller to install DHCP service binding
|
||||
protocol onto
|
||||
@param[in] ImageHandle The driver's image handle
|
||||
@param[out] Service The variable to receive the created DHCP service
|
||||
instance.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource .
|
||||
@retval EFI_SUCCESS The DHCP service instance is created.
|
||||
@retval other Other error occurs.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp4CreateService (
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT DHCP_SERVICE **Service
|
||||
)
|
||||
{
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_STATUS Status;
|
||||
|
||||
*Service = NULL;
|
||||
DhcpSb = AllocateZeroPool (sizeof (DHCP_SERVICE));
|
||||
|
||||
if (DhcpSb == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
DhcpSb->Signature = DHCP_SERVICE_SIGNATURE;
|
||||
DhcpSb->ServiceState = DHCP_UNCONFIGED;
|
||||
DhcpSb->Controller = Controller;
|
||||
DhcpSb->Image = ImageHandle;
|
||||
InitializeListHead (&DhcpSb->Children);
|
||||
DhcpSb->DhcpState = Dhcp4Stopped;
|
||||
DhcpSb->Xid = NET_RANDOM (NetRandomInitSeed ());
|
||||
CopyMem (
|
||||
&DhcpSb->ServiceBinding,
|
||||
&mDhcp4ServiceBindingTemplate,
|
||||
sizeof (EFI_SERVICE_BINDING_PROTOCOL)
|
||||
);
|
||||
//
|
||||
// Create various resources, UdpIo, Timer, and get Mac address
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL | EVT_TIMER,
|
||||
TPL_CALLBACK,
|
||||
DhcpOnTimerTick,
|
||||
DhcpSb,
|
||||
&DhcpSb->Timer
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
DhcpSb->UdpIo = UdpIoCreateIo (
|
||||
Controller,
|
||||
ImageHandle,
|
||||
DhcpConfigUdpIo,
|
||||
UDP_IO_UDP4_VERSION,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (DhcpSb->UdpIo == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
DhcpSb->HwLen = (UINT8) DhcpSb->UdpIo->SnpMode.HwAddressSize;
|
||||
DhcpSb->HwType = DhcpSb->UdpIo->SnpMode.IfType;
|
||||
CopyMem (&DhcpSb->Mac, &DhcpSb->UdpIo->SnpMode.CurrentAddress, sizeof (DhcpSb->Mac));
|
||||
|
||||
*Service = DhcpSb;
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
Dhcp4CloseService (DhcpSb);
|
||||
FreePool (DhcpSb);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service ConnectController(). In order to make
|
||||
drivers as small as possible, there are a few calling restrictions for
|
||||
this service. ConnectController() must follow these
|
||||
calling restrictions. If any other agent wishes to call Start() it
|
||||
must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to bind driver to
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCESS This driver is added to ControllerHandle
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
|
||||
@retval other This driver does not support this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// First: test for the DHCP4 Protocol
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
if (Status == EFI_SUCCESS) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
Status = Dhcp4CreateService (ControllerHandle, This->DriverBindingHandle, &DhcpSb);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
ASSERT (DhcpSb != NULL);
|
||||
|
||||
//
|
||||
// Start the receiving
|
||||
//
|
||||
Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
Status = gBS->SetTimer (DhcpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the Dhcp4ServiceBinding Protocol onto ControlerHandle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||
&DhcpSb->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
ON_ERROR:
|
||||
Dhcp4CloseService (DhcpSb);
|
||||
FreePool (DhcpSb);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Callback function which provided by user to remove one node in NetDestroyLinkList process.
|
||||
|
||||
@param[in] Entry The entry to be removed.
|
||||
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been removed successfully.
|
||||
@retval Others Fail to remove the entry.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DestroyChildEntry (
|
||||
IN LIST_ENTRY *Entry,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
DHCP_PROTOCOL *Instance;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
|
||||
if (Entry == NULL || Context == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP_PROTOCOL, Link, DHCP_PROTOCOL_SIGNATURE);
|
||||
ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
|
||||
|
||||
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service DisconnectController(). In order to
|
||||
make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. DisconnectController()
|
||||
must follow these calling restrictions. If any other agent wishes
|
||||
to call Stop() it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to stop driver on
|
||||
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
|
||||
children is zero stop the entire bus driver.
|
||||
@param[in] ChildHandleBuffer List of Child Handles to Stop.
|
||||
|
||||
@retval EFI_SUCCESS This driver is removed ControllerHandle
|
||||
@retval other This driver was not removed from this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_STATUS Status;
|
||||
LIST_ENTRY *List;
|
||||
UINTN ListLength;
|
||||
|
||||
//
|
||||
// DHCP driver opens UDP child, So, the ControllerHandle is the
|
||||
// UDP child handle. locate the Nic handle first.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
|
||||
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
NicHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding);
|
||||
if (!IsListEmpty (&DhcpSb->Children)) {
|
||||
//
|
||||
// Destroy all the children instances before destory the service.
|
||||
//
|
||||
List = &DhcpSb->Children;
|
||||
Status = NetDestroyLinkList (
|
||||
List,
|
||||
Dhcp4DestroyChildEntry,
|
||||
ServiceBinding,
|
||||
&ListLength
|
||||
);
|
||||
if (EFI_ERROR (Status) || ListLength != 0) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (NumberOfChildren == 0 && !IsListEmpty (&DhcpSb->Children)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (NumberOfChildren == 0 && IsListEmpty (&DhcpSb->Children)) {
|
||||
//
|
||||
// Destroy the service itself if no child instance left.
|
||||
//
|
||||
DhcpSb->ServiceState = DHCP_DESTROY;
|
||||
|
||||
gBS->UninstallProtocolInterface (
|
||||
NicHandle,
|
||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||
ServiceBinding
|
||||
);
|
||||
|
||||
Dhcp4CloseService (DhcpSb);
|
||||
|
||||
if (gDhcpControllerNameTable != NULL) {
|
||||
FreeUnicodeStringTable (gDhcpControllerNameTable);
|
||||
gDhcpControllerNameTable = NULL;
|
||||
}
|
||||
FreePool (DhcpSb);
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize a new DHCP instance.
|
||||
|
||||
@param DhcpSb The dhcp service instance
|
||||
@param Instance The dhcp instance to initialize
|
||||
|
||||
**/
|
||||
VOID
|
||||
DhcpInitProtocol (
|
||||
IN DHCP_SERVICE *DhcpSb,
|
||||
IN OUT DHCP_PROTOCOL *Instance
|
||||
)
|
||||
{
|
||||
Instance->Signature = DHCP_PROTOCOL_SIGNATURE;
|
||||
CopyMem (&Instance->Dhcp4Protocol, &mDhcp4ProtocolTemplate, sizeof (Instance->Dhcp4Protocol));
|
||||
InitializeListHead (&Instance->Link);
|
||||
Instance->Handle = NULL;
|
||||
Instance->Service = DhcpSb;
|
||||
Instance->InDestroy = FALSE;
|
||||
Instance->CompletionEvent = NULL;
|
||||
Instance->RenewRebindEvent = NULL;
|
||||
Instance->Token = NULL;
|
||||
Instance->UdpIo = NULL;
|
||||
Instance->ElaspedTime = 0;
|
||||
NetbufQueInit (&Instance->ResponseQueue);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||
then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
DHCP_PROTOCOL *Instance;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
VOID *Udp4;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = AllocatePool (sizeof (*Instance));
|
||||
|
||||
if (Instance == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
DhcpSb = DHCP_SERVICE_FROM_THIS (This);
|
||||
DhcpInitProtocol (DhcpSb, Instance);
|
||||
|
||||
//
|
||||
// Install DHCP4 onto ChildHandle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
&Instance->Dhcp4Protocol,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (Instance);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Instance->Handle = *ChildHandle;
|
||||
|
||||
//
|
||||
// Open the Udp4 protocol BY_CHILD.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
DhcpSb->UdpIo->UdpHandle,
|
||||
&gEfiUdp4ProtocolGuid,
|
||||
(VOID **) &Udp4,
|
||||
gDhcp4DriverBinding.DriverBindingHandle,
|
||||
Instance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
Instance->Handle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
&Instance->Dhcp4Protocol,
|
||||
NULL
|
||||
);
|
||||
|
||||
FreePool (Instance);
|
||||
return Status;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
InsertTailList (&DhcpSb->Children, &Instance->Link);
|
||||
DhcpSb->NumChildren++;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
DHCP_PROTOCOL *Instance;
|
||||
EFI_DHCP4_PROTOCOL *Dhcp;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the private context data structures
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
(VOID **) &Dhcp,
|
||||
gDhcp4DriverBinding.DriverBindingHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Instance = DHCP_INSTANCE_FROM_THIS (Dhcp);
|
||||
DhcpSb = DHCP_SERVICE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Service != DhcpSb) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// A child can be destroyed more than once. For example,
|
||||
// Dhcp4DriverBindingStop will destroy all of its children.
|
||||
// when caller driver is being stopped, it will destroy the
|
||||
// dhcp child it opens.
|
||||
//
|
||||
if (Instance->InDestroy) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
Instance->InDestroy = TRUE;
|
||||
|
||||
//
|
||||
// Close the Udp4 protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
DhcpSb->UdpIo->UdpHandle,
|
||||
&gEfiUdp4ProtocolGuid,
|
||||
gDhcp4DriverBinding.DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
//
|
||||
// Uninstall the DHCP4 protocol first to enable a top down destruction.
|
||||
//
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
ChildHandle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
Dhcp
|
||||
);
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Instance->InDestroy = FALSE;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (DhcpSb->ActiveChild == Instance) {
|
||||
DhcpYieldControl (DhcpSb);
|
||||
}
|
||||
|
||||
RemoveEntryList (&Instance->Link);
|
||||
DhcpSb->NumChildren--;
|
||||
|
||||
if (Instance->UdpIo != NULL) {
|
||||
UdpIoCleanIo (Instance->UdpIo);
|
||||
gBS->CloseProtocol (
|
||||
Instance->UdpIo->UdpHandle,
|
||||
&gEfiUdp4ProtocolGuid,
|
||||
Instance->Service->Image,
|
||||
Instance->Handle
|
||||
);
|
||||
UdpIoFreeIo (Instance->UdpIo);
|
||||
Instance->UdpIo = NULL;
|
||||
Instance->Token = NULL;
|
||||
}
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
FreePool (Instance);
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/** @file
|
||||
Header for the DHCP4 driver.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_DRIVER_H__
|
||||
#define __EFI_DHCP4_DRIVER_H__
|
||||
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gDhcp4ComponentName;
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp4ComponentName2;
|
||||
extern EFI_UNICODE_STRING_TABLE *gDhcpControllerNameTable;
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle. This service
|
||||
is called by the EFI boot service ConnectController(). In
|
||||
order to make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. ConnectController() must
|
||||
follow these calling restrictions. If any other agent wishes to call
|
||||
Supported() it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to test
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCESS This driver supports this device
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on this device
|
||||
@retval other This driver does not support this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service ConnectController(). In order to make
|
||||
drivers as small as possible, there are a few calling restrictions for
|
||||
this service. ConnectController() must follow these
|
||||
calling restrictions. If any other agent wishes to call Start() it
|
||||
must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to bind driver to
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCESS This driver is added to ControllerHandle
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
|
||||
@retval other This driver does not support this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service DisconnectController(). In order to
|
||||
make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. DisconnectController()
|
||||
must follow these calling restrictions. If any other agent wishes
|
||||
to call Stop() it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to stop driver on
|
||||
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
|
||||
children is zero stop the entire bus driver.
|
||||
@param[in] ChildHandleBuffer List of Child Handles to Stop.
|
||||
|
||||
@retval EFI_SUCCESS This driver is removed ControllerHandle
|
||||
@retval other This driver was not removed from this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||
then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
## @file
|
||||
# This module produces EFI DHCPv4 Protocol and EFI DHCPv4 Service Binding Protocol.
|
||||
#
|
||||
# This module produces EFI DHCPv4 Protocol upon EFI UDPv4 Protocol, to provide the
|
||||
# capability to collect configuration information for the EFI IPv4 Protocol drivers
|
||||
# and to provide DHCPv4 server and PXE boot server discovery services.
|
||||
#
|
||||
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Dhcp4Dxe
|
||||
MODULE_UNI_FILE = Dhcp4Dxe.uni
|
||||
FILE_GUID = 94734718-0BBC-47fb-96A5-EE7A5AE6A2AD
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = Dhcp4DriverEntryPoint
|
||||
UNLOAD_IMAGE = NetLibDefaultUnload
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 EBC
|
||||
#
|
||||
# DRIVER_BINDING = gDhcp4DriverBinding
|
||||
# COMPONENT_NAME = gDhcp4ComponentName
|
||||
# COMPONENT_NAME2 = gDhcp4ComponentName2
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Dhcp4Impl.c
|
||||
Dhcp4Io.c
|
||||
Dhcp4Io.h
|
||||
ComponentName.c
|
||||
Dhcp4Driver.h
|
||||
Dhcp4Driver.c
|
||||
Dhcp4Option.c
|
||||
Dhcp4Option.h
|
||||
Dhcp4Impl.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
NetworkPkg/NetworkPkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
DebugLib
|
||||
NetLib
|
||||
UdpIoLib
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiDhcp4ServiceBindingProtocolGuid ## BY_START
|
||||
gEfiUdp4ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiDhcp4ProtocolGuid ## BY_START
|
||||
gEfiUdp4ProtocolGuid ## TO_START
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
Dhcp4DxeExtra.uni
|
|
@ -0,0 +1,18 @@
|
|||
// /** @file
|
||||
// This module produces EFI DHCPv4 Protocol and EFI DHCPv4 Service Binding Protocol.
|
||||
//
|
||||
// This module produces EFI DHCPv4 Protocol upon EFI UDPv4 Protocol, to provide the
|
||||
// capability to collect configuration information for the EFI IPv4 Protocol drivers
|
||||
// and to provide DHCPv4 server and PXE boot server discovery services.
|
||||
//
|
||||
// Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "EFI DHCPv4 Driver"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI DHCPv4 Protocol using the EFI UDPv4 Protocol, providing the capability to collect configuration information for the EFI IPv4 Protocol drivers and providing DHCPv4 server and PXE boot server discovery services."
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// /** @file
|
||||
// Dhcp4Dxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"DHCP v4 DXE Driver"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,206 @@
|
|||
/** @file
|
||||
EFI DHCP protocol implementation.
|
||||
RFCs supported are:
|
||||
RFC 2131: Dynamic Host Configuration Protocol
|
||||
RFC 2132: DHCP Options and BOOTP Vendor Extensions
|
||||
RFC 1534: Interoperation Between DHCP and BOOTP
|
||||
RFC 3396: Encoding Long Options in DHCP.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_IMPL_H__
|
||||
#define __EFI_DHCP4_IMPL_H__
|
||||
|
||||
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/Dhcp4.h>
|
||||
#include <Protocol/Udp4.h>
|
||||
#include <IndustryStandard/Dhcp.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
|
||||
typedef struct _DHCP_SERVICE DHCP_SERVICE;
|
||||
typedef struct _DHCP_PROTOCOL DHCP_PROTOCOL;
|
||||
|
||||
#include "Dhcp4Option.h"
|
||||
#include "Dhcp4Io.h"
|
||||
|
||||
#define DHCP_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', 'C', 'P')
|
||||
#define DHCP_PROTOCOL_SIGNATURE SIGNATURE_32 ('d', 'h', 'c', 'p')
|
||||
|
||||
#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)
|
||||
|
||||
//
|
||||
// The state of the DHCP service. It starts as UNCONFIGED. If
|
||||
// and active child configures the service successfully, it
|
||||
// goes to CONFIGED. If the active child configures NULL, it
|
||||
// goes back to UNCONFIGED. It becomes DESTROY if it is (partly)
|
||||
// destroyed.
|
||||
//
|
||||
#define DHCP_UNCONFIGED 0
|
||||
#define DHCP_CONFIGED 1
|
||||
#define DHCP_DESTROY 2
|
||||
|
||||
|
||||
struct _DHCP_PROTOCOL {
|
||||
UINT32 Signature;
|
||||
EFI_DHCP4_PROTOCOL Dhcp4Protocol;
|
||||
LIST_ENTRY Link;
|
||||
EFI_HANDLE Handle;
|
||||
DHCP_SERVICE *Service;
|
||||
|
||||
BOOLEAN InDestroy;
|
||||
|
||||
EFI_EVENT CompletionEvent;
|
||||
EFI_EVENT RenewRebindEvent;
|
||||
|
||||
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
|
||||
UDP_IO *UdpIo; // The UDP IO used for TransmitReceive.
|
||||
UINT32 Timeout;
|
||||
UINT16 ElaspedTime;
|
||||
NET_BUF_QUEUE ResponseQueue;
|
||||
};
|
||||
|
||||
//
|
||||
// DHCP driver is specical in that it is a singleton. Although it
|
||||
// has a service binding, there can be only one active child.
|
||||
//
|
||||
struct _DHCP_SERVICE {
|
||||
UINT32 Signature;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
|
||||
INTN ServiceState; // CONFIGED, UNCONFIGED, and DESTROY
|
||||
|
||||
EFI_HANDLE Controller;
|
||||
EFI_HANDLE Image;
|
||||
|
||||
LIST_ENTRY Children;
|
||||
UINTN NumChildren;
|
||||
|
||||
INTN DhcpState;
|
||||
EFI_STATUS IoStatus; // the result of last user operation
|
||||
UINT32 Xid;
|
||||
|
||||
IP4_ADDR ClientAddr; // lease IP or configured client address
|
||||
IP4_ADDR Netmask;
|
||||
IP4_ADDR ServerAddr;
|
||||
|
||||
EFI_DHCP4_PACKET *LastOffer; // The last received offer
|
||||
EFI_DHCP4_PACKET *Selected;
|
||||
DHCP_PARAMETER *Para;
|
||||
|
||||
UINT32 Lease;
|
||||
UINT32 T1;
|
||||
UINT32 T2;
|
||||
INTN ExtraRefresh; // This refresh is reqested by user
|
||||
|
||||
UDP_IO *UdpIo; // Udp child receiving all DHCP message
|
||||
UDP_IO *LeaseIoPort; // Udp child with lease IP
|
||||
EFI_DHCP4_PACKET *LastPacket; // The last sent packet for retransmission
|
||||
EFI_MAC_ADDRESS Mac;
|
||||
UINT8 HwType;
|
||||
UINT8 HwLen;
|
||||
UINT8 ClientAddressSendOut[16];
|
||||
|
||||
DHCP_PROTOCOL *ActiveChild;
|
||||
EFI_DHCP4_CONFIG_DATA ActiveConfig;
|
||||
UINT32 UserOptionLen;
|
||||
|
||||
//
|
||||
// Timer event and various timer
|
||||
//
|
||||
EFI_EVENT Timer;
|
||||
|
||||
UINT32 PacketToLive; // Retransmission timer for our packets
|
||||
UINT32 LastTimeout; // Record the init value of PacketToLive every time
|
||||
INTN CurRetry;
|
||||
INTN MaxRetries;
|
||||
UINT32 LeaseLife;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
EFI_DHCP4_PACKET_OPTION **Option;
|
||||
UINT32 OptionCount;
|
||||
UINT32 Index;
|
||||
} DHCP_PARSE_CONTEXT;
|
||||
|
||||
#define DHCP_INSTANCE_FROM_THIS(Proto) \
|
||||
CR ((Proto), DHCP_PROTOCOL, Dhcp4Protocol, DHCP_PROTOCOL_SIGNATURE)
|
||||
|
||||
#define DHCP_SERVICE_FROM_THIS(Sb) \
|
||||
CR ((Sb), DHCP_SERVICE, ServiceBinding, DHCP_SERVICE_SIGNATURE)
|
||||
|
||||
extern EFI_DHCP4_PROTOCOL mDhcp4ProtocolTemplate;
|
||||
|
||||
/**
|
||||
Give up the control of the DHCP service to let other child
|
||||
resume. Don't change the service's DHCP state and the Client
|
||||
address and option list configure as required by RFC2131.
|
||||
|
||||
@param DhcpSb The DHCP service instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DhcpYieldControl (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
);
|
||||
|
||||
/**
|
||||
Complete a Dhcp4 transaction and signal the upper layer.
|
||||
|
||||
@param Instance Dhcp4 instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
PxeDhcpDone (
|
||||
IN DHCP_PROTOCOL *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Free the resource related to the configure parameters.
|
||||
DHCP driver will make a copy of the user's configure
|
||||
such as the time out value.
|
||||
|
||||
@param Config The DHCP configure data
|
||||
|
||||
**/
|
||||
VOID
|
||||
DhcpCleanConfigure (
|
||||
IN OUT EFI_DHCP4_CONFIG_DATA *Config
|
||||
);
|
||||
|
||||
/**
|
||||
Callback of Dhcp packet. Does nothing.
|
||||
|
||||
@param Arg The context.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DhcpDummyExtFree (
|
||||
IN VOID *Arg
|
||||
);
|
||||
|
||||
/**
|
||||
Set the elapsed time based on the given instance and the pointer to the
|
||||
elapsed time option.
|
||||
|
||||
@param[in] Elapsed The pointer to the position to append.
|
||||
@param[in] Instance The pointer to the Dhcp4 instance.
|
||||
**/
|
||||
VOID
|
||||
SetElapsedTime (
|
||||
IN UINT16 *Elapsed,
|
||||
IN DHCP_PROTOCOL *Instance
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,189 @@
|
|||
/** @file
|
||||
The DHCP4 protocol implementation.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_IO_H__
|
||||
#define __EFI_DHCP4_IO_H__
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/UdpIoLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
|
||||
|
||||
#define DHCP_WAIT_OFFER 3 // Time to wait the offers
|
||||
#define DHCP_DEFAULT_LEASE 7 * 24 * 60 * 60 // Seven days as default.
|
||||
#define DHCP_SERVER_PORT 67
|
||||
#define DHCP_CLIENT_PORT 68
|
||||
|
||||
//
|
||||
// BOOTP header "op" field
|
||||
//
|
||||
#define BOOTP_REQUEST 1
|
||||
#define BOOTP_REPLY 2
|
||||
|
||||
//
|
||||
// DHCP message types
|
||||
//
|
||||
#define DHCP_MSG_DISCOVER 1
|
||||
#define DHCP_MSG_OFFER 2
|
||||
#define DHCP_MSG_REQUEST 3
|
||||
#define DHCP_MSG_DECLINE 4
|
||||
#define DHCP_MSG_ACK 5
|
||||
#define DHCP_MSG_NAK 6
|
||||
#define DHCP_MSG_RELEASE 7
|
||||
#define DHCP_MSG_INFORM 8
|
||||
|
||||
//
|
||||
// DHCP notify user type
|
||||
//
|
||||
#define DHCP_NOTIFY_COMPLETION 1
|
||||
#define DHCP_NOTIFY_RENEWREBIND 2
|
||||
#define DHCP_NOTIFY_ALL 3
|
||||
|
||||
#define DHCP_IS_BOOTP(Parameter) (((Parameter) == NULL) || ((Parameter)->DhcpType == 0))
|
||||
|
||||
#define DHCP_CONNECTED(State) \
|
||||
(((State) == Dhcp4Bound) || ((State) == (Dhcp4Renewing)) || ((State) == Dhcp4Rebinding))
|
||||
|
||||
/**
|
||||
Set the DHCP state. If CallUser is true, it will try to notify
|
||||
the user before change the state by DhcpNotifyUser. It returns
|
||||
EFI_ABORTED if the user return EFI_ABORTED, otherwise, it returns
|
||||
EFI_SUCCESS. If CallUser is FALSE, it isn't necessary to test
|
||||
the return value of this function.
|
||||
|
||||
@param DhcpSb The DHCP service instance
|
||||
@param State The new DHCP state to change to
|
||||
@param CallUser Whether we need to call user
|
||||
|
||||
@retval EFI_SUCCESS The state is changed
|
||||
@retval EFI_ABORTED The user asks to abort the DHCP process.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpSetState (
|
||||
IN OUT DHCP_SERVICE *DhcpSb,
|
||||
IN INTN State,
|
||||
IN BOOLEAN CallUser
|
||||
);
|
||||
|
||||
/**
|
||||
Build and transmit a DHCP message according to the current states.
|
||||
This function implement the Table 5. of RFC 2131. Always transits
|
||||
the state (as defined in Figure 5. of the same RFC) before sending
|
||||
a DHCP message. The table is adjusted accordingly.
|
||||
|
||||
@param[in] DhcpSb The DHCP service instance
|
||||
@param[in] Seed The seed packet which the new packet is based on
|
||||
@param[in] Para The DHCP parameter of the Seed packet
|
||||
@param[in] Type The message type to send
|
||||
@param[in] Msg The human readable message to include in the packet
|
||||
sent.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources for the packet
|
||||
@retval EFI_ACCESS_DENIED Failed to transmit the packet through UDP
|
||||
@retval EFI_SUCCESS The message is sent
|
||||
@retval other Other error occurs
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpSendMessage (
|
||||
IN DHCP_SERVICE *DhcpSb,
|
||||
IN EFI_DHCP4_PACKET *Seed,
|
||||
IN DHCP_PARAMETER *Para,
|
||||
IN UINT8 Type,
|
||||
IN UINT8 *Msg
|
||||
);
|
||||
|
||||
/**
|
||||
Each DHCP service has three timer. Two of them are count down timer.
|
||||
One for the packet retransmission. The other is to collect the offers.
|
||||
The third timer increaments the lease life which is compared to T1, T2,
|
||||
and lease to determine the time to renew and rebind the lease.
|
||||
DhcpOnTimerTick will be called once every second.
|
||||
|
||||
@param[in] Event The timer event
|
||||
@param[in] Context The context, which is the DHCP service instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DhcpOnTimerTick (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Handle the received DHCP packets. This function drives the DHCP
|
||||
state machine.
|
||||
|
||||
@param UdpPacket The UDP packets received.
|
||||
@param EndPoint The local/remote UDP access point
|
||||
@param IoStatus The status of the UDP receive
|
||||
@param Context The opaque parameter to the function.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DhcpInput (
|
||||
NET_BUF *UdpPacket,
|
||||
UDP_END_POINT *EndPoint,
|
||||
EFI_STATUS IoStatus,
|
||||
VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Send an initial DISCOVER or REQUEST message according to the
|
||||
DHCP service's current state.
|
||||
|
||||
@param[in] DhcpSb The DHCP service instance
|
||||
|
||||
@retval EFI_SUCCESS The request has been sent
|
||||
@retval other Some error occurs when sending the request.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpInitRequest (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up the DHCP related states, IoStatus isn't reset.
|
||||
|
||||
@param DhcpSb The DHCP instance service.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DhcpCleanLease (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
);
|
||||
|
||||
/**
|
||||
Release the net buffer when packet is sent.
|
||||
|
||||
@param UdpPacket The UDP packets received.
|
||||
@param EndPoint The local/remote UDP access point
|
||||
@param IoStatus The status of the UDP receive
|
||||
@param Context The opaque parameter to the function.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DhcpOnPacketSent (
|
||||
NET_BUF *Packet,
|
||||
UDP_END_POINT *EndPoint,
|
||||
EFI_STATUS IoStatus,
|
||||
VOID *Context
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,890 @@
|
|||
/** @file
|
||||
Function to validate, parse, process the DHCP options.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "Dhcp4Impl.h"
|
||||
|
||||
///
|
||||
/// A list of the format of DHCP Options sorted by option tag
|
||||
/// to validate a dhcp message. Refere the comments of the
|
||||
/// DHCP_OPTION_FORMAT structure.
|
||||
///
|
||||
DHCP_OPTION_FORMAT DhcpOptionFormats[] = {
|
||||
{DHCP4_TAG_NETMASK, DHCP_OPTION_IP, 1, 1 , TRUE},
|
||||
{DHCP4_TAG_TIME_OFFSET, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_ROUTER, DHCP_OPTION_IP, 1, -1 , TRUE},
|
||||
{DHCP4_TAG_TIME_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NAME_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_DNS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_LOG_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_COOKIE_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_LPR_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_IMPRESS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_RL_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_HOSTNAME, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_BOOTFILE_LEN, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_DUMP, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_DOMAINNAME, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_SWAP_SERVER, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_ROOTPATH, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_EXTEND_PATH, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_IPFORWARD, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_NONLOCAL_SRR, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_POLICY_SRR, DHCP_OPTION_IPPAIR, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_EMTU, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_TTL, DHCP_OPTION_INT8, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_PATHMTU_AGE, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_PATHMTU_PLATEAU,DHCP_OPTION_INT16, 1, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_IFMTU, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_SUBNET_LOCAL, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_BROADCAST, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_DISCOVER_MASK, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_SUPPLY_MASK, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_DISCOVER_ROUTE, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_ROUTER_SOLICIT, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_STATIC_ROUTE, DHCP_OPTION_IPPAIR, 1, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_TRAILER, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_ARPAGE, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_ETHER_ENCAP, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_TCP_TTL, DHCP_OPTION_INT8, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_KEEP_INTERVAL, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_KEEP_GARBAGE, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_NIS_DOMAIN, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NIS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NTP_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_VENDOR, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NBNS, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NBDD, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NBTYPE, DHCP_OPTION_INT8, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_NBSCOPE, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_XFONT, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_XDM, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_REQUEST_IP, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_LEASE, DHCP_OPTION_INT32, 1, 1 , TRUE},
|
||||
{DHCP4_TAG_OVERLOAD, DHCP_OPTION_INT8, 1, 1 , TRUE},
|
||||
{DHCP4_TAG_MSG_TYPE, DHCP_OPTION_INT8, 1, 1 , TRUE},
|
||||
{DHCP4_TAG_SERVER_ID, DHCP_OPTION_IP, 1, 1 , TRUE},
|
||||
{DHCP4_TAG_PARA_LIST, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_MESSAGE, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_MAXMSG, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP4_TAG_T1, DHCP_OPTION_INT32, 1, 1 , TRUE},
|
||||
{DHCP4_TAG_T2, DHCP_OPTION_INT32, 1, 1 , TRUE},
|
||||
{DHCP4_TAG_VENDOR_CLASS_ID,DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_CLIENT_ID, DHCP_OPTION_INT8, 2, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_NISPLUS, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NISPLUS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_TFTP, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_BOOTFILE, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_MOBILEIP, DHCP_OPTION_IP, 0, -1 , FALSE},
|
||||
{DHCP4_TAG_SMTP, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_POP3, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_NNTP, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_WWW, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_FINGER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_IRC, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_STTALK, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP4_TAG_STDA, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
|
||||
{DHCP4_TAG_CLASSLESS_ROUTE,DHCP_OPTION_INT8, 5, -1 , FALSE},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Binary search the DhcpOptionFormats array to find the format
|
||||
information about a specific option.
|
||||
|
||||
@param[in] Tag The option's tag.
|
||||
|
||||
@return The point to the option's format, NULL if not found.
|
||||
|
||||
**/
|
||||
DHCP_OPTION_FORMAT *
|
||||
DhcpFindOptionFormat (
|
||||
IN UINT8 Tag
|
||||
)
|
||||
{
|
||||
INTN Left;
|
||||
INTN Right;
|
||||
INTN Middle;
|
||||
|
||||
Left = 0;
|
||||
Right = sizeof (DhcpOptionFormats) / sizeof (DHCP_OPTION_FORMAT) - 1;
|
||||
|
||||
while (Right >= Left) {
|
||||
Middle = (Left + Right) / 2;
|
||||
|
||||
if (Tag == DhcpOptionFormats[Middle].Tag) {
|
||||
return &DhcpOptionFormats[Middle];
|
||||
}
|
||||
|
||||
if (Tag < DhcpOptionFormats[Middle].Tag) {
|
||||
Right = Middle - 1;
|
||||
} else {
|
||||
Left = Middle + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Validate whether a single DHCP option is valid according to its format.
|
||||
|
||||
@param[in] Format The option's format
|
||||
@param[in] OptValue The value of the option
|
||||
@param[in] Len The length of the option value
|
||||
|
||||
@retval TRUE The option is valid.
|
||||
@retval FALSE Otherwise.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
DhcpOptionIsValid (
|
||||
IN DHCP_OPTION_FORMAT *Format,
|
||||
IN UINT8 *OptValue,
|
||||
IN INTN Len
|
||||
)
|
||||
{
|
||||
INTN Unit;
|
||||
INTN Occur;
|
||||
INTN Index;
|
||||
|
||||
Unit = 0;
|
||||
|
||||
switch (Format->Type) {
|
||||
case DHCP_OPTION_SWITCH:
|
||||
case DHCP_OPTION_INT8:
|
||||
Unit = 1;
|
||||
break;
|
||||
|
||||
case DHCP_OPTION_INT16:
|
||||
Unit = 2;
|
||||
break;
|
||||
|
||||
case DHCP_OPTION_INT32:
|
||||
case DHCP_OPTION_IP:
|
||||
Unit = 4;
|
||||
break;
|
||||
|
||||
case DHCP_OPTION_IPPAIR:
|
||||
Unit = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT (Unit != 0);
|
||||
|
||||
//
|
||||
// Validate that the option appears in the full units.
|
||||
//
|
||||
if ((Len % Unit) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate the occurance of the option unit is with in [MinOccur, MaxOccur]
|
||||
//
|
||||
Occur = Len / Unit;
|
||||
|
||||
if (((Format->MinOccur != -1) && (Occur < Format->MinOccur)) ||
|
||||
((Format->MaxOccur != -1) && (Occur > Format->MaxOccur))
|
||||
) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// If the option is of type switch, only 0/1 are valid values.
|
||||
//
|
||||
if (Format->Type == DHCP_OPTION_SWITCH) {
|
||||
for (Index = 0; Index < Occur; Index++) {
|
||||
if ((OptValue[Index] != 0) && (OptValue[Index] != 1)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Extract the client interested options, all the parameters are
|
||||
converted to host byte order.
|
||||
|
||||
@param[in] Tag The DHCP option tag
|
||||
@param[in] Len The length of the option
|
||||
@param[in] Data The value of the DHCP option
|
||||
@param[out] Para The variable to save the interested parameter
|
||||
|
||||
@retval EFI_SUCCESS The DHCP option is successfully extracted.
|
||||
@retval EFI_INVALID_PARAMETER The DHCP option is mal-formated
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpGetParameter (
|
||||
IN UINT8 Tag,
|
||||
IN INTN Len,
|
||||
IN UINT8 *Data,
|
||||
OUT DHCP_PARAMETER *Para
|
||||
)
|
||||
{
|
||||
switch (Tag) {
|
||||
case DHCP4_TAG_NETMASK:
|
||||
Para->NetMask = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP4_TAG_ROUTER:
|
||||
//
|
||||
// Return the first router to consumer which is the preferred one
|
||||
//
|
||||
Para->Router = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP4_TAG_LEASE:
|
||||
Para->Lease = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP4_TAG_OVERLOAD:
|
||||
Para->Overload = *Data;
|
||||
|
||||
if ((Para->Overload < 1) || (Para->Overload > 3)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
|
||||
case DHCP4_TAG_MSG_TYPE:
|
||||
Para->DhcpType = *Data;
|
||||
|
||||
if ((Para->DhcpType < 1) || (Para->DhcpType > 9)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
|
||||
case DHCP4_TAG_SERVER_ID:
|
||||
Para->ServerId = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP4_TAG_T1:
|
||||
Para->T1 = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP4_TAG_T2:
|
||||
Para->T2 = NetGetUint32 (Data);
|
||||
break;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Inspect all the options in a single buffer. DHCP options may be contained
|
||||
in several buffers, such as the BOOTP options filed, boot file or server
|
||||
name. Each option buffer is required to end with DHCP4_TAG_EOP.
|
||||
|
||||
@param[in] Buffer The buffer which contains DHCP options
|
||||
@param[in] BufLen The length of the buffer
|
||||
@param[in] Check The callback function for each option found
|
||||
@param[in] Context The opaque parameter for the Check
|
||||
@param[out] Overload Variable to save the value of DHCP4_TAG_OVERLOAD
|
||||
option.
|
||||
|
||||
@retval EFI_SUCCESS All the options are valid
|
||||
@retval EFI_INVALID_PARAMETER The options are mal-formated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpIterateBufferOptions (
|
||||
IN UINT8 *Buffer,
|
||||
IN INTN BufLen,
|
||||
IN DHCP_CHECK_OPTION Check OPTIONAL,
|
||||
IN VOID *Context,
|
||||
OUT UINT8 *Overload OPTIONAL
|
||||
)
|
||||
{
|
||||
INTN Cur;
|
||||
UINT8 Tag;
|
||||
UINT8 Len;
|
||||
|
||||
Cur = 0;
|
||||
|
||||
while (Cur < BufLen) {
|
||||
Tag = Buffer[Cur];
|
||||
|
||||
if (Tag == DHCP4_TAG_PAD) {
|
||||
Cur++;
|
||||
continue;
|
||||
} else if (Tag == DHCP4_TAG_EOP) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Cur++;
|
||||
|
||||
if (Cur == BufLen) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Len = Buffer[Cur++];
|
||||
|
||||
if (Cur + Len > BufLen) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Tag == DHCP4_TAG_OVERLOAD) && (Overload != NULL)) {
|
||||
if (Len != 1) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*Overload = Buffer[Cur];
|
||||
}
|
||||
|
||||
if ((Check != NULL) && EFI_ERROR (Check (Tag, Len, Buffer + Cur, Context))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Cur += Len;
|
||||
}
|
||||
|
||||
//
|
||||
// Each option buffer is expected to end with an EOP
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Iterate through a DHCP message to visit each option. First inspect
|
||||
all the options in the OPTION field. Then if overloaded, inspect
|
||||
the options in FILENAME and SERVERNAME fields. One option may be
|
||||
encoded in several places. See RFC 3396 Encoding Long Options in DHCP
|
||||
|
||||
@param[in] Packet The DHCP packet to check the options for
|
||||
@param[in] Check The callback function to be called for each option
|
||||
found
|
||||
@param[in] Context The opaque parameter for Check
|
||||
|
||||
@retval EFI_SUCCESS The DHCP packet's options are well formated
|
||||
@retval EFI_INVALID_PARAMETER The DHCP packet's options are not well formated
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpIterateOptions (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
IN DHCP_CHECK_OPTION Check OPTIONAL,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 Overload;
|
||||
|
||||
Overload = 0;
|
||||
|
||||
Status = DhcpIterateBufferOptions (
|
||||
Packet->Dhcp4.Option,
|
||||
Packet->Length - sizeof (EFI_DHCP4_HEADER) - sizeof (UINT32),
|
||||
Check,
|
||||
Context,
|
||||
&Overload
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if ((Overload == DHCP_OVERLOAD_FILENAME) || (Overload == DHCP_OVERLOAD_BOTH)) {
|
||||
Status = DhcpIterateBufferOptions (
|
||||
(UINT8 *) Packet->Dhcp4.Header.BootFileName,
|
||||
128,
|
||||
Check,
|
||||
Context,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if ((Overload == DHCP_OVERLOAD_SVRNAME) || (Overload == DHCP_OVERLOAD_BOTH)) {
|
||||
Status = DhcpIterateBufferOptions (
|
||||
(UINT8 *) Packet->Dhcp4.Header.ServerName,
|
||||
64,
|
||||
Check,
|
||||
Context,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Call back function to DhcpIterateOptions to compute each option's
|
||||
length. It just adds the data length of all the occurances of this
|
||||
Tag. Context is an array of 256 DHCP_OPTION_COUNT.
|
||||
|
||||
@param[in] Tag The current option to check
|
||||
@param[in] Len The length of the option data
|
||||
@param[in] Data The option data
|
||||
@param[in] Context The context, which is a array of 256
|
||||
DHCP_OPTION_COUNT.
|
||||
|
||||
@retval EFI_SUCCESS It always returns EFI_SUCCESS.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpGetOptionLen (
|
||||
IN UINT8 Tag,
|
||||
IN UINT8 Len,
|
||||
IN UINT8 *Data,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
DHCP_OPTION_COUNT *OpCount;
|
||||
|
||||
OpCount = (DHCP_OPTION_COUNT *) Context;
|
||||
OpCount[Tag].Offset = (UINT16) (OpCount[Tag].Offset + Len);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Call back function to DhcpIterateOptions to consolidate each option's
|
||||
data. There are maybe several occurrence of the same option.
|
||||
|
||||
@param[in] Tag The option to consolidate its data
|
||||
@param[in] Len The length of option data
|
||||
@param[in] Data The data of the option's current occurance
|
||||
@param[in] Context The context, which is DHCP_OPTION_CONTEXT. This
|
||||
array is just a wrap to pass THREE parameters.
|
||||
|
||||
@retval EFI_SUCCESS It always returns EFI_SUCCESS
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpFillOption (
|
||||
IN UINT8 Tag,
|
||||
IN UINT8 Len,
|
||||
IN UINT8 *Data,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
DHCP_OPTION_CONTEXT *OptContext;
|
||||
DHCP_OPTION_COUNT *OptCount;
|
||||
DHCP_OPTION *Options;
|
||||
UINT8 *Buf;
|
||||
UINT8 Index;
|
||||
|
||||
OptContext = (DHCP_OPTION_CONTEXT *) Context;
|
||||
|
||||
OptCount = OptContext->OpCount;
|
||||
Index = OptCount[Tag].Index;
|
||||
Options = OptContext->Options;
|
||||
Buf = OptContext->Buf;
|
||||
|
||||
if (Options[Index].Data == NULL) {
|
||||
Options[Index].Tag = Tag;
|
||||
Options[Index].Data = Buf + OptCount[Tag].Offset;
|
||||
}
|
||||
|
||||
CopyMem (Buf + OptCount[Tag].Offset, Data, Len);
|
||||
|
||||
OptCount[Tag].Offset = (UINT16) (OptCount[Tag].Offset + Len);
|
||||
Options[Index].Len = (UINT16) (Options[Index].Len + Len);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Parse the options of a DHCP packet. It supports RFC 3396: Encoding
|
||||
Long Options in DHCP. That is, it will combine all the option value
|
||||
of all the occurances of each option.
|
||||
A little bit of implemenation:
|
||||
It adopts the "Key indexed counting" algorithm. First, it allocates
|
||||
an array of 256 DHCP_OPTION_COUNTs because DHCP option tag is encoded
|
||||
as a UINT8. It then iterates the DHCP packet to get data length of
|
||||
each option by calling DhcpIterOptions with DhcpGetOptionLen. Now, it
|
||||
knows the number of present options and their length. It allocates a
|
||||
array of DHCP_OPTION and a continuous buffer after the array to put
|
||||
all the options' data. Each option's data is pointed to by the Data
|
||||
field in DHCP_OPTION structure. At last, it call DhcpIterateOptions
|
||||
with DhcpFillOption to fill each option's data to its position in the
|
||||
buffer.
|
||||
|
||||
@param[in] Packet The DHCP packet to parse the options
|
||||
@param[out] Count The number of valid dhcp options present in the
|
||||
packet
|
||||
@param[out] OptionPoint The array that contains the DHCP options. Caller
|
||||
should free it.
|
||||
|
||||
@retval EFI_NOT_FOUND Cannot find any option.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory to parse the packet.
|
||||
@retval EFI_INVALID_PARAMETER The options are mal-formated
|
||||
@retval EFI_SUCCESS The options are parsed into OptionPoint
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpParseOption (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
OUT INTN *Count,
|
||||
OUT DHCP_OPTION **OptionPoint
|
||||
)
|
||||
{
|
||||
DHCP_OPTION_CONTEXT Context;
|
||||
DHCP_OPTION *Options;
|
||||
DHCP_OPTION_COUNT *OptCount;
|
||||
EFI_STATUS Status;
|
||||
UINT16 TotalLen;
|
||||
INTN OptNum;
|
||||
INTN Index;
|
||||
|
||||
ASSERT ((Count != NULL) && (OptionPoint != NULL));
|
||||
|
||||
//
|
||||
// First compute how many options and how long each option is
|
||||
// with the "Key indexed counting" algorithms.
|
||||
//
|
||||
OptCount = AllocateZeroPool (DHCP_MAX_OPTIONS * sizeof (DHCP_OPTION_COUNT));
|
||||
|
||||
if (OptCount == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = DhcpIterateOptions (Packet, DhcpGetOptionLen, OptCount);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Before the loop, Offset is the length of the option. After loop,
|
||||
// OptCount[Index].Offset specifies the offset into the continuous
|
||||
// option value buffer to put the data.
|
||||
//
|
||||
TotalLen = 0;
|
||||
OptNum = 0;
|
||||
|
||||
for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
|
||||
if (OptCount[Index].Offset != 0) {
|
||||
OptCount[Index].Index = (UINT8) OptNum;
|
||||
|
||||
TotalLen = (UINT16) (TotalLen + OptCount[Index].Offset);
|
||||
OptCount[Index].Offset = (UINT16) (TotalLen - OptCount[Index].Offset);
|
||||
|
||||
OptNum++;
|
||||
}
|
||||
}
|
||||
|
||||
*Count = OptNum;
|
||||
*OptionPoint = NULL;
|
||||
|
||||
if (OptNum == 0) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a buffer to hold the DHCP options, and after that, a
|
||||
// continuous buffer to put all the options' data.
|
||||
//
|
||||
Options = AllocateZeroPool ((UINTN) (OptNum * sizeof (DHCP_OPTION)) + TotalLen);
|
||||
|
||||
if (Options == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Context.OpCount = OptCount;
|
||||
Context.Options = Options;
|
||||
Context.Buf = (UINT8 *) (Options + OptNum);
|
||||
|
||||
Status = DhcpIterateOptions (Packet, DhcpFillOption, &Context);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (Options);
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
*OptionPoint = Options;
|
||||
|
||||
ON_EXIT:
|
||||
FreePool (OptCount);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Validate the packet's options. If necessary, allocate
|
||||
and fill in the interested parameters.
|
||||
|
||||
@param[in] Packet The packet to validate the options
|
||||
@param[out] Para The variable to save the DHCP parameters.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory to validate the packet.
|
||||
@retval EFI_INVALID_PARAMETER The options are mal-formated
|
||||
@retval EFI_SUCCESS The options are parsed into OptionPoint
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpValidateOptions (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
OUT DHCP_PARAMETER **Para OPTIONAL
|
||||
)
|
||||
{
|
||||
DHCP_PARAMETER Parameter;
|
||||
DHCP_OPTION_FORMAT *Format;
|
||||
DHCP_OPTION *AllOption;
|
||||
DHCP_OPTION *Option;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN Updated;
|
||||
INTN Count;
|
||||
INTN Index;
|
||||
|
||||
if (Para != NULL) {
|
||||
*Para = NULL;
|
||||
}
|
||||
|
||||
AllOption = NULL;
|
||||
|
||||
Status = DhcpParseOption (Packet, &Count, &AllOption);
|
||||
if (EFI_ERROR (Status) || (Count == 0)) {
|
||||
return Status;
|
||||
}
|
||||
ASSERT (AllOption != NULL);
|
||||
|
||||
Updated = FALSE;
|
||||
ZeroMem (&Parameter, sizeof (Parameter));
|
||||
|
||||
for (Index = 0; Index < Count; Index++) {
|
||||
Option = &AllOption[Index];
|
||||
|
||||
//
|
||||
// Find the format of the option then validate it.
|
||||
//
|
||||
Format = DhcpFindOptionFormat (Option->Tag);
|
||||
|
||||
if (Format == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!DhcpOptionIsValid (Format, Option->Data, Option->Len)) {
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the client interested parameters
|
||||
//
|
||||
if (Format->Alert && (Para != NULL)) {
|
||||
Updated = TRUE;
|
||||
Status = DhcpGetParameter (Option->Tag, Option->Len, Option->Data, &Parameter);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Updated && (Para != NULL)) {
|
||||
*Para = AllocateCopyPool (sizeof (DHCP_PARAMETER), &Parameter);
|
||||
if (*Para == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
FreePool (AllOption);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Append an option to the memory, if the option is longer than
|
||||
255 bytes, splits it into several options.
|
||||
|
||||
@param[out] Buf The buffer to append the option to
|
||||
@param[in] Tag The option's tag
|
||||
@param[in] DataLen The length of the option's data
|
||||
@param[in] Data The option's data
|
||||
|
||||
@return The position to append the next option
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
DhcpAppendOption (
|
||||
OUT UINT8 *Buf,
|
||||
IN UINT8 Tag,
|
||||
IN UINT16 DataLen,
|
||||
IN UINT8 *Data
|
||||
)
|
||||
{
|
||||
INTN Index;
|
||||
INTN Len;
|
||||
|
||||
ASSERT (DataLen != 0);
|
||||
|
||||
for (Index = 0; Index < (DataLen + 254) / 255; Index++) {
|
||||
Len = MIN (255, DataLen - Index * 255);
|
||||
|
||||
*(Buf++) = Tag;
|
||||
*(Buf++) = (UINT8) Len;
|
||||
CopyMem (Buf, Data + Index * 255, (UINTN) Len);
|
||||
|
||||
Buf += Len;
|
||||
}
|
||||
|
||||
return Buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Build a new DHCP packet from a seed packet. Options may be deleted or
|
||||
appended. The caller should free the NewPacket when finished using it.
|
||||
|
||||
@param[in] SeedPacket The seed packet to start with
|
||||
@param[in] DeleteCount The number of options to delete
|
||||
@param[in] DeleteList The options to delete from the packet
|
||||
@param[in] AppendCount The number of options to append
|
||||
@param[in] AppendList The options to append to the packet
|
||||
@param[out] NewPacket The new packet, allocated and built by this
|
||||
function.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
|
||||
@retval EFI_INVALID_PARAMETER The options in SeekPacket are mal-formated
|
||||
@retval EFI_SUCCESS The packet is build.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpBuild (
|
||||
IN EFI_DHCP4_PACKET *SeedPacket,
|
||||
IN UINT32 DeleteCount,
|
||||
IN UINT8 *DeleteList OPTIONAL,
|
||||
IN UINT32 AppendCount,
|
||||
IN EFI_DHCP4_PACKET_OPTION *AppendList[] OPTIONAL,
|
||||
OUT EFI_DHCP4_PACKET **NewPacket
|
||||
)
|
||||
{
|
||||
DHCP_OPTION *Mark;
|
||||
DHCP_OPTION *SeedOptions;
|
||||
EFI_DHCP4_PACKET *Packet;
|
||||
EFI_STATUS Status;
|
||||
INTN Count;
|
||||
UINT32 Index;
|
||||
UINT32 Len;
|
||||
UINT8 *Buf;
|
||||
|
||||
//
|
||||
// Use an array of DHCP_OPTION to mark the existance
|
||||
// and position of each valid options.
|
||||
//
|
||||
Mark = AllocatePool (sizeof (DHCP_OPTION) * DHCP_MAX_OPTIONS);
|
||||
|
||||
if (Mark == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
|
||||
Mark[Index].Tag = (UINT8) Index;
|
||||
Mark[Index].Len = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Get list of the options from the seed packet, then put
|
||||
// them to the mark array according to their tags.
|
||||
//
|
||||
SeedOptions = NULL;
|
||||
Status = DhcpParseOption (SeedPacket, &Count, &SeedOptions);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
if (SeedOptions != NULL) {
|
||||
for (Index = 0; Index < (UINT32) Count; Index++) {
|
||||
Mark[SeedOptions[Index].Tag] = SeedOptions[Index];
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Mark the option's length is zero if it is in the DeleteList.
|
||||
//
|
||||
for (Index = 0; Index < DeleteCount; Index++) {
|
||||
Mark[DeleteList[Index]].Len = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Add or replace the option if it is in the append list.
|
||||
//
|
||||
for (Index = 0; Index < AppendCount; Index++) {
|
||||
Mark[AppendList[Index]->OpCode].Len = AppendList[Index]->Length;
|
||||
Mark[AppendList[Index]->OpCode].Data = AppendList[Index]->Data;
|
||||
}
|
||||
|
||||
//
|
||||
// compute the new packet length. No need to add 1 byte for
|
||||
// EOP option since EFI_DHCP4_PACKET includes one extra byte
|
||||
// for option. It is necessary to split the option if it is
|
||||
// longer than 255 bytes.
|
||||
//
|
||||
Len = sizeof (EFI_DHCP4_PACKET);
|
||||
|
||||
for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
|
||||
if (Mark[Index].Len != 0) {
|
||||
Len += ((Mark[Index].Len + 254) / 255) * 2 + Mark[Index].Len;
|
||||
}
|
||||
}
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
Packet = (EFI_DHCP4_PACKET *) AllocatePool (Len);
|
||||
|
||||
if (Packet == NULL) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Packet->Size = Len;
|
||||
Packet->Length = 0;
|
||||
CopyMem (&Packet->Dhcp4.Header, &SeedPacket->Dhcp4.Header, sizeof (Packet->Dhcp4.Header));
|
||||
Packet->Dhcp4.Magik = DHCP_OPTION_MAGIC;
|
||||
Buf = Packet->Dhcp4.Option;
|
||||
|
||||
for (Index = 0; Index < DHCP_MAX_OPTIONS; Index++) {
|
||||
if (Mark[Index].Len != 0) {
|
||||
Buf = DhcpAppendOption (Buf, Mark[Index].Tag, Mark[Index].Len, Mark[Index].Data);
|
||||
}
|
||||
}
|
||||
|
||||
*(Buf++) = DHCP4_TAG_EOP;
|
||||
Packet->Length = sizeof (EFI_DHCP4_HEADER) + sizeof (UINT32)
|
||||
+ (UINT32) (Buf - Packet->Dhcp4.Option);
|
||||
|
||||
*NewPacket = Packet;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
if (SeedOptions != NULL) {
|
||||
FreePool (SeedOptions);
|
||||
}
|
||||
|
||||
FreePool (Mark);
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
/** @file
|
||||
To validate, parse and process the DHCP options.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_OPTION_H__
|
||||
#define __EFI_DHCP4_OPTION_H__
|
||||
|
||||
///
|
||||
/// DHCP option tags (types)
|
||||
///
|
||||
|
||||
#define DHCP_OPTION_MAGIC 0x63538263 // Network byte order
|
||||
#define DHCP_MAX_OPTIONS 256
|
||||
|
||||
|
||||
//
|
||||
// DHCP option types, this is used to validate the DHCP options.
|
||||
//
|
||||
#define DHCP_OPTION_SWITCH 1
|
||||
#define DHCP_OPTION_INT8 2
|
||||
#define DHCP_OPTION_INT16 3
|
||||
#define DHCP_OPTION_INT32 4
|
||||
#define DHCP_OPTION_IP 5
|
||||
#define DHCP_OPTION_IPPAIR 6
|
||||
|
||||
//
|
||||
// Value of DHCP overload option
|
||||
//
|
||||
#define DHCP_OVERLOAD_FILENAME 1
|
||||
#define DHCP_OVERLOAD_SVRNAME 2
|
||||
#define DHCP_OVERLOAD_BOTH 3
|
||||
|
||||
///
|
||||
/// The DHCP option structure. This structure extends the EFI_DHCP_OPTION
|
||||
/// structure to support options longer than 255 bytes, such as classless route.
|
||||
///
|
||||
typedef struct {
|
||||
UINT8 Tag;
|
||||
UINT16 Len;
|
||||
UINT8 *Data;
|
||||
} DHCP_OPTION;
|
||||
|
||||
///
|
||||
/// Structures used to parse the DHCP options with RFC3396 support.
|
||||
///
|
||||
typedef struct {
|
||||
UINT8 Index;
|
||||
UINT16 Offset;
|
||||
} DHCP_OPTION_COUNT;
|
||||
|
||||
typedef struct {
|
||||
DHCP_OPTION_COUNT *OpCount;
|
||||
DHCP_OPTION *Options;
|
||||
UINT8 *Buf;
|
||||
} DHCP_OPTION_CONTEXT;
|
||||
|
||||
///
|
||||
/// The options that matters to DHCP driver itself. The user of
|
||||
/// DHCP clients may be interested in other options, such as
|
||||
/// classless route, who can parse the DHCP offer to get them.
|
||||
///
|
||||
typedef struct {
|
||||
IP4_ADDR NetMask; // DHCP4_TAG_NETMASK
|
||||
IP4_ADDR Router; // DHCP4_TAG_ROUTER, only the first router is used
|
||||
|
||||
//
|
||||
// DHCP specific options
|
||||
//
|
||||
UINT8 DhcpType; // DHCP4_TAG_MSG_TYPE
|
||||
UINT8 Overload; // DHCP4_TAG_OVERLOAD
|
||||
IP4_ADDR ServerId; // DHCP4_TAG_SERVER_ID
|
||||
UINT32 Lease; // DHCP4_TAG_LEASE
|
||||
UINT32 T1; // DHCP4_TAG_T1
|
||||
UINT32 T2; // DHCP4_TAG_T2
|
||||
} DHCP_PARAMETER;
|
||||
|
||||
///
|
||||
/// Structure used to describe and validate the format of DHCP options.
|
||||
/// Type is the options' data type, such as DHCP_OPTION_INT8. MinOccur
|
||||
/// is the minium occurance of this data type. MaxOccur is defined
|
||||
/// similarly. If MaxOccur is -1, it means that there is no limit on the
|
||||
/// maximum occurance. Alert tells whether DHCP client should further
|
||||
/// inspect the option to parse DHCP_PARAMETER.
|
||||
///
|
||||
typedef struct {
|
||||
UINT8 Tag;
|
||||
INTN Type;
|
||||
INTN MinOccur;
|
||||
INTN MaxOccur;
|
||||
BOOLEAN Alert;
|
||||
} DHCP_OPTION_FORMAT;
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*DHCP_CHECK_OPTION) (
|
||||
IN UINT8 Tag,
|
||||
IN UINT8 Len,
|
||||
IN UINT8 *Data,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Iterate through a DHCP message to visit each option. First inspect
|
||||
all the options in the OPTION field. Then if overloaded, inspect
|
||||
the options in FILENAME and SERVERNAME fields. One option may be
|
||||
encoded in several places. See RFC 3396 Encoding Long Options in DHCP
|
||||
|
||||
@param[in] Packet The DHCP packet to check the options for
|
||||
@param[in] Check The callback function to be called for each option
|
||||
found
|
||||
@param[in] Context The opaque parameter for Check
|
||||
|
||||
@retval EFI_SUCCESS The DHCP packet's options are well formated
|
||||
@retval EFI_INVALID_PARAMETER The DHCP packet's options are not well formated
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpIterateOptions (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
IN DHCP_CHECK_OPTION Check OPTIONAL,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Validate the packet's options. If necessary, allocate
|
||||
and fill in the interested parameters.
|
||||
|
||||
@param[in] Packet The packet to validate the options
|
||||
@param[out] Para The variable to save the DHCP parameters.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory to validate the packet.
|
||||
@retval EFI_INVALID_PARAMETER The options are mal-formated
|
||||
@retval EFI_SUCCESS The options are parsed into OptionPoint
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpValidateOptions (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
OUT DHCP_PARAMETER **Para OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Parse the options of a DHCP packet. It supports RFC 3396: Encoding
|
||||
Long Options in DHCP. That is, it will combine all the option value
|
||||
of all the occurances of each option.
|
||||
A little bit of implemenation:
|
||||
It adopts the "Key indexed counting" algorithm. First, it allocates
|
||||
an array of 256 DHCP_OPTION_COUNTs because DHCP option tag is encoded
|
||||
as a UINT8. It then iterates the DHCP packet to get data length of
|
||||
each option by calling DhcpIterOptions with DhcpGetOptionLen. Now, it
|
||||
knows the number of present options and their length. It allocates a
|
||||
array of DHCP_OPTION and a continuous buffer after the array to put
|
||||
all the options' data. Each option's data is pointed to by the Data
|
||||
field in DHCP_OPTION structure. At last, it call DhcpIterateOptions
|
||||
with DhcpFillOption to fill each option's data to its position in the
|
||||
buffer.
|
||||
|
||||
@param[in] Packet The DHCP packet to parse the options
|
||||
@param[out] Count The number of valid dhcp options present in the
|
||||
packet
|
||||
@param[out] OptionPoint The array that contains the DHCP options. Caller
|
||||
should free it.
|
||||
|
||||
@retval EFI_NOT_FOUND Cannot find any option.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory to parse the packet.
|
||||
@retval EFI_INVALID_PARAMETER The options are mal-formated
|
||||
@retval EFI_SUCCESS The options are parsed into OptionPoint
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpParseOption (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
OUT INTN *Count,
|
||||
OUT DHCP_OPTION **OptionPoint
|
||||
);
|
||||
|
||||
/**
|
||||
Append an option to the memory, if the option is longer than
|
||||
255 bytes, splits it into several options.
|
||||
|
||||
@param[out] Buf The buffer to append the option to
|
||||
@param[in] Tag The option's tag
|
||||
@param[in] DataLen The length of the option's data
|
||||
@param[in] Data The option's data
|
||||
|
||||
@return The position to append the next option
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
DhcpAppendOption (
|
||||
OUT UINT8 *Buf,
|
||||
IN UINT8 Tag,
|
||||
IN UINT16 DataLen,
|
||||
IN UINT8 *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Build a new DHCP packet from a seed packet. Options may be deleted or
|
||||
appended. The caller should free the NewPacket when finished using it.
|
||||
|
||||
@param[in] SeedPacket The seed packet to start with
|
||||
@param[in] DeleteCount The number of options to delete
|
||||
@param[in] DeleteList The options to delete from the packet
|
||||
@param[in] AppendCount The number of options to append
|
||||
@param[in] AppendList The options to append to the packet
|
||||
@param[out] NewPacket The new packet, allocated and built by this
|
||||
function.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
|
||||
@retval EFI_INVALID_PARAMETER The options in SeekPacket are mal-formated
|
||||
@retval EFI_SUCCESS The packet is build.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpBuild (
|
||||
IN EFI_DHCP4_PACKET *SeedPacket,
|
||||
IN UINT32 DeleteCount,
|
||||
IN UINT8 *DeleteList OPTIONAL,
|
||||
IN UINT32 AppendCount,
|
||||
IN EFI_DHCP4_PACKET_OPTION *AppendList[] OPTIONAL,
|
||||
OUT EFI_DHCP4_PACKET **NewPacket
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,442 @@
|
|||
/** @file
|
||||
UEFI Component Name(2) protocol implementation for Dhcp6 driver.
|
||||
|
||||
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "Dhcp6Impl.h"
|
||||
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the driver.
|
||||
|
||||
This function retrieves the user-readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user-readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user-readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user-readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that attempt to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that attempts to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language, from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gDhcp6ComponentName = {
|
||||
Dhcp6ComponentNameGetDriverName,
|
||||
Dhcp6ComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
//
|
||||
// EFI Component Name 2 Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gDhcp6ComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) Dhcp6ComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) Dhcp6ComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mDhcp6DriverNameTable[] = {
|
||||
{
|
||||
"eng;en",
|
||||
L"DHCP6 Protocol Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable = NULL;
|
||||
|
||||
CHAR16 *mDhcp6ControllerName[] = {
|
||||
L"DHCPv6 (State=0, Init)",
|
||||
L"DHCPv6 (State=1, Selecting)",
|
||||
L"DHCPv6 (State=2, Requesting)",
|
||||
L"DHCPv6 (State=3, Declining)",
|
||||
L"DHCPv6 (State=4, Confirming)",
|
||||
L"DHCPv6 (State=5, Releasing)",
|
||||
L"DHCPv6 (State=6, Bound)",
|
||||
L"DHCPv6 (State=7, Renewing)",
|
||||
L"DHCPv6 (State=8, Rebinding)"
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the driver.
|
||||
|
||||
This function retrieves the user-readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user-readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] DriverName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mDhcp6DriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This == &gDhcp6ComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Update the component name for the Dhcp6 child handle.
|
||||
|
||||
@param Dhcp6[in] A pointer to the EFI_DHCP6_PROTOCOL.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
|
||||
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateName (
|
||||
IN EFI_DHCP6_PROTOCOL *Dhcp6
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DHCP6_MODE_DATA Dhcp6ModeData;
|
||||
CHAR16 *HandleName;
|
||||
|
||||
if (Dhcp6 == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Format the child name into the string buffer.
|
||||
//
|
||||
Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (gDhcp6ControllerNameTable != NULL) {
|
||||
FreeUnicodeStringTable (gDhcp6ControllerNameTable);
|
||||
gDhcp6ControllerNameTable = NULL;
|
||||
}
|
||||
|
||||
if (Dhcp6ModeData.Ia == NULL) {
|
||||
HandleName = L"DHCPv6 (No configured IA)";
|
||||
} else {
|
||||
if (Dhcp6ModeData.Ia->State > Dhcp6Rebinding) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
HandleName = mDhcp6ControllerName[Dhcp6ModeData.Ia->State];
|
||||
}
|
||||
|
||||
if (Dhcp6ModeData.Ia != NULL) {
|
||||
FreePool (Dhcp6ModeData.Ia);
|
||||
}
|
||||
if (Dhcp6ModeData.ClientId != NULL) {
|
||||
FreePool (Dhcp6ModeData.ClientId);
|
||||
}
|
||||
|
||||
Status = AddUnicodeString2 (
|
||||
"eng",
|
||||
gDhcp6ComponentName.SupportedLanguages,
|
||||
&gDhcp6ControllerNameTable,
|
||||
HandleName,
|
||||
TRUE
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return AddUnicodeString2 (
|
||||
"en",
|
||||
gDhcp6ComponentName2.SupportedLanguages,
|
||||
&gDhcp6ControllerNameTable,
|
||||
HandleName,
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user-readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user-readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] ControllerHandle The handle of a controller that the driver
|
||||
specified by This is managing. This handle
|
||||
specifies the controller whose name is to be
|
||||
returned.
|
||||
|
||||
@param[in] ChildHandle The handle of the child controller to retrieve
|
||||
the name of. This is an optional parameter that
|
||||
may be NULL. It will be NULL for device
|
||||
drivers. It will also be NULL for a bus drivers
|
||||
that wish to retrieve the name of the bus
|
||||
controller. It will not be NULL for a bus
|
||||
driver that wishes to retrieve the name of a
|
||||
child controller.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name that the caller is
|
||||
requesting, and it must match one of the
|
||||
languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up
|
||||
to the driver writer. Language is specified in the
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] ControllerName A pointer to the Unicode string to return.
|
||||
This Unicode string is the name of the
|
||||
controller specified by ControllerHandle and
|
||||
ChildHandle in the language specified by
|
||||
Language, from the point of view of the driver
|
||||
specified by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in
|
||||
the language specified by Language for the
|
||||
driver specified by This was returned in
|
||||
DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DHCP6_PROTOCOL *Dhcp6;
|
||||
|
||||
//
|
||||
// Only provide names for child handles.
|
||||
//
|
||||
if (ChildHandle == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure this driver produced ChildHandle
|
||||
//
|
||||
Status = EfiTestChildHandle (
|
||||
ControllerHandle,
|
||||
ChildHandle,
|
||||
&gEfiUdp6ProtocolGuid
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve an instance of a produced protocol from ChildHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiDhcp6ProtocolGuid,
|
||||
(VOID **)&Dhcp6,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the component name for this child handle.
|
||||
//
|
||||
Status = UpdateName (Dhcp6);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
gDhcp6ControllerNameTable,
|
||||
ControllerName,
|
||||
(BOOLEAN)(This == &gDhcp6ComponentName)
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,813 @@
|
|||
/** @file
|
||||
Driver Binding functions and Service Binding functions
|
||||
implementationfor for Dhcp6 Driver.
|
||||
|
||||
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "Dhcp6Impl.h"
|
||||
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gDhcp6DriverBinding = {
|
||||
Dhcp6DriverBindingSupported,
|
||||
Dhcp6DriverBindingStart,
|
||||
Dhcp6DriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_SERVICE_BINDING_PROTOCOL gDhcp6ServiceBindingTemplate = {
|
||||
Dhcp6ServiceBindingCreateChild,
|
||||
Dhcp6ServiceBindingDestroyChild
|
||||
};
|
||||
|
||||
/**
|
||||
Configure the default Udp6Io to receive all the DHCP6 traffic
|
||||
on this network interface.
|
||||
|
||||
@param[in] UdpIo The pointer to Udp6Io to be configured.
|
||||
@param[in] Context The pointer to the context.
|
||||
|
||||
@retval EFI_SUCCESS The Udp6Io is successfully configured.
|
||||
@retval Others Failed to configure the Udp6Io.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ConfigureUdpIo (
|
||||
IN UDP_IO *UdpIo,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_UDP6_PROTOCOL *Udp6;
|
||||
EFI_UDP6_CONFIG_DATA *Config;
|
||||
|
||||
Udp6 = UdpIo->Protocol.Udp6;
|
||||
Config = &(UdpIo->Config.Udp6);
|
||||
|
||||
ZeroMem (Config, sizeof (EFI_UDP6_CONFIG_DATA));
|
||||
|
||||
//
|
||||
// Set Udp6 configure data for the Dhcp6 instance.
|
||||
//
|
||||
Config->AcceptPromiscuous = FALSE;
|
||||
Config->AcceptAnyPort = FALSE;
|
||||
Config->AllowDuplicatePort = FALSE;
|
||||
Config->TrafficClass = 0;
|
||||
Config->HopLimit = 128;
|
||||
Config->ReceiveTimeout = 0;
|
||||
Config->TransmitTimeout = 0;
|
||||
|
||||
//
|
||||
// Configure an endpoint of client(0, 546), server(0, 0), the addresses
|
||||
// will be overridden later. Note that we MUST not limit RemotePort.
|
||||
// More details, refer to RFC 3315 section 5.2.
|
||||
//
|
||||
Config->StationPort = DHCP6_PORT_CLIENT;
|
||||
Config->RemotePort = 0;
|
||||
|
||||
return Udp6->Configure (Udp6, Config);;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroy the Dhcp6 service. The Dhcp6 service may be partly initialized,
|
||||
or partly destroyed. If a resource is destroyed, it is marked as such in
|
||||
case the destroy failed and being called again later.
|
||||
|
||||
@param[in, out] Service The pointer to Dhcp6 service to be destroyed.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6DestroyService (
|
||||
IN OUT DHCP6_SERVICE *Service
|
||||
)
|
||||
{
|
||||
//
|
||||
// All children instances should have been already destroyed here.
|
||||
//
|
||||
ASSERT (Service->NumOfChild == 0);
|
||||
|
||||
if (Service->ClientId != NULL) {
|
||||
FreePool (Service->ClientId);
|
||||
}
|
||||
|
||||
if (Service->UdpIo != NULL) {
|
||||
UdpIoFreeIo (Service->UdpIo);
|
||||
}
|
||||
|
||||
FreePool (Service);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Create a new Dhcp6 service for the Nic controller.
|
||||
|
||||
@param[in] Controller The controller to be installed DHCP6 service
|
||||
binding protocol.
|
||||
@param[in] ImageHandle The image handle of the Dhcp6 driver.
|
||||
@param[out] Service The return pointer of the new Dhcp6 service.
|
||||
|
||||
@retval EFI_SUCCESS The Dhcp6 service is created successfully.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6CreateService (
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT DHCP6_SERVICE **Service
|
||||
)
|
||||
{
|
||||
DHCP6_SERVICE *Dhcp6Srv;
|
||||
EFI_STATUS Status;
|
||||
|
||||
*Service = NULL;
|
||||
Dhcp6Srv = AllocateZeroPool (sizeof (DHCP6_SERVICE));
|
||||
|
||||
if (Dhcp6Srv == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the SNP protocol to get mode data later.
|
||||
//
|
||||
Dhcp6Srv->Snp = NULL;
|
||||
NetLibGetSnpHandle (Controller, &Dhcp6Srv->Snp);
|
||||
if (Dhcp6Srv->Snp == NULL) {
|
||||
FreePool (Dhcp6Srv);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the fields of the new Dhcp6 service.
|
||||
//
|
||||
Dhcp6Srv->Signature = DHCP6_SERVICE_SIGNATURE;
|
||||
Dhcp6Srv->Controller = Controller;
|
||||
Dhcp6Srv->Image = ImageHandle;
|
||||
Dhcp6Srv->Xid = (0xffffff & NET_RANDOM (NetRandomInitSeed ()));
|
||||
|
||||
CopyMem (
|
||||
&Dhcp6Srv->ServiceBinding,
|
||||
&gDhcp6ServiceBindingTemplate,
|
||||
sizeof (EFI_SERVICE_BINDING_PROTOCOL)
|
||||
);
|
||||
|
||||
//
|
||||
// Locate Ip6->Ip6Config and store it for get IP6 Duplicate Address Detection transmits.
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
Controller,
|
||||
&gEfiIp6ConfigProtocolGuid,
|
||||
(VOID **) &Dhcp6Srv->Ip6Cfg
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (Dhcp6Srv);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate client Duid: If SMBIOS system UUID is located, generate DUID in DUID-UUID format.
|
||||
// Otherwise, in DUID-LLT format.
|
||||
//
|
||||
Dhcp6Srv->ClientId = Dhcp6GenerateClientId (Dhcp6Srv->Snp->Mode);
|
||||
|
||||
if (Dhcp6Srv->ClientId == NULL) {
|
||||
FreePool (Dhcp6Srv);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Create an Udp6Io for stateful transmit/receive of each Dhcp6 instance.
|
||||
//
|
||||
Dhcp6Srv->UdpIo = UdpIoCreateIo (
|
||||
Controller,
|
||||
ImageHandle,
|
||||
Dhcp6ConfigureUdpIo,
|
||||
UDP_IO_UDP6_VERSION,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (Dhcp6Srv->UdpIo == NULL) {
|
||||
FreePool (Dhcp6Srv->ClientId);
|
||||
FreePool (Dhcp6Srv);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
InitializeListHead (&Dhcp6Srv->Child);
|
||||
|
||||
*Service = Dhcp6Srv;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroy the Dhcp6 instance and recycle the resources.
|
||||
|
||||
@param[in, out] Instance The pointer to the Dhcp6 instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6DestroyInstance (
|
||||
IN OUT DHCP6_INSTANCE *Instance
|
||||
)
|
||||
{
|
||||
//
|
||||
// Clean up the retry list first.
|
||||
//
|
||||
Dhcp6CleanupRetry (Instance, DHCP6_PACKET_ALL);
|
||||
gBS->CloseEvent (Instance->Timer);
|
||||
|
||||
//
|
||||
// Clean up the current configure data.
|
||||
//
|
||||
if (Instance->Config != NULL) {
|
||||
Dhcp6CleanupConfigData (Instance->Config);
|
||||
FreePool (Instance->Config);
|
||||
}
|
||||
|
||||
//
|
||||
// Clean up the current Ia.
|
||||
//
|
||||
if (Instance->IaCb.Ia != NULL) {
|
||||
if (Instance->IaCb.Ia->ReplyPacket != NULL) {
|
||||
FreePool (Instance->IaCb.Ia->ReplyPacket);
|
||||
}
|
||||
FreePool (Instance->IaCb.Ia);
|
||||
}
|
||||
|
||||
if (Instance->Unicast != NULL) {
|
||||
FreePool (Instance->Unicast);
|
||||
}
|
||||
|
||||
if (Instance->AdSelect != NULL) {
|
||||
FreePool (Instance->AdSelect);
|
||||
}
|
||||
|
||||
FreePool (Instance);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Create the Dhcp6 instance and initialize it.
|
||||
|
||||
@param[in] Service The pointer to the Dhcp6 service.
|
||||
@param[out] Instance The pointer to the Dhcp6 instance.
|
||||
|
||||
@retval EFI_SUCCESS The Dhcp6 instance is created.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6CreateInstance (
|
||||
IN DHCP6_SERVICE *Service,
|
||||
OUT DHCP6_INSTANCE **Instance
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DHCP6_INSTANCE *Dhcp6Ins;
|
||||
|
||||
*Instance = NULL;
|
||||
Dhcp6Ins = AllocateZeroPool (sizeof (DHCP6_INSTANCE));
|
||||
|
||||
if (Dhcp6Ins == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the fields of the new Dhcp6 instance.
|
||||
//
|
||||
Dhcp6Ins->Signature = DHCP6_INSTANCE_SIGNATURE;
|
||||
Dhcp6Ins->UdpSts = EFI_ALREADY_STARTED;
|
||||
Dhcp6Ins->Service = Service;
|
||||
Dhcp6Ins->InDestroy = FALSE;
|
||||
Dhcp6Ins->MediaPresent = TRUE;
|
||||
|
||||
CopyMem (
|
||||
&Dhcp6Ins->Dhcp6,
|
||||
&gDhcp6ProtocolTemplate,
|
||||
sizeof (EFI_DHCP6_PROTOCOL)
|
||||
);
|
||||
|
||||
InitializeListHead (&Dhcp6Ins->TxList);
|
||||
InitializeListHead (&Dhcp6Ins->InfList);
|
||||
|
||||
//
|
||||
// There is a timer for each Dhcp6 instance, which is used to track the
|
||||
// lease time of Ia and the retransmisson time of all sent packets.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL | EVT_TIMER,
|
||||
TPL_CALLBACK,
|
||||
Dhcp6OnTimerTick,
|
||||
Dhcp6Ins,
|
||||
&Dhcp6Ins->Timer
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
FreePool (Dhcp6Ins);
|
||||
return Status;
|
||||
}
|
||||
|
||||
*Instance = Dhcp6Ins;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Callback function which provided by user to remove one node in NetDestroyLinkList process.
|
||||
|
||||
@param[in] Entry The entry to be removed.
|
||||
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been removed successfully.
|
||||
@retval Others Fail to remove the entry.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DestroyChildEntry (
|
||||
IN LIST_ENTRY *Entry,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
DHCP6_INSTANCE *Instance;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
|
||||
if (Entry == NULL || Context == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP6_INSTANCE, Link, DHCP6_INSTANCE_SIGNATURE);
|
||||
ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
|
||||
|
||||
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Entry point of the DHCP6 driver to install various protocols.
|
||||
|
||||
@param[in] ImageHandle The handle of the UEFI image file.
|
||||
@param[in] SystemTable The pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval Others Unexpected error occurs.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
return EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gDhcp6DriverBinding,
|
||||
ImageHandle,
|
||||
&gDhcp6ComponentName,
|
||||
&gDhcp6ComponentName2
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle. This service
|
||||
is called by the EFI boot service ConnectController(). In
|
||||
order to make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. ConnectController() must
|
||||
follow these calling restrictions. If any other agent wishes to call
|
||||
Supported() it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This The pointer to the driver binding protocol.
|
||||
@param[in] ControllerHandle The handle of device to be tested.
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to be started.
|
||||
|
||||
@retval EFI_SUCCESS This driver supports this device.
|
||||
@retval Others This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
return gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiUdp6ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service ConnectController(). In order to make
|
||||
drivers as small as possible, there are a few calling restrictions for
|
||||
this service. ConnectController() must follow these
|
||||
calling restrictions. If any other agent wishes to call Start() it
|
||||
must also follow these calling restrictions.
|
||||
|
||||
@param[in] This The pointer to the driver binding protocol.
|
||||
@param[in] ControllerHandle The handle of device to be started.
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to be started.
|
||||
|
||||
@retval EFI_SUCCESS This driver is installed to ControllerHandle.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DHCP6_SERVICE *Service;
|
||||
|
||||
//
|
||||
// Check the Dhcp6 serivce whether already started.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiDhcp6ServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Create and initialize the Dhcp6 service.
|
||||
//
|
||||
Status = Dhcp6CreateService (
|
||||
ControllerHandle,
|
||||
This->DriverBindingHandle,
|
||||
&Service
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (Service != NULL);
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiDhcp6ServiceBindingProtocolGuid,
|
||||
&Service->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Dhcp6DestroyService (Service);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service DisconnectController(). In order to
|
||||
make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. DisconnectController()
|
||||
must follow these calling restrictions. If any other agent wishes
|
||||
to call Stop() it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to stop driver on
|
||||
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
|
||||
children is zero stop the entire bus driver.
|
||||
@param[in] ChildHandleBuffer List of Child Handles to Stop.
|
||||
|
||||
@retval EFI_SUCCESS This driver is removed ControllerHandle
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
@retval other This driver was not removed from this device
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
DHCP6_SERVICE *Service;
|
||||
LIST_ENTRY *List;
|
||||
UINTN ListLength;
|
||||
|
||||
//
|
||||
// Find and check the Nic handle by the controller handle.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);
|
||||
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiDhcp6ServiceBindingProtocolGuid,
|
||||
(VOID **) &ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
NicHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Service = DHCP6_SERVICE_FROM_THIS (ServiceBinding);
|
||||
if (!IsListEmpty (&Service->Child)) {
|
||||
//
|
||||
// Destroy all the children instances before destory the service.
|
||||
//
|
||||
List = &Service->Child;
|
||||
Status = NetDestroyLinkList (
|
||||
List,
|
||||
Dhcp6DestroyChildEntry,
|
||||
ServiceBinding,
|
||||
&ListLength
|
||||
);
|
||||
if (EFI_ERROR (Status) || ListLength != 0) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (NumberOfChildren == 0 && !IsListEmpty (&Service->Child)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (NumberOfChildren == 0 && IsListEmpty (&Service->Child)) {
|
||||
//
|
||||
// Destroy the service itself if no child instance left.
|
||||
//
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
NicHandle,
|
||||
&gEfiDhcp6ServiceBindingProtocolGuid,
|
||||
ServiceBinding
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Dhcp6DestroyService (Service);
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param[in, out] ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing
|
||||
UEFI handle, then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval other The child handle was not created.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN OUT EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
DHCP6_SERVICE *Service;
|
||||
DHCP6_INSTANCE *Instance;
|
||||
VOID *Udp6;
|
||||
|
||||
if (This == NULL || ChildHandle == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Service = DHCP6_SERVICE_FROM_THIS (This);
|
||||
|
||||
Status = Dhcp6CreateInstance (Service, &Instance);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (Instance != NULL);
|
||||
|
||||
//
|
||||
// Start the timer when the instance is ready to use.
|
||||
//
|
||||
Status = gBS->SetTimer (
|
||||
Instance->Timer,
|
||||
TimerPeriodic,
|
||||
TICKS_PER_SECOND
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the DHCP6 protocol onto ChildHandle.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiDhcp6ProtocolGuid,
|
||||
&Instance->Dhcp6,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Instance->Handle = *ChildHandle;
|
||||
|
||||
//
|
||||
// Open the UDP6 protocol BY_CHILD.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
Service->UdpIo->UdpHandle,
|
||||
&gEfiUdp6ProtocolGuid,
|
||||
(VOID **) &Udp6,
|
||||
gDhcp6DriverBinding.DriverBindingHandle,
|
||||
Instance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
Instance->Handle,
|
||||
&gEfiDhcp6ProtocolGuid,
|
||||
&Instance->Dhcp6,
|
||||
NULL
|
||||
);
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Add into the children list of its parent service.
|
||||
//
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
InsertTailList (&Service->Child, &Instance->Link);
|
||||
Service->NumOfChild++;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
|
||||
Dhcp6DestroyInstance (Instance);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param[in] ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
EFI_DHCP6_PROTOCOL *Dhcp6;
|
||||
DHCP6_SERVICE *Service;
|
||||
DHCP6_INSTANCE *Instance;
|
||||
|
||||
if (This == NULL || ChildHandle == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the private context data structures
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiDhcp6ProtocolGuid,
|
||||
(VOID **) &Dhcp6,
|
||||
gDhcp6DriverBinding.DriverBindingHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Instance = DHCP6_INSTANCE_FROM_THIS (Dhcp6);
|
||||
Service = DHCP6_SERVICE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Service != Service) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Instance->InDestroy) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
Instance->InDestroy = TRUE;
|
||||
|
||||
Status = gBS->CloseProtocol (
|
||||
Service->UdpIo->UdpHandle,
|
||||
&gEfiUdp6ProtocolGuid,
|
||||
gDhcp6DriverBinding.DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Instance->InDestroy = FALSE;
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Uninstall the MTFTP6 protocol first to enable a top down destruction.
|
||||
//
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
ChildHandle,
|
||||
&gEfiDhcp6ProtocolGuid,
|
||||
Dhcp6
|
||||
);
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Instance->InDestroy = FALSE;
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Remove it from the children list of its parent service.
|
||||
//
|
||||
RemoveEntryList (&Instance->Link);
|
||||
Service->NumOfChild--;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
Dhcp6DestroyInstance (Instance);
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/** @file
|
||||
Driver Binding functions and Service Binding functions
|
||||
declaration for Dhcp6 Driver.
|
||||
|
||||
Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP6_DRIVER_H__
|
||||
#define __EFI_DHCP6_DRIVER_H__
|
||||
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gDhcp6ComponentName;
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gDhcp6ComponentName2;
|
||||
extern EFI_UNICODE_STRING_TABLE *gDhcp6ControllerNameTable;
|
||||
|
||||
/**
|
||||
Test to see if this driver supports ControllerHandle. This service
|
||||
is called by the EFI boot service ConnectController(). In
|
||||
order to make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. ConnectController() must
|
||||
follow these calling restrictions. If any other agent wishes to call
|
||||
Supported(), it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to test.
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCESS This driver supports this device.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on this device.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service ConnectController(). In order to make
|
||||
drivers as small as possible, there are a few calling restrictions for
|
||||
this service. ConnectController() must follow these
|
||||
calling restrictions. If any other agent wishes to call Start(), it
|
||||
must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to bind driver to.
|
||||
@param[in] RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCESS This driver is added to ControllerHandle.
|
||||
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
|
||||
@retval other This driver does not support this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle. This service is called by the
|
||||
EFI boot service DisconnectController(). In order to
|
||||
make drivers as small as possible, there are a few calling
|
||||
restrictions for this service. DisconnectController()
|
||||
must follow these calling restrictions. If any other agent wishes
|
||||
to call Stop() it must also follow these calling restrictions.
|
||||
|
||||
@param[in] This Protocol instance pointer.
|
||||
@param[in] ControllerHandle Handle of device to stop driver on.
|
||||
@param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
|
||||
children is zero, stop the entire bus driver.
|
||||
@param[in] ChildHandleBuffer List of Child Handles to Stop.
|
||||
|
||||
@retval EFI_SUCCESS This driver is removed ControllerHandle.
|
||||
@retval other This driver was not removed from this device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||
then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child.
|
||||
@retval other The child handle was not created.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN OUT EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy.
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp6ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
## @file
|
||||
# Client-side DHCPv6 services.
|
||||
#
|
||||
# This driver produces EFI DHCPv6 Protocol which is used to get IPv6 addresses
|
||||
# and other configuration parameters from DHCPv6 servers.
|
||||
#
|
||||
# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
|
||||
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Dhcp6Dxe
|
||||
FILE_GUID = 95E3669D-34BE-4775-A651-7EA41B69D89E
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = Dhcp6DriverEntryPoint
|
||||
UNLOAD_IMAGE = NetLibDefaultUnload
|
||||
MODULE_UNI_FILE = Dhcp6Dxe.uni
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 EBC
|
||||
#
|
||||
# DRIVER_BINDING = gDhcp6DriverBinding
|
||||
# COMPONENT_NAME = gDhcp6ComponentName
|
||||
# COMPONENT_NAME2 = gDhcp6ComponentName2
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Dhcp6Driver.c
|
||||
Dhcp6Driver.h
|
||||
Dhcp6Impl.c
|
||||
Dhcp6Impl.h
|
||||
Dhcp6Io.c
|
||||
Dhcp6Io.h
|
||||
Dhcp6Utility.c
|
||||
Dhcp6Utility.h
|
||||
ComponentName.c
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
NetworkPkg/NetworkPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiLib
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
UefiRuntimeServicesTableLib
|
||||
DebugLib
|
||||
NetLib
|
||||
UdpIoLib
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiUdp6ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiUdp6ProtocolGuid ## TO_START
|
||||
gEfiDhcp6ServiceBindingProtocolGuid ## BY_START
|
||||
gEfiDhcp6ProtocolGuid ## BY_START
|
||||
gEfiIp6ConfigProtocolGuid ## TO_START
|
||||
|
||||
[Guids]
|
||||
gZeroGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
|
||||
[Pcd]
|
||||
gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType ## SOMETIMES_CONSUMES
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
Dhcp6DxeExtra.uni
|
|
@ -0,0 +1,17 @@
|
|||
// /** @file
|
||||
// Client-side DHCPv6 services.
|
||||
//
|
||||
// This driver produces EFI DHCPv6 Protocol which is used to get IPv6 addresses
|
||||
// and other configuration parameters from DHCPv6 servers.
|
||||
//
|
||||
// Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "Client-side DHCPv6 services"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This driver produces EFI DHCPv6 Protocol which is used to get IPv6 addresses and other configuration parameters from DHCPv6 servers."
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// /** @file
|
||||
// Dhcp6Dxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"DHCP6 DXE"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,479 @@
|
|||
/** @file
|
||||
Dhcp6 internal data structure and definition declaration.
|
||||
|
||||
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP6_IMPL_H__
|
||||
#define __EFI_DHCP6_IMPL_H__
|
||||
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <IndustryStandard/Dhcp.h>
|
||||
|
||||
#include <Protocol/Dhcp6.h>
|
||||
#include <Protocol/Udp6.h>
|
||||
#include <Protocol/Ip6Config.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
#include <Protocol/DriverBinding.h>
|
||||
|
||||
#include <Library/UdpIoLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Guid/ZeroGuid.h>
|
||||
|
||||
|
||||
typedef struct _DHCP6_IA_CB DHCP6_IA_CB;
|
||||
typedef struct _DHCP6_INF_CB DHCP6_INF_CB;
|
||||
typedef struct _DHCP6_TX_CB DHCP6_TX_CB;
|
||||
typedef struct _DHCP6_SERVICE DHCP6_SERVICE;
|
||||
typedef struct _DHCP6_INSTANCE DHCP6_INSTANCE;
|
||||
|
||||
#include "Dhcp6Utility.h"
|
||||
#include "Dhcp6Io.h"
|
||||
#include "Dhcp6Driver.h"
|
||||
|
||||
#define DHCP6_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'S')
|
||||
#define DHCP6_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'H', '6', 'I')
|
||||
|
||||
#define DHCP6_PACKET_ALL 0
|
||||
#define DHCP6_PACKET_STATEFUL 1
|
||||
#define DHCP6_PACKET_STATELESS 2
|
||||
|
||||
#define DHCP6_BASE_PACKET_SIZE 1024
|
||||
|
||||
#define DHCP6_PORT_CLIENT 546
|
||||
#define DHCP6_PORT_SERVER 547
|
||||
|
||||
#define DHCP_CHECK_MEDIA_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)
|
||||
|
||||
#define DHCP6_INSTANCE_FROM_THIS(Instance) CR ((Instance), DHCP6_INSTANCE, Dhcp6, DHCP6_INSTANCE_SIGNATURE)
|
||||
#define DHCP6_SERVICE_FROM_THIS(Service) CR ((Service), DHCP6_SERVICE, ServiceBinding, DHCP6_SERVICE_SIGNATURE)
|
||||
|
||||
extern EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress;
|
||||
extern EFI_DHCP6_PROTOCOL gDhcp6ProtocolTemplate;
|
||||
|
||||
//
|
||||
// Control block for each IA.
|
||||
//
|
||||
struct _DHCP6_IA_CB {
|
||||
EFI_DHCP6_IA *Ia;
|
||||
UINT32 T1;
|
||||
UINT32 T2;
|
||||
UINT32 AllExpireTime;
|
||||
UINT32 LeaseTime;
|
||||
};
|
||||
|
||||
//
|
||||
// Control block for each transmitted message.
|
||||
//
|
||||
struct _DHCP6_TX_CB {
|
||||
LIST_ENTRY Link;
|
||||
UINT32 Xid;
|
||||
EFI_DHCP6_PACKET *TxPacket;
|
||||
EFI_DHCP6_RETRANSMISSION RetryCtl;
|
||||
UINT32 RetryCnt;
|
||||
UINT32 RetryExp;
|
||||
UINT32 RetryLos;
|
||||
UINT32 TickTime;
|
||||
UINT16 *Elapsed;
|
||||
BOOLEAN SolicitRetry;
|
||||
};
|
||||
|
||||
//
|
||||
// Control block for each info-request message.
|
||||
//
|
||||
struct _DHCP6_INF_CB {
|
||||
LIST_ENTRY Link;
|
||||
UINT32 Xid;
|
||||
EFI_DHCP6_INFO_CALLBACK ReplyCallback;
|
||||
VOID *CallbackContext;
|
||||
EFI_EVENT TimeoutEvent;
|
||||
};
|
||||
|
||||
//
|
||||
// Control block for Dhcp6 instance, it's per configuration data.
|
||||
//
|
||||
struct _DHCP6_INSTANCE {
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE Handle;
|
||||
DHCP6_SERVICE *Service;
|
||||
LIST_ENTRY Link;
|
||||
EFI_DHCP6_PROTOCOL Dhcp6;
|
||||
EFI_EVENT Timer;
|
||||
EFI_DHCP6_CONFIG_DATA *Config;
|
||||
EFI_DHCP6_IA *CacheIa;
|
||||
DHCP6_IA_CB IaCb;
|
||||
LIST_ENTRY TxList;
|
||||
LIST_ENTRY InfList;
|
||||
EFI_DHCP6_PACKET *AdSelect;
|
||||
UINT8 AdPref;
|
||||
EFI_IPv6_ADDRESS *Unicast;
|
||||
volatile EFI_STATUS UdpSts;
|
||||
BOOLEAN InDestroy;
|
||||
BOOLEAN MediaPresent;
|
||||
//
|
||||
// StartTime is used to calculate the 'elapsed-time' option. Refer to RFC3315,
|
||||
// the elapsed-time is amount of time since the client began its current DHCP transaction.
|
||||
//
|
||||
UINT64 StartTime;
|
||||
};
|
||||
|
||||
//
|
||||
// Control block for Dhcp6 service, it's per Nic handle.
|
||||
//
|
||||
struct _DHCP6_SERVICE {
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE Controller;
|
||||
EFI_HANDLE Image;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
|
||||
EFI_DHCP6_DUID *ClientId;
|
||||
UDP_IO *UdpIo;
|
||||
UINT32 Xid;
|
||||
LIST_ENTRY Child;
|
||||
UINTN NumOfChild;
|
||||
};
|
||||
|
||||
/**
|
||||
Starts the DHCPv6 standard S.A.R.R. process.
|
||||
|
||||
The Start() function starts the DHCPv6 standard process. This function can
|
||||
be called only when the state of Dhcp6 instance is in the Dhcp6Init state.
|
||||
If the DHCP process completes successfully, the state of the Dhcp6 instance
|
||||
will be transferred through Dhcp6Selecting and Dhcp6Requesting to the
|
||||
Dhcp6Bound state.
|
||||
Refer to rfc-3315 for precise state transitions during this process. At the
|
||||
time when each event occurs in this process, the callback function that was set
|
||||
by EFI_DHCP6_PROTOCOL.Configure() will be called and the user can take this
|
||||
opportunity to control the process.
|
||||
|
||||
@param[in] This The pointer to Dhcp6 protocol.
|
||||
|
||||
@retval EFI_SUCCESS The DHCPv6 standard process has started, or it
|
||||
completed when CompletionEvent was NULL.
|
||||
@retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_TIMEOUT The DHCPv6 configuration process failed because no
|
||||
response was received from the server within the
|
||||
specified timeout value.
|
||||
@retval EFI_ABORTED The user aborted the DHCPv6 process.
|
||||
@retval EFI_ALREADY_STARTED Some other Dhcp6 instance already started the DHCPv6
|
||||
standard process.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6Start (
|
||||
IN EFI_DHCP6_PROTOCOL *This
|
||||
);
|
||||
|
||||
/**
|
||||
Stops the DHCPv6 standard S.A.R.R. process.
|
||||
|
||||
The Stop() function is used to stop the DHCPv6 standard process. After this
|
||||
function is called successfully, the state of Dhcp6 instance is transferred
|
||||
into the Dhcp6Init. EFI_DHCP6_PROTOCOL.Configure() needs to be called
|
||||
before DHCPv6 standard process can be started again. This function can be
|
||||
called when the Dhcp6 instance is in any state.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol.
|
||||
|
||||
@retval EFI_SUCCESS The Dhcp6 instance is now in the Dhcp6Init state.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6Stop (
|
||||
IN EFI_DHCP6_PROTOCOL *This
|
||||
);
|
||||
|
||||
/**
|
||||
Returns the current operating mode data for the Dhcp6 instance.
|
||||
|
||||
The GetModeData() function returns the current operating mode and
|
||||
cached data packet for the Dhcp6 instance.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol.
|
||||
@param[out] Dhcp6ModeData The pointer to the Dhcp6 mode data.
|
||||
@param[out] Dhcp6ConfigData The pointer to the Dhcp6 configure data.
|
||||
|
||||
@retval EFI_SUCCESS The mode data was returned.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_ACCESS_DENIED The EFI DHCPv6 Protocol instance has not
|
||||
been configured when Dhcp6ConfigData is
|
||||
not NULL.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6GetModeData (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
OUT EFI_DHCP6_MODE_DATA *Dhcp6ModeData OPTIONAL,
|
||||
OUT EFI_DHCP6_CONFIG_DATA *Dhcp6ConfigData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Initializes, changes, or resets the operational settings for the Dhcp6 instance.
|
||||
|
||||
The Configure() function is used to initialize or clean up the configuration
|
||||
data of the Dhcp6 instance:
|
||||
- When Dhcp6CfgData is not NULL and Configure() is called successfully, the
|
||||
configuration data will be initialized in the Dhcp6 instance and the state
|
||||
of the configured IA will be transferred into Dhcp6Init.
|
||||
- When Dhcp6CfgData is NULL and Configure() is called successfully, the
|
||||
configuration data will be cleaned up and no IA will be associated with
|
||||
the Dhcp6 instance.
|
||||
To update the configuration data for an Dhcp6 instance, the original data
|
||||
must be cleaned up before setting the new configuration data.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol
|
||||
@param[in] Dhcp6CfgData The pointer to the EFI_DHCP6_CONFIG_DATA.
|
||||
|
||||
@retval EFI_SUCCESS The Dhcp6 is configured successfully with the
|
||||
Dhcp6Init state, or cleaned up the original
|
||||
configuration setting.
|
||||
@retval EFI_ACCESS_DENIED The Dhcp6 instance has been already configured
|
||||
when Dhcp6CfgData is not NULL.
|
||||
The Dhcp6 instance has already started the
|
||||
DHCPv6 S.A.R.R when Dhcp6CfgData is NULL.
|
||||
@retval EFI_INVALID_PARAMETER Some of the parameter is invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6Configure (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN EFI_DHCP6_CONFIG_DATA *Dhcp6CfgData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Request configuration information without the assignment of any
|
||||
Ia addresses of the client.
|
||||
|
||||
The InfoRequest() function is used to request configuration information
|
||||
without the assignment of any IPv6 address of the client. Client sends
|
||||
out Information Request packet to obtain the required configuration
|
||||
information, and DHCPv6 server responds with Reply packet containing
|
||||
the information for the client. The received Reply packet will be passed
|
||||
to the user by ReplyCallback function. If user returns EFI_NOT_READY from
|
||||
ReplyCallback, the Dhcp6 instance will continue to receive other Reply
|
||||
packets unless timeout according to the Retransmission parameter.
|
||||
Otherwise, the Information Request exchange process will be finished
|
||||
successfully if user returns EFI_SUCCESS from ReplyCallback.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol.
|
||||
@param[in] SendClientId If TRUE, the DHCPv6 protocol instance will build Client
|
||||
Identifier option and include it into Information Request
|
||||
packet. Otherwise, Client Identifier option will not be included.
|
||||
@param[in] OptionRequest The pointer to the buffer of option request options.
|
||||
@param[in] OptionCount The option number in the OptionList.
|
||||
@param[in] OptionList The list of appended options.
|
||||
@param[in] Retransmission The pointer to the retransmission of the message.
|
||||
@param[in] TimeoutEvent The event of timeout.
|
||||
@param[in] ReplyCallback The callback function when a reply was received.
|
||||
@param[in] CallbackContext The pointer to the parameter passed to the callback.
|
||||
|
||||
@retval EFI_SUCCESS The DHCPv6 information request exchange process
|
||||
completed when TimeoutEvent is NULL. Information
|
||||
Request packet has been sent to DHCPv6 server when
|
||||
TimeoutEvent is not NULL.
|
||||
@retval EFI_NO_RESPONSE The DHCPv6 information request exchange process failed
|
||||
because of no response, or not all requested-options
|
||||
are responded to by DHCPv6 servers when Timeout happened.
|
||||
@retval EFI_ABORTED The DHCPv6 information request exchange process was aborted
|
||||
by the user.
|
||||
@retval EFI_INVALID_PARAMETER Some parameter is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6InfoRequest (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN BOOLEAN SendClientId,
|
||||
IN EFI_DHCP6_PACKET_OPTION *OptionRequest,
|
||||
IN UINT32 OptionCount,
|
||||
IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL,
|
||||
IN EFI_DHCP6_RETRANSMISSION *Retransmission,
|
||||
IN EFI_EVENT TimeoutEvent OPTIONAL,
|
||||
IN EFI_DHCP6_INFO_CALLBACK ReplyCallback,
|
||||
IN VOID *CallbackContext OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Manually extend the valid and preferred lifetimes for the IPv6 addresses
|
||||
of the configured IA and update other configuration parameters by sending
|
||||
Renew or Rebind packet.
|
||||
|
||||
The RenewRebind() function is used to manually extend the valid and preferred
|
||||
lifetimes for the IPv6 addresses of the configured IA and update other
|
||||
configuration parameters by sending a Renew or Rebind packet.
|
||||
- When RebindRequest is FALSE and the state of the configured IA is Dhcp6Bound,
|
||||
it will send Renew packet to the previously DHCPv6 server and transfer the
|
||||
state of the configured IA to Dhcp6Renewing. If valid Reply packet received,
|
||||
the state transfers to Dhcp6Bound and the valid and preferred timer restarts.
|
||||
If fails, the state transfers to Dhcp6Bound but the timer continues.
|
||||
- When RebindRequest is TRUE and the state of the configured IA is Dhcp6Bound,
|
||||
it will send a Rebind packet. If a valid Reply packet is received, the state transfers
|
||||
to Dhcp6Bound, and the valid and preferred timer restarts. If it fails, the state
|
||||
transfers to Dhcp6Init, and the IA can't be used.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol.
|
||||
@param[in] RebindRequest If TRUE, Rebind packet will be sent and enter Dhcp6Rebinding state.
|
||||
Otherwise, Renew packet will be sent and enter Dhcp6Renewing state.
|
||||
|
||||
@retval EFI_SUCCESS The DHCPv6 renew/rebind exchange process
|
||||
completed and at least one IPv6 address of the
|
||||
configured IA was bound again when
|
||||
EFI_DHCP6_CONFIG_DATA.IaInfoEvent was NULL.
|
||||
The EFI DHCPv6 Protocol instance has sent Renew
|
||||
or Rebind packet when
|
||||
EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The Dhcp6 instance hasn't been configured, or the
|
||||
state of the configured IA is not in Dhcp6Bound.
|
||||
@retval EFI_ALREADY_STARTED The state of the configured IA has already entered
|
||||
Dhcp6Renewing when RebindRequest is FALSE.
|
||||
The state of the configured IA has already entered
|
||||
Dhcp6Rebinding when RebindRequest is TRUE.
|
||||
@retval EFI_ABORTED The DHCPv6 renew/rebind exchange process aborted
|
||||
by user.
|
||||
@retval EFI_NO_RESPONSE The DHCPv6 renew/rebind exchange process failed
|
||||
because of no response.
|
||||
@retval EFI_NO_MAPPING No IPv6 address has been bound to the configured
|
||||
IA after the DHCPv6 renew/rebind exchange process.
|
||||
@retval EFI_INVALID_PARAMETER Some parameter is NULL.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6RenewRebind (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN BOOLEAN RebindRequest
|
||||
);
|
||||
|
||||
/**
|
||||
Inform that one or more addresses assigned by a server are already
|
||||
in use by another node.
|
||||
|
||||
The Decline() function is used to manually decline the assignment of
|
||||
IPv6 addresses, which have been already used by another node. If all
|
||||
IPv6 addresses of the configured IA are declined through this function,
|
||||
the state of the IA will switch through Dhcp6Declining to Dhcp6Init.
|
||||
Otherwise, the state of the IA will restore to Dhcp6Bound after the
|
||||
declining process. The Decline() can only be called when the IA is in
|
||||
Dhcp6Bound state. If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL,
|
||||
this function is a blocking operation. It will return after the
|
||||
declining process finishes, or aborted by user.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol.
|
||||
@param[in] AddressCount The number of declining addresses.
|
||||
@param[in] Addresses The pointer to the buffer stored the declining
|
||||
addresses.
|
||||
|
||||
@retval EFI_SUCCESS The DHCPv6 decline exchange process completed
|
||||
when EFI_DHCP6_CONFIG_DATA.IaInfoEvent was NULL.
|
||||
The Dhcp6 instance has sent Decline packet when
|
||||
EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The Dhcp6 instance hasn't been configured, or the
|
||||
state of the configured IA is not in Dhcp6Bound.
|
||||
@retval EFI_ABORTED The DHCPv6 decline exchange process was aborted by the user.
|
||||
@retval EFI_NOT_FOUND Any specified IPv6 address is not correlated with
|
||||
the configured IA for this instance.
|
||||
@retval EFI_INVALID_PARAMETER Some parameter is NULL.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6Decline (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN UINT32 AddressCount,
|
||||
IN EFI_IPv6_ADDRESS *Addresses
|
||||
);
|
||||
|
||||
/**
|
||||
Release one or more addresses associated with the configured Ia
|
||||
for the current instance.
|
||||
|
||||
The Release() function is used to manually release the one or more
|
||||
IPv6 address. If AddressCount is zero, it will release all IPv6
|
||||
addresses of the configured IA. If all IPv6 addresses of the IA are
|
||||
released through this function, the state of the IA will switch
|
||||
through Dhcp6Releasing to Dhcp6Init, otherwise, the state of the
|
||||
IA will restore to Dhcp6Bound after the releasing process.
|
||||
The Release() can only be called when the IA is in a Dhcp6Bound state.
|
||||
If the EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the function is
|
||||
a blocking operation. It will return after the releasing process
|
||||
finishes, or aborted by user.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol.
|
||||
@param[in] AddressCount The number of releasing addresses.
|
||||
@param[in] Addresses The pointer to the buffer stored the releasing
|
||||
addresses.
|
||||
@retval EFI_SUCCESS The DHCPv6 release exchange process has
|
||||
completed when EFI_DHCP6_CONFIG_DATA.IaInfoEvent
|
||||
is NULL. The Dhcp6 instance has sent Release
|
||||
packet when EFI_DHCP6_CONFIG_DATA.IaInfoEvent
|
||||
is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The Dhcp6 instance hasn't been configured, or the
|
||||
state of the configured IA is not in Dhcp6Bound.
|
||||
@retval EFI_ABORTED The DHCPv6 release exchange process was aborted by the user.
|
||||
@retval EFI_NOT_FOUND Any specified IPv6 address is not correlated with
|
||||
the configured IA for this instance.
|
||||
@retval EFI_INVALID_PARAMETER Some parameter is NULL.
|
||||
@retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6Release (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN UINT32 AddressCount,
|
||||
IN EFI_IPv6_ADDRESS *Addresses
|
||||
);
|
||||
|
||||
/**
|
||||
Parse the option data in the Dhcp6 packet.
|
||||
|
||||
The Parse() function is used to retrieve the option list in the DHCPv6 packet.
|
||||
|
||||
@param[in] This The pointer to the Dhcp6 protocol.
|
||||
@param[in] Packet The pointer to the Dhcp6 packet.
|
||||
@param[in, out] OptionCount The number of option in the packet.
|
||||
@param[out] PacketOptionList The array of pointers to the each option in the packet.
|
||||
|
||||
@retval EFI_SUCCESS The packet was successfully parsed.
|
||||
@retval EFI_INVALID_PARAMETER Some parameter is NULL.
|
||||
@retval EFI_BUFFER_TOO_SMALL *OptionCount is smaller than the number of options
|
||||
that were found in the Packet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp6Parse (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN EFI_DHCP6_PACKET *Packet,
|
||||
IN OUT UINT32 *OptionCount,
|
||||
OUT EFI_DHCP6_PACKET_OPTION *PacketOptionList[] OPTIONAL
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,221 @@
|
|||
/** @file
|
||||
Dhcp6 internal functions declaration.
|
||||
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP6_IO_H__
|
||||
#define __EFI_DHCP6_IO_H__
|
||||
|
||||
|
||||
/**
|
||||
Clean up the specific nodes in the retry list.
|
||||
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
@param[in] Scope The scope of cleanup nodes.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6CleanupRetry (
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
IN UINT32 Scope
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up the session of the instance stateful exchange.
|
||||
|
||||
@param[in, out] Instance The pointer to the Dhcp6 instance.
|
||||
@param[in] Status The return status from udp.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6CleanupSession (
|
||||
IN OUT DHCP6_INSTANCE *Instance,
|
||||
IN EFI_STATUS Status
|
||||
);
|
||||
|
||||
/**
|
||||
Create the solicit message and send it.
|
||||
|
||||
@param[in] Instance The pointer to Dhcp6 instance.
|
||||
|
||||
@retval EFI_SUCCESS Create and send the solicit message successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval Others Failed to send the solicit message.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6SendSolicitMsg (
|
||||
IN DHCP6_INSTANCE *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Create the request message and send it.
|
||||
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
|
||||
@retval EFI_SUCCESS Create and send the request message successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_DEVICE_ERROR An unexpected error.
|
||||
@retval Others Failed to send the request message.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6SendRequestMsg (
|
||||
IN DHCP6_INSTANCE *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Create the renew/rebind message and send it.
|
||||
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
@param[in] RebindRequest If TRUE, it is a Rebind type message.
|
||||
Otherwise, it is a Renew type message.
|
||||
|
||||
@retval EFI_SUCCESS Create and send the renew/rebind message successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_DEVICE_ERROR An unexpected error.
|
||||
@retval Others Failed to send the renew/rebind message.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6SendRenewRebindMsg (
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
IN BOOLEAN RebindRequest
|
||||
);
|
||||
|
||||
/**
|
||||
Create the decline message and send it.
|
||||
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
@param[in] DecIa The pointer to the decline Ia.
|
||||
|
||||
@retval EFI_SUCCESS Create and send the decline message successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_DEVICE_ERROR An unexpected error.
|
||||
@retval Others Failed to send the decline message.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6SendDeclineMsg (
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
IN EFI_DHCP6_IA *DecIa
|
||||
);
|
||||
|
||||
/**
|
||||
Create the release message and send it.
|
||||
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
@param[in] RelIa The pointer to the release Ia.
|
||||
|
||||
@retval EFI_SUCCESS Create and send the release message successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_DEVICE_ERROR An unexpected error.
|
||||
@retval Others Failed to send the release message.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6SendReleaseMsg (
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
IN EFI_DHCP6_IA *RelIa
|
||||
);
|
||||
|
||||
/**
|
||||
Start the information request process.
|
||||
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
@param[in] SendClientId If TRUE, the client identifier option will be included in
|
||||
information request message. Otherwise, the client identifier
|
||||
option will not be included.
|
||||
@param[in] OptionRequest The pointer to the option request option.
|
||||
@param[in] OptionCount The number options in the OptionList.
|
||||
@param[in] OptionList The array pointers to the appended options.
|
||||
@param[in] Retransmission The pointer to the retransmission control.
|
||||
@param[in] TimeoutEvent The event of timeout.
|
||||
@param[in] ReplyCallback The callback function when the reply was received.
|
||||
@param[in] CallbackContext The pointer to the parameter passed to the callback.
|
||||
|
||||
@retval EFI_SUCCESS Start the info-request process successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_NO_MAPPING No source address is available for use.
|
||||
@retval Others Failed to start the info-request process.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6StartInfoRequest (
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
IN BOOLEAN SendClientId,
|
||||
IN EFI_DHCP6_PACKET_OPTION *OptionRequest,
|
||||
IN UINT32 OptionCount,
|
||||
IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL,
|
||||
IN EFI_DHCP6_RETRANSMISSION *Retransmission,
|
||||
IN EFI_EVENT TimeoutEvent OPTIONAL,
|
||||
IN EFI_DHCP6_INFO_CALLBACK ReplyCallback,
|
||||
IN VOID *CallbackContext OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Create the information request message and send it.
|
||||
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
@param[in] InfCb The pointer to the information request control block.
|
||||
@param[in] SendClientId If TRUE, the client identifier option will be included in
|
||||
information request message. Otherwise, the client identifier
|
||||
option will not be included.
|
||||
@param[in] OptionRequest The pointer to the option request option.
|
||||
@param[in] OptionCount The number options in the OptionList.
|
||||
@param[in] OptionList The array pointers to the appended options.
|
||||
@param[in] Retransmission The pointer to the retransmission control.
|
||||
|
||||
@retval EFI_SUCCESS Create and send the info-request message successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval Others Failed to send the info-request message.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6SendInfoRequestMsg (
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
IN DHCP6_INF_CB *InfCb,
|
||||
IN BOOLEAN SendClientId,
|
||||
IN EFI_DHCP6_PACKET_OPTION *OptionRequest,
|
||||
IN UINT32 OptionCount,
|
||||
IN EFI_DHCP6_PACKET_OPTION *OptionList[],
|
||||
IN EFI_DHCP6_RETRANSMISSION *Retransmission
|
||||
);
|
||||
|
||||
/**
|
||||
The receive callback function for the Dhcp6 exchange process.
|
||||
|
||||
@param[in] Udp6Wrap The pointer to the received net buffer.
|
||||
@param[in] EndPoint The pointer to the udp end point.
|
||||
@param[in] IoStatus The return status from udp io.
|
||||
@param[in] Context The opaque parameter to the function.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
Dhcp6ReceivePacket (
|
||||
IN NET_BUF *Udp6Wrap,
|
||||
IN UDP_END_POINT *EndPoint,
|
||||
IN EFI_STATUS IoStatus,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
The timer routine of the Dhcp6 instance for each second.
|
||||
|
||||
@param[in] Event The timer event.
|
||||
@param[in] Context The opaque parameter to the function.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
Dhcp6OnTimerTick (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,354 @@
|
|||
/** @file
|
||||
Dhcp6 support functions declaration.
|
||||
|
||||
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP6_UTILITY_H__
|
||||
#define __EFI_DHCP6_UTILITY_H__
|
||||
|
||||
|
||||
#define DHCP6_10_BIT_MASK 0x3ff
|
||||
#define DHCP6_DAD_ADDITIONAL_DELAY 30000000 // 3 seconds
|
||||
|
||||
/**
|
||||
Generate client Duid in the format of Duid-llt.
|
||||
|
||||
@param[in] Mode The pointer to the mode of SNP.
|
||||
|
||||
@retval NULL if failed to generate client Id.
|
||||
@retval Others The pointer to the new client id.
|
||||
|
||||
**/
|
||||
EFI_DHCP6_DUID *
|
||||
Dhcp6GenerateClientId (
|
||||
IN EFI_SIMPLE_NETWORK_MODE *Mode
|
||||
);
|
||||
|
||||
/**
|
||||
Copy the Dhcp6 configure data.
|
||||
|
||||
@param[in] DstCfg The pointer to the destination configure data.
|
||||
@param[in] SorCfg The pointer to the source configure data.
|
||||
|
||||
@retval EFI_SUCCESS Copy the content from SorCfg from DstCfg successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6CopyConfigData (
|
||||
IN EFI_DHCP6_CONFIG_DATA *DstCfg,
|
||||
IN EFI_DHCP6_CONFIG_DATA *SorCfg
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up the configure data.
|
||||
|
||||
@param[in, out] CfgData The pointer to the configure data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6CleanupConfigData (
|
||||
IN OUT EFI_DHCP6_CONFIG_DATA *CfgData
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up the mode data.
|
||||
|
||||
@param[in, out] ModeData The pointer to the mode data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6CleanupModeData (
|
||||
IN OUT EFI_DHCP6_MODE_DATA *ModeData
|
||||
);
|
||||
|
||||
/**
|
||||
Calculate the expire time by the algorithm defined in rfc.
|
||||
|
||||
@param[in] Base The base value of the time.
|
||||
@param[in] IsFirstRt If TRUE, it is the first time to calculate expire time.
|
||||
@param[in] NeedSigned If TRUE, the the signed factor is needed.
|
||||
|
||||
@return Expire The calculated result for the new expire time.
|
||||
|
||||
**/
|
||||
UINT32
|
||||
Dhcp6CalculateExpireTime (
|
||||
IN UINT32 Base,
|
||||
IN BOOLEAN IsFirstRt,
|
||||
IN BOOLEAN NeedSigned
|
||||
);
|
||||
|
||||
/**
|
||||
Calculate the lease time by the algorithm defined in rfc.
|
||||
|
||||
@param[in] IaCb The pointer to the Ia control block.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6CalculateLeaseTime (
|
||||
IN DHCP6_IA_CB *IaCb
|
||||
);
|
||||
|
||||
/**
|
||||
Check whether the addresses are all included by the configured Ia.
|
||||
|
||||
@param[in] Ia The pointer to the Ia.
|
||||
@param[in] AddressCount The number of addresses.
|
||||
@param[in] Addresses The pointer to the addresses buffer.
|
||||
|
||||
@retval EFI_SUCCESS The addresses are all included by the configured IA.
|
||||
@retval EFI_NOT_FOUND The addresses are not included by the configured IA.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6CheckAddress (
|
||||
IN EFI_DHCP6_IA *Ia,
|
||||
IN UINT32 AddressCount,
|
||||
IN EFI_IPv6_ADDRESS *Addresses
|
||||
);
|
||||
|
||||
/**
|
||||
Deprive the addresses from current Ia, and generate another eliminated Ia.
|
||||
|
||||
@param[in] Ia The pointer to the Ia.
|
||||
@param[in] AddressCount The number of addresses.
|
||||
@param[in] Addresses The pointer to the addresses buffer.
|
||||
|
||||
@retval NULL If failed to generate the deprived Ia.
|
||||
@retval others The pointer to the deprived Ia.
|
||||
|
||||
**/
|
||||
EFI_DHCP6_IA *
|
||||
Dhcp6DepriveAddress (
|
||||
IN EFI_DHCP6_IA *Ia,
|
||||
IN UINT32 AddressCount,
|
||||
IN EFI_IPv6_ADDRESS *Addresses
|
||||
);
|
||||
|
||||
/**
|
||||
The dummy ext buffer free callback routine.
|
||||
|
||||
@param[in] Arg The pointer to the parameter.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
Dhcp6DummyExtFree (
|
||||
IN VOID *Arg
|
||||
);
|
||||
|
||||
/**
|
||||
The callback routine once message transmitted.
|
||||
|
||||
@param[in] Wrap The pointer to the received net buffer.
|
||||
@param[in] EndPoint The pointer to the udp end point.
|
||||
@param[in] IoStatus The return status from udp io.
|
||||
@param[in] Context The opaque parameter to the function.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
Dhcp6OnTransmitted (
|
||||
IN NET_BUF *Wrap,
|
||||
IN UDP_END_POINT *EndPoint,
|
||||
IN EFI_STATUS IoStatus,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Append the appointed option to the buf, and move the buf to the end.
|
||||
|
||||
@param[in, out] Buf The pointer to buffer.
|
||||
@param[in] OptType The option type.
|
||||
@param[in] OptLen The lenght of option content.s
|
||||
@param[in] Data The pointer to the option content.
|
||||
|
||||
@return Buf The position to append the next option.
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
Dhcp6AppendOption (
|
||||
IN OUT UINT8 *Buf,
|
||||
IN UINT16 OptType,
|
||||
IN UINT16 OptLen,
|
||||
IN UINT8 *Data
|
||||
);
|
||||
|
||||
/**
|
||||
Append the Ia option to Buf, and move Buf to the end.
|
||||
|
||||
@param[in, out] Buf The pointer to the position to append.
|
||||
@param[in] Ia The pointer to the Ia.
|
||||
@param[in] T1 The time of T1.
|
||||
@param[in] T2 The time of T2.
|
||||
@param[in] MessageType Message type of DHCP6 package.
|
||||
|
||||
@return Buf The position to append the next Ia option.
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
Dhcp6AppendIaOption (
|
||||
IN OUT UINT8 *Buf,
|
||||
IN EFI_DHCP6_IA *Ia,
|
||||
IN UINT32 T1,
|
||||
IN UINT32 T2,
|
||||
IN UINT32 MessageType
|
||||
);
|
||||
|
||||
/**
|
||||
Append the appointed Elapsed time option to Buf, and move Buf to the end.
|
||||
|
||||
@param[in, out] Buf The pointer to the position to append.
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
@param[out] Elapsed The pointer to the elapsed time value in
|
||||
the generated packet.
|
||||
|
||||
@return Buf The position to append the next Ia option.
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
Dhcp6AppendETOption (
|
||||
IN OUT UINT8 *Buf,
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
OUT UINT16 **Elapsed
|
||||
);
|
||||
|
||||
/**
|
||||
Set the elapsed time based on the given instance and the pointer to the
|
||||
elapsed time option.
|
||||
|
||||
@param[in] Elapsed The pointer to the position to append.
|
||||
@param[in] Instance The pointer to the Dhcp6 instance.
|
||||
**/
|
||||
VOID
|
||||
SetElapsedTime (
|
||||
IN UINT16 *Elapsed,
|
||||
IN DHCP6_INSTANCE *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Seek the address of the first byte of the option header.
|
||||
|
||||
@param[in] Buf The pointer to buffer.
|
||||
@param[in] SeekLen The length to seek.
|
||||
@param[in] OptType The option type.
|
||||
|
||||
@retval NULL If failed to seek the option.
|
||||
@retval others The position to the option.
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
Dhcp6SeekOption (
|
||||
IN UINT8 *Buf,
|
||||
IN UINT32 SeekLen,
|
||||
IN UINT16 OptType
|
||||
);
|
||||
|
||||
/**
|
||||
Seek the address of the first byte of the Ia option header.
|
||||
|
||||
@param[in] Buf The pointer to the buffer.
|
||||
@param[in] SeekLen The length to seek.
|
||||
@param[in] IaDesc The pointer to the Ia descriptor.
|
||||
|
||||
@retval NULL If failed to seek the Ia option.
|
||||
@retval others The position to the Ia option.
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
Dhcp6SeekIaOption (
|
||||
IN UINT8 *Buf,
|
||||
IN UINT32 SeekLen,
|
||||
IN EFI_DHCP6_IA_DESCRIPTOR *IaDesc
|
||||
);
|
||||
|
||||
/**
|
||||
Parse the address option and update the address info.
|
||||
|
||||
@param[in] CurrentIa The pointer to the Ia Address in control blcok.
|
||||
@param[in] IaInnerOpt The pointer to the buffer.
|
||||
@param[in] IaInnerLen The length to parse.
|
||||
@param[out] AddrNum The number of addresses.
|
||||
@param[in, out] AddrBuf The pointer to the address buffer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6ParseAddrOption (
|
||||
IN EFI_DHCP6_IA *CurrentIa,
|
||||
IN UINT8 *IaInnerOpt,
|
||||
IN UINT16 IaInnerLen,
|
||||
OUT UINT32 *AddrNum,
|
||||
IN OUT EFI_DHCP6_IA_ADDRESS *AddrBuf
|
||||
);
|
||||
|
||||
/**
|
||||
Create a control blcok for the Ia according to the corresponding options.
|
||||
|
||||
@param[in] Instance The pointer to DHCP6 Instance.
|
||||
@param[in] IaInnerOpt The pointer to the inner options in the Ia option.
|
||||
@param[in] IaInnerLen The length of all the inner options in the Ia option.
|
||||
@param[in] T1 T1 time in the Ia option.
|
||||
@param[in] T2 T2 time in the Ia option.
|
||||
|
||||
@retval EFI_NOT_FOUND No valid IA option is found.
|
||||
@retval EFI_SUCCESS Create an IA control block successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
@retval EFI_DEVICE_ERROR An unexpected error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6GenerateIaCb (
|
||||
IN DHCP6_INSTANCE *Instance,
|
||||
IN UINT8 *IaInnerOpt,
|
||||
IN UINT16 IaInnerLen,
|
||||
IN UINT32 T1,
|
||||
IN UINT32 T2
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Cache the current IA configuration information.
|
||||
|
||||
@param[in] Instance The pointer to DHCP6 Instance.
|
||||
|
||||
@retval EFI_SUCCESS Cache the current IA successfully.
|
||||
@retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6CacheIa (
|
||||
IN DHCP6_INSTANCE *Instance
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Append CacheIa to the currrent IA. Meanwhile, clear CacheIa.ValidLifetime to 0.
|
||||
|
||||
@param[in] Instance The pointer to DHCP6 instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
Dhcp6AppendCacheIa (
|
||||
IN DHCP6_INSTANCE *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Calculate the Dhcp6 get mapping timeout by adding additinal delay to the IP6 DAD transmits count.
|
||||
|
||||
@param[in] Ip6Cfg The pointer to Ip6 config protocol.
|
||||
@param[out] TimeOut The time out value in 100ns units.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Input parameters are invalid.
|
||||
@retval EFI_SUCCESS Calculate the time out value successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp6GetMappingTimeOut (
|
||||
IN EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg,
|
||||
OUT UINTN *TimeOut
|
||||
);
|
||||
#endif
|
|
@ -0,0 +1,451 @@
|
|||
/** @file
|
||||
Implementation of EFI_COMPONENT_NAME_PROTOCOL and EFI_COMPONENT_NAME2_PROTOCOL protocol.
|
||||
|
||||
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "DnsImpl.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param Language A pointer to a three-character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
@param DriverName A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param ControllerHandle The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
@param ChildHandle The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
@param Language A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
@param ControllerName A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language, from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
|
||||
///
|
||||
/// Component Name Protocol instance
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_COMPONENT_NAME_PROTOCOL gDnsComponentName = {
|
||||
DnsComponentNameGetDriverName,
|
||||
DnsComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
///
|
||||
/// Component Name 2 Protocol instance
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_COMPONENT_NAME2_PROTOCOL gDnsComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) DnsComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) DnsComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
///
|
||||
/// Table of driver names
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_UNICODE_STRING_TABLE mDnsDriverNameTable[] = {
|
||||
{ "eng;en", (CHAR16 *)L"DNS Network Service Driver" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gDnsControllerNameTable = NULL;
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param Language A pointer to a three-character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
@param DriverName A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mDnsDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This == &gDnsComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Update the component name for the Dns4 child handle.
|
||||
|
||||
@param Dns4 A pointer to the EFI_DNS4_PROTOCOL.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
|
||||
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateDns4Name (
|
||||
EFI_DNS4_PROTOCOL *Dns4
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
CHAR16 HandleName[80];
|
||||
EFI_DNS4_MODE_DATA ModeData;
|
||||
|
||||
if (Dns4 == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Format the child name into the string buffer as:
|
||||
// DNSv4 (StationIp=?, LocalPort=?)
|
||||
//
|
||||
Status = Dns4->GetModeData (Dns4, &ModeData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
UnicodeSPrint (
|
||||
HandleName,
|
||||
sizeof (HandleName),
|
||||
L"DNSv4 (StationIp=%d.%d.%d.%d, LocalPort=%d)",
|
||||
ModeData.DnsConfigData.StationIp.Addr[0],
|
||||
ModeData.DnsConfigData.StationIp.Addr[1],
|
||||
ModeData.DnsConfigData.StationIp.Addr[2],
|
||||
ModeData.DnsConfigData.StationIp.Addr[3],
|
||||
ModeData.DnsConfigData.LocalPort
|
||||
);
|
||||
|
||||
if (ModeData.DnsCacheList != NULL) {
|
||||
FreePool (ModeData.DnsCacheList);
|
||||
}
|
||||
if (ModeData.DnsServerList != NULL) {
|
||||
FreePool (ModeData.DnsServerList);
|
||||
}
|
||||
|
||||
if (gDnsControllerNameTable != NULL) {
|
||||
FreeUnicodeStringTable (gDnsControllerNameTable);
|
||||
gDnsControllerNameTable = NULL;
|
||||
}
|
||||
|
||||
Status = AddUnicodeString2 (
|
||||
"eng",
|
||||
gDnsComponentName.SupportedLanguages,
|
||||
&gDnsControllerNameTable,
|
||||
HandleName,
|
||||
TRUE
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return AddUnicodeString2 (
|
||||
"en",
|
||||
gDnsComponentName2.SupportedLanguages,
|
||||
&gDnsControllerNameTable,
|
||||
HandleName,
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Update the component name for the Dns6 child handle.
|
||||
|
||||
@param Dns6 A pointer to the EFI_DNS6_PROTOCOL.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully.
|
||||
@retval EFI_INVALID_PARAMETER The input parameter is invalid.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
UpdateDns6Name (
|
||||
EFI_DNS6_PROTOCOL *Dns6
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
CHAR16 HandleName[128];
|
||||
EFI_DNS6_MODE_DATA ModeData;
|
||||
CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
|
||||
|
||||
if (Dns6 == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Format the child name into the string buffer as:
|
||||
// DNSv6 (StationIp=?, LocalPort=?)
|
||||
//
|
||||
Status = Dns6->GetModeData (Dns6, &ModeData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = NetLibIp6ToStr (&ModeData.DnsConfigData.StationIp, Address, sizeof (Address));
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
UnicodeSPrint (
|
||||
HandleName,
|
||||
sizeof (HandleName),
|
||||
L"DNSv6 (StationIp=%s, LocalPort=%d)",
|
||||
Address,
|
||||
ModeData.DnsConfigData.LocalPort
|
||||
);
|
||||
|
||||
if (ModeData.DnsCacheList != NULL) {
|
||||
FreePool (ModeData.DnsCacheList);
|
||||
}
|
||||
if (ModeData.DnsServerList != NULL) {
|
||||
FreePool (ModeData.DnsServerList);
|
||||
}
|
||||
|
||||
if (gDnsControllerNameTable != NULL) {
|
||||
FreeUnicodeStringTable (gDnsControllerNameTable);
|
||||
gDnsControllerNameTable = NULL;
|
||||
}
|
||||
|
||||
Status = AddUnicodeString2 (
|
||||
"eng",
|
||||
gDnsComponentName.SupportedLanguages,
|
||||
&gDnsControllerNameTable,
|
||||
HandleName,
|
||||
TRUE
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return AddUnicodeString2 (
|
||||
"en",
|
||||
gDnsComponentName2.SupportedLanguages,
|
||||
&gDnsControllerNameTable,
|
||||
HandleName,
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param ControllerHandle The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
@param ChildHandle The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
@param Language A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
@param ControllerName A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language, from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_DNS4_PROTOCOL *Dns4;
|
||||
EFI_DNS6_PROTOCOL *Dns6;
|
||||
|
||||
//
|
||||
// ChildHandle must be NULL for a Device Driver
|
||||
//
|
||||
if (ChildHandle == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure this driver produced ChildHandle
|
||||
//
|
||||
Status = EfiTestChildHandle (
|
||||
ControllerHandle,
|
||||
ChildHandle,
|
||||
&gEfiUdp6ProtocolGuid
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Retrieve an instance of a produced protocol from ChildHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiDns6ProtocolGuid,
|
||||
(VOID **)&Dns6,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the component name for this child handle.
|
||||
//
|
||||
Status = UpdateDns6Name (Dns6);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure this driver produced ChildHandle
|
||||
//
|
||||
Status = EfiTestChildHandle (
|
||||
ControllerHandle,
|
||||
ChildHandle,
|
||||
&gEfiUdp4ProtocolGuid
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Retrieve an instance of a produced protocol from ChildHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiDns4ProtocolGuid,
|
||||
(VOID **)&Dns4,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the component name for this child handle.
|
||||
//
|
||||
Status = UpdateDns4Name (Dns4);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
gDnsControllerNameTable,
|
||||
ControllerName,
|
||||
(BOOLEAN)(This == &gDnsComponentName)
|
||||
);
|
||||
}
|
|
@ -0,0 +1,758 @@
|
|||
/** @file
|
||||
Functions implementation related with DHCPv4/v6 for DNS driver.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "DnsImpl.h"
|
||||
|
||||
/**
|
||||
This function initialize the DHCP4 message instance.
|
||||
|
||||
This function will pad each item of dhcp4 message packet.
|
||||
|
||||
@param Seed Pointer to the message instance of the DHCP4 packet.
|
||||
@param InterfaceInfo Pointer to the EFI_IP4_CONFIG2_INTERFACE_INFO instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DnsInitSeedPacket (
|
||||
OUT EFI_DHCP4_PACKET *Seed,
|
||||
IN EFI_IP4_CONFIG2_INTERFACE_INFO *InterfaceInfo
|
||||
)
|
||||
{
|
||||
EFI_DHCP4_HEADER *Header;
|
||||
|
||||
//
|
||||
// Get IfType and HwAddressSize from SNP mode data.
|
||||
//
|
||||
Seed->Size = sizeof (EFI_DHCP4_PACKET);
|
||||
Seed->Length = sizeof (Seed->Dhcp4);
|
||||
Header = &Seed->Dhcp4.Header;
|
||||
ZeroMem (Header, sizeof (EFI_DHCP4_HEADER));
|
||||
Header->OpCode = DHCP4_OPCODE_REQUEST;
|
||||
Header->HwType = InterfaceInfo->IfType;
|
||||
Header->HwAddrLen = (UINT8) InterfaceInfo->HwAddressSize;
|
||||
CopyMem (Header->ClientHwAddr, &(InterfaceInfo->HwAddress), Header->HwAddrLen);
|
||||
|
||||
Seed->Dhcp4.Magik = DHCP4_MAGIC;
|
||||
Seed->Dhcp4.Option[0] = DHCP4_TAG_EOP;
|
||||
}
|
||||
|
||||
/**
|
||||
The common notify function.
|
||||
|
||||
@param[in] Event The event signaled.
|
||||
@param[in] Context The context.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DhcpCommonNotify (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
if ((Event == NULL) || (Context == NULL)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
*((BOOLEAN *) Context) = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse the ACK to get required information
|
||||
|
||||
@param Dhcp4 The DHCP4 protocol.
|
||||
@param Packet Packet waiting for parse.
|
||||
@param DnsServerInfor The required Dns4 server information.
|
||||
|
||||
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
|
||||
@retval EFI_NO_MAPPING DHCP failed to acquire address and other information.
|
||||
@retval EFI_DEVICE_ERROR Other errors as indicated.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDhcp4Ack (
|
||||
IN EFI_DHCP4_PROTOCOL *Dhcp4,
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
IN DNS4_SERVER_INFOR *DnsServerInfor
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 OptionCount;
|
||||
EFI_DHCP4_PACKET_OPTION **OptionList;
|
||||
UINT32 ServerCount;
|
||||
EFI_IPv4_ADDRESS *ServerList;
|
||||
UINT32 Index;
|
||||
UINT32 Count;
|
||||
|
||||
ServerCount = 0;
|
||||
ServerList = NULL;
|
||||
|
||||
OptionCount = 0;
|
||||
OptionList = NULL;
|
||||
|
||||
Status = Dhcp4->Parse (Dhcp4, Packet, &OptionCount, OptionList);
|
||||
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
OptionList = AllocatePool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
|
||||
if (OptionList == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = Dhcp4->Parse (Dhcp4, Packet, &OptionCount, OptionList);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (OptionList);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Status = EFI_NOT_FOUND;
|
||||
|
||||
for (Index = 0; Index < OptionCount; Index++) {
|
||||
//
|
||||
// Get DNS server addresses
|
||||
//
|
||||
if (OptionList[Index]->OpCode == DHCP4_TAG_DNS_SERVER) {
|
||||
|
||||
if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
ServerCount = OptionList[Index]->Length/4;
|
||||
ServerList = AllocatePool (ServerCount * sizeof (EFI_IPv4_ADDRESS));
|
||||
if (ServerList == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for(Count=0; Count < ServerCount; Count++){
|
||||
CopyMem (ServerList + Count, &OptionList[Index]->Data[4 * Count], sizeof (EFI_IPv4_ADDRESS));
|
||||
}
|
||||
|
||||
*(DnsServerInfor->ServerCount) = ServerCount;
|
||||
DnsServerInfor->ServerList = ServerList;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
gBS->FreePool (OptionList);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol
|
||||
instance to intercept events that occurs in the DHCPv6 Information Request
|
||||
exchange process.
|
||||
|
||||
@param This Pointer to the EFI_DHCP6_PROTOCOL instance that
|
||||
is used to configure this callback function.
|
||||
@param Context Pointer to the context that is initialized in
|
||||
the EFI_DHCP6_PROTOCOL.InfoRequest().
|
||||
@param Packet Pointer to Reply packet that has been received.
|
||||
The EFI DHCPv6 Protocol instance is responsible
|
||||
for freeing the buffer.
|
||||
|
||||
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
|
||||
@retval EFI_DEVICE_ERROR Other errors as indicated.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ParseDhcp6Ack (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN VOID *Context,
|
||||
IN EFI_DHCP6_PACKET *Packet
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 OptionCount;
|
||||
EFI_DHCP6_PACKET_OPTION **OptionList;
|
||||
DNS6_SERVER_INFOR *DnsServerInfor;
|
||||
UINT32 ServerCount;
|
||||
EFI_IPv6_ADDRESS *ServerList;
|
||||
UINT32 Index;
|
||||
UINT32 Count;
|
||||
|
||||
OptionCount = 0;
|
||||
ServerCount = 0;
|
||||
ServerList = NULL;
|
||||
|
||||
Status = This->Parse (This, Packet, &OptionCount, NULL);
|
||||
if (Status != EFI_BUFFER_TOO_SMALL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *));
|
||||
if (OptionList == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = This->Parse (This, Packet, &OptionCount, OptionList);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->FreePool (OptionList);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
DnsServerInfor = (DNS6_SERVER_INFOR *) Context;
|
||||
|
||||
for (Index = 0; Index < OptionCount; Index++) {
|
||||
OptionList[Index]->OpCode = NTOHS (OptionList[Index]->OpCode);
|
||||
OptionList[Index]->OpLen = NTOHS (OptionList[Index]->OpLen);
|
||||
|
||||
//
|
||||
// Get DNS server addresses from this reply packet.
|
||||
//
|
||||
if (OptionList[Index]->OpCode == DHCP6_TAG_DNS_SERVER) {
|
||||
|
||||
if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
gBS->FreePool (OptionList);
|
||||
return Status;
|
||||
}
|
||||
|
||||
ServerCount = OptionList[Index]->OpLen/16;
|
||||
ServerList = AllocatePool (ServerCount * sizeof (EFI_IPv6_ADDRESS));
|
||||
if (ServerList == NULL) {
|
||||
gBS->FreePool (OptionList);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for(Count=0; Count < ServerCount; Count++){
|
||||
CopyMem (ServerList + Count, &OptionList[Index]->Data[16 * Count], sizeof (EFI_IPv6_ADDRESS));
|
||||
}
|
||||
|
||||
*(DnsServerInfor->ServerCount) = ServerCount;
|
||||
DnsServerInfor->ServerList = ServerList;
|
||||
}
|
||||
}
|
||||
|
||||
gBS->FreePool (OptionList);
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Parse the DHCP ACK to get Dns4 server information.
|
||||
|
||||
@param Instance The DNS instance.
|
||||
@param DnsServerCount Retrieved Dns4 server Ip count.
|
||||
@param DnsServerList Retrieved Dns4 server Ip list.
|
||||
|
||||
@retval EFI_SUCCESS The Dns4 information is got from the DHCP ACK.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
@retval EFI_NO_MEDIA There was a media error.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDns4ServerFromDhcp4 (
|
||||
IN DNS_INSTANCE *Instance,
|
||||
OUT UINT32 *DnsServerCount,
|
||||
OUT EFI_IPv4_ADDRESS **DnsServerList
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Image;
|
||||
EFI_HANDLE Controller;
|
||||
EFI_STATUS MediaStatus;
|
||||
EFI_HANDLE MnpChildHandle;
|
||||
EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
|
||||
EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
|
||||
EFI_HANDLE Dhcp4Handle;
|
||||
EFI_DHCP4_PROTOCOL *Dhcp4;
|
||||
EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
|
||||
UINTN DataSize;
|
||||
VOID *Data;
|
||||
EFI_IP4_CONFIG2_INTERFACE_INFO *InterfaceInfo;
|
||||
EFI_DHCP4_PACKET SeedPacket;
|
||||
EFI_DHCP4_PACKET_OPTION *ParaList[2];
|
||||
DNS4_SERVER_INFOR DnsServerInfor;
|
||||
|
||||
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN Token;
|
||||
BOOLEAN IsDone;
|
||||
UINTN Index;
|
||||
|
||||
Image = Instance->Service->ImageHandle;
|
||||
Controller = Instance->Service->ControllerHandle;
|
||||
|
||||
MnpChildHandle = NULL;
|
||||
Mnp = NULL;
|
||||
|
||||
Dhcp4Handle = NULL;
|
||||
Dhcp4 = NULL;
|
||||
|
||||
Ip4Config2 = NULL;
|
||||
DataSize = 0;
|
||||
Data = NULL;
|
||||
InterfaceInfo = NULL;
|
||||
|
||||
ZeroMem ((UINT8 *) ParaList, sizeof (ParaList));
|
||||
|
||||
ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA));
|
||||
|
||||
ZeroMem (&DnsServerInfor, sizeof (DNS4_SERVER_INFOR));
|
||||
|
||||
ZeroMem (&Token, sizeof (EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN));
|
||||
|
||||
DnsServerInfor.ServerCount = DnsServerCount;
|
||||
|
||||
IsDone = FALSE;
|
||||
|
||||
//
|
||||
// Check media.
|
||||
//
|
||||
MediaStatus = EFI_SUCCESS;
|
||||
NetLibDetectMediaWaitTimeout (Controller, DNS_CHECK_MEDIA_GET_DHCP_WAITING_TIME, &MediaStatus);
|
||||
if (MediaStatus != EFI_SUCCESS) {
|
||||
return EFI_NO_MEDIA;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a Mnp child instance, get the protocol and config for it.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
Controller,
|
||||
Image,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
&MnpChildHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
(VOID **) &Mnp,
|
||||
Image,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
MnpConfigData.ReceivedQueueTimeoutValue = 0;
|
||||
MnpConfigData.TransmitQueueTimeoutValue = 0;
|
||||
MnpConfigData.ProtocolTypeFilter = IP4_ETHER_PROTO;
|
||||
MnpConfigData.EnableUnicastReceive = TRUE;
|
||||
MnpConfigData.EnableMulticastReceive = TRUE;
|
||||
MnpConfigData.EnableBroadcastReceive = TRUE;
|
||||
MnpConfigData.EnablePromiscuousReceive = FALSE;
|
||||
MnpConfigData.FlushQueuesOnReset = TRUE;
|
||||
MnpConfigData.EnableReceiveTimestamps = FALSE;
|
||||
MnpConfigData.DisableBackgroundPolling = FALSE;
|
||||
|
||||
Status = Mnp->Configure(Mnp, &MnpConfigData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a DHCP4 child instance and get the protocol.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
Controller,
|
||||
Image,
|
||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||
&Dhcp4Handle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
Dhcp4Handle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
(VOID **) &Dhcp4,
|
||||
Image,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Get Ip4Config2 instance info.
|
||||
//
|
||||
Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data);
|
||||
if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Data = AllocateZeroPool (DataSize);
|
||||
if (Data == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
InterfaceInfo = (EFI_IP4_CONFIG2_INTERFACE_INFO *)Data;
|
||||
|
||||
//
|
||||
// Build required Token.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
DhcpCommonNotify,
|
||||
&IsDone,
|
||||
&Token.CompletionEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
SetMem (&Token.RemoteAddress, sizeof (EFI_IPv4_ADDRESS), 0xff);
|
||||
|
||||
Token.RemotePort = 67;
|
||||
|
||||
Token.ListenPointCount = 1;
|
||||
|
||||
Token.ListenPoints = AllocateZeroPool (Token.ListenPointCount * sizeof (EFI_DHCP4_LISTEN_POINT));
|
||||
if (Token.ListenPoints == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (Instance->Dns4CfgData.UseDefaultSetting) {
|
||||
CopyMem (&(Token.ListenPoints[0].ListenAddress), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&(Token.ListenPoints[0].SubnetMask), &(InterfaceInfo->SubnetMask), sizeof (EFI_IPv4_ADDRESS));
|
||||
} else {
|
||||
CopyMem (&(Token.ListenPoints[0].ListenAddress), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&(Token.ListenPoints[0].SubnetMask), &(Instance->Dns4CfgData.SubnetMask), sizeof (EFI_IPv4_ADDRESS));
|
||||
}
|
||||
|
||||
Token.ListenPoints[0].ListenPort = 68;
|
||||
|
||||
Token.TimeoutValue = DNS_TIME_TO_GETMAP;
|
||||
|
||||
DnsInitSeedPacket (&SeedPacket, InterfaceInfo);
|
||||
|
||||
ParaList[0] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION));
|
||||
if (ParaList[0] == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
ParaList[0]->OpCode = DHCP4_TAG_TYPE;
|
||||
ParaList[0]->Length = 1;
|
||||
ParaList[0]->Data[0] = DHCP4_MSG_REQUEST;
|
||||
|
||||
ParaList[1] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION));
|
||||
if (ParaList[1] == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
ParaList[1]->OpCode = DHCP4_TAG_PARA_LIST;
|
||||
ParaList[1]->Length = 1;
|
||||
ParaList[1]->Data[0] = DHCP4_TAG_DNS_SERVER;
|
||||
|
||||
Status = Dhcp4->Build (Dhcp4, &SeedPacket, 0, NULL, 2, ParaList, &Token.Packet);
|
||||
|
||||
Token.Packet->Dhcp4.Header.Xid = HTONL(NET_RANDOM (NetRandomInitSeed ()));
|
||||
|
||||
Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)0x8000);
|
||||
|
||||
if (Instance->Dns4CfgData.UseDefaultSetting) {
|
||||
CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS));
|
||||
} else {
|
||||
CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS));
|
||||
}
|
||||
|
||||
CopyMem (Token.Packet->Dhcp4.Header.ClientHwAddr, &(InterfaceInfo->HwAddress), InterfaceInfo->HwAddressSize);
|
||||
|
||||
Token.Packet->Dhcp4.Header.HwAddrLen = (UINT8)(InterfaceInfo->HwAddressSize);
|
||||
|
||||
//
|
||||
// TransmitReceive Token
|
||||
//
|
||||
Status = Dhcp4->TransmitReceive (Dhcp4, &Token);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Poll the packet
|
||||
//
|
||||
do {
|
||||
Status = Mnp->Poll (Mnp);
|
||||
} while (!IsDone);
|
||||
|
||||
//
|
||||
// Parse the ACK to get required information if received done.
|
||||
//
|
||||
if (IsDone && !EFI_ERROR (Token.Status)) {
|
||||
for (Index = 0; Index < Token.ResponseCount; Index++) {
|
||||
Status = ParseDhcp4Ack (Dhcp4, &Token.ResponseList[Index], &DnsServerInfor);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*DnsServerList = DnsServerInfor.ServerList;
|
||||
} else {
|
||||
Status = Token.Status;
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
|
||||
if (Data != NULL) {
|
||||
FreePool (Data);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < 2; Index++) {
|
||||
if (ParaList[Index] != NULL) {
|
||||
FreePool (ParaList[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (Token.ListenPoints) {
|
||||
FreePool (Token.ListenPoints);
|
||||
}
|
||||
|
||||
if (Token.Packet) {
|
||||
FreePool (Token.Packet);
|
||||
}
|
||||
|
||||
if (Token.ResponseList != NULL) {
|
||||
FreePool (Token.ResponseList);
|
||||
}
|
||||
|
||||
if (Token.CompletionEvent != NULL) {
|
||||
gBS->CloseEvent (Token.CompletionEvent);
|
||||
}
|
||||
|
||||
if (Dhcp4 != NULL) {
|
||||
Dhcp4->Stop (Dhcp4);
|
||||
Dhcp4->Configure (Dhcp4, NULL);
|
||||
|
||||
gBS->CloseProtocol (
|
||||
Dhcp4Handle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
Image,
|
||||
Controller
|
||||
);
|
||||
}
|
||||
|
||||
if (Dhcp4Handle != NULL) {
|
||||
NetLibDestroyServiceChild (
|
||||
Controller,
|
||||
Image,
|
||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||
Dhcp4Handle
|
||||
);
|
||||
}
|
||||
|
||||
if (Mnp != NULL) {
|
||||
Mnp->Configure (Mnp, NULL);
|
||||
|
||||
gBS->CloseProtocol (
|
||||
MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
Image,
|
||||
Controller
|
||||
);
|
||||
}
|
||||
|
||||
NetLibDestroyServiceChild (
|
||||
Controller,
|
||||
Image,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
MnpChildHandle
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse the DHCP ACK to get Dns6 server information.
|
||||
|
||||
@param Image The handle of the driver image.
|
||||
@param Controller The handle of the controller.
|
||||
@param DnsServerCount Retrieved Dns6 server Ip count.
|
||||
@param DnsServerList Retrieved Dns6 server Ip list.
|
||||
|
||||
@retval EFI_SUCCESS The Dns6 information is got from the DHCP ACK.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
@retval EFI_NO_MEDIA There was a media error.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDns6ServerFromDhcp6 (
|
||||
IN EFI_HANDLE Image,
|
||||
IN EFI_HANDLE Controller,
|
||||
OUT UINT32 *DnsServerCount,
|
||||
OUT EFI_IPv6_ADDRESS **DnsServerList
|
||||
)
|
||||
{
|
||||
EFI_HANDLE Dhcp6Handle;
|
||||
EFI_DHCP6_PROTOCOL *Dhcp6;
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS TimerStatus;
|
||||
EFI_DHCP6_PACKET_OPTION *Oro;
|
||||
EFI_DHCP6_RETRANSMISSION InfoReqReXmit;
|
||||
EFI_EVENT Timer;
|
||||
EFI_STATUS MediaStatus;
|
||||
DNS6_SERVER_INFOR DnsServerInfor;
|
||||
|
||||
Dhcp6Handle = NULL;
|
||||
Dhcp6 = NULL;
|
||||
Oro = NULL;
|
||||
Timer = NULL;
|
||||
|
||||
ZeroMem (&DnsServerInfor, sizeof (DNS6_SERVER_INFOR));
|
||||
|
||||
DnsServerInfor.ServerCount = DnsServerCount;
|
||||
|
||||
//
|
||||
// Check media status before doing DHCP.
|
||||
//
|
||||
MediaStatus = EFI_SUCCESS;
|
||||
NetLibDetectMediaWaitTimeout (Controller, DNS_CHECK_MEDIA_GET_DHCP_WAITING_TIME, &MediaStatus);
|
||||
if (MediaStatus != EFI_SUCCESS) {
|
||||
return EFI_NO_MEDIA;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a DHCP6 child instance and get the protocol.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
Controller,
|
||||
Image,
|
||||
&gEfiDhcp6ServiceBindingProtocolGuid,
|
||||
&Dhcp6Handle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
Dhcp6Handle,
|
||||
&gEfiDhcp6ProtocolGuid,
|
||||
(VOID **) &Dhcp6,
|
||||
Image,
|
||||
Controller,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 1);
|
||||
if (Oro == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Ask the server to reply with DNS options.
|
||||
// All members in EFI_DHCP6_PACKET_OPTION are in network order.
|
||||
//
|
||||
Oro->OpCode = HTONS (DHCP6_TAG_DNS_REQUEST);
|
||||
Oro->OpLen = HTONS (2);
|
||||
Oro->Data[1] = DHCP6_TAG_DNS_SERVER;
|
||||
|
||||
InfoReqReXmit.Irt = 4;
|
||||
InfoReqReXmit.Mrc = 1;
|
||||
InfoReqReXmit.Mrt = 10;
|
||||
InfoReqReXmit.Mrd = 30;
|
||||
|
||||
Status = Dhcp6->InfoRequest (
|
||||
Dhcp6,
|
||||
TRUE,
|
||||
Oro,
|
||||
0,
|
||||
NULL,
|
||||
&InfoReqReXmit,
|
||||
NULL,
|
||||
ParseDhcp6Ack,
|
||||
&DnsServerInfor
|
||||
);
|
||||
if (Status == EFI_NO_MAPPING) {
|
||||
Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = gBS->SetTimer (
|
||||
Timer,
|
||||
TimerRelative,
|
||||
DNS_TIME_TO_GETMAP * TICKS_PER_SECOND
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
do {
|
||||
TimerStatus = gBS->CheckEvent (Timer);
|
||||
if (!EFI_ERROR (TimerStatus)) {
|
||||
Status = Dhcp6->InfoRequest (
|
||||
Dhcp6,
|
||||
TRUE,
|
||||
Oro,
|
||||
0,
|
||||
NULL,
|
||||
&InfoReqReXmit,
|
||||
NULL,
|
||||
ParseDhcp6Ack,
|
||||
&DnsServerInfor
|
||||
);
|
||||
}
|
||||
} while (TimerStatus == EFI_NOT_READY);
|
||||
}
|
||||
|
||||
*DnsServerList = DnsServerInfor.ServerList;
|
||||
|
||||
ON_EXIT:
|
||||
|
||||
if (Oro != NULL) {
|
||||
FreePool (Oro);
|
||||
}
|
||||
|
||||
if (Timer != NULL) {
|
||||
gBS->CloseEvent (Timer);
|
||||
}
|
||||
|
||||
if (Dhcp6 != NULL) {
|
||||
gBS->CloseProtocol (
|
||||
Dhcp6Handle,
|
||||
&gEfiDhcp6ProtocolGuid,
|
||||
Image,
|
||||
Controller
|
||||
);
|
||||
}
|
||||
|
||||
NetLibDestroyServiceChild (
|
||||
Controller,
|
||||
Image,
|
||||
&gEfiDhcp6ServiceBindingProtocolGuid,
|
||||
Dhcp6Handle
|
||||
);
|
||||
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/** @file
|
||||
Functions implementation related with DHCPv4/v6 for DNS driver.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _DNS_DHCP_H_
|
||||
#define _DNS_DHCP_H_
|
||||
|
||||
//
|
||||
// DHCP DNS related
|
||||
//
|
||||
#pragma pack(1)
|
||||
|
||||
#define IP4_ETHER_PROTO 0x0800
|
||||
|
||||
#define DHCP4_OPCODE_REQUEST 1
|
||||
#define DHCP4_MAGIC 0x63538263 /// network byte order
|
||||
#define DHCP4_TAG_EOP 255 /// End Option
|
||||
|
||||
#define DHCP4_TAG_TYPE 53
|
||||
#define DHCP4_MSG_REQUEST 3
|
||||
#define DHCP4_MSG_INFORM 8
|
||||
|
||||
#define DHCP4_TAG_PARA_LIST 55
|
||||
#define DHCP4_TAG_DNS_SERVER 6
|
||||
|
||||
|
||||
#define DHCP6_TAG_DNS_REQUEST 6
|
||||
#define DHCP6_TAG_DNS_SERVER 23
|
||||
|
||||
#define DNS_CHECK_MEDIA_GET_DHCP_WAITING_TIME EFI_TIMER_PERIOD_SECONDS(20)
|
||||
|
||||
//
|
||||
// The required Dns4 server information.
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 *ServerCount;
|
||||
EFI_IPv4_ADDRESS *ServerList;
|
||||
} DNS4_SERVER_INFOR;
|
||||
|
||||
//
|
||||
// The required Dns6 server information.
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 *ServerCount;
|
||||
EFI_IPv6_ADDRESS *ServerList;
|
||||
} DNS6_SERVER_INFOR;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
Parse the ACK to get required information
|
||||
|
||||
@param Dhcp4 The DHCP4 protocol.
|
||||
@param Packet Packet waiting for parse.
|
||||
@param DnsServerInfor The required Dns4 server information.
|
||||
|
||||
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
|
||||
@retval EFI_NO_MAPPING DHCP failed to acquire address and other information.
|
||||
@retval EFI_DEVICE_ERROR Other errors as indicated.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ParseDhcp4Ack (
|
||||
IN EFI_DHCP4_PROTOCOL *Dhcp4,
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
IN DNS4_SERVER_INFOR *DnsServerInfor
|
||||
);
|
||||
|
||||
/**
|
||||
EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol
|
||||
instance to intercept events that occurs in the DHCPv6 Information Request
|
||||
exchange process.
|
||||
|
||||
@param This Pointer to the EFI_DHCP6_PROTOCOL instance that
|
||||
is used to configure this callback function.
|
||||
@param Context Pointer to the context that is initialized in
|
||||
the EFI_DHCP6_PROTOCOL.InfoRequest().
|
||||
@param Packet Pointer to Reply packet that has been received.
|
||||
The EFI DHCPv6 Protocol instance is responsible
|
||||
for freeing the buffer.
|
||||
|
||||
@retval EFI_SUCCESS The DNS information is got from the DHCP ACK.
|
||||
@retval EFI_DEVICE_ERROR Other errors as indicated.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ParseDhcp6Ack (
|
||||
IN EFI_DHCP6_PROTOCOL *This,
|
||||
IN VOID *Context,
|
||||
IN EFI_DHCP6_PACKET *Packet
|
||||
);
|
||||
|
||||
/**
|
||||
Parse the DHCP ACK to get Dns4 server information.
|
||||
|
||||
@param Instance The DNS instance.
|
||||
@param DnsServerCount Retrieved Dns4 server Ip count.
|
||||
@param DnsServerList Retrieved Dns4 server Ip list.
|
||||
|
||||
@retval EFI_SUCCESS The Dns4 information is got from the DHCP ACK.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
@retval EFI_NO_MEDIA There was a media error.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDns4ServerFromDhcp4 (
|
||||
IN DNS_INSTANCE *Instance,
|
||||
OUT UINT32 *DnsServerCount,
|
||||
OUT EFI_IPv4_ADDRESS **DnsServerList
|
||||
);
|
||||
|
||||
/**
|
||||
Parse the DHCP ACK to get Dns6 server information.
|
||||
|
||||
@param Image The handle of the driver image.
|
||||
@param Controller The handle of the controller.
|
||||
@param DnsServerCount Retrieved Dns6 server Ip count.
|
||||
@param DnsServerList Retrieved Dns6 server Ip list.
|
||||
|
||||
@retval EFI_SUCCESS The Dns6 information is got from the DHCP ACK.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
@retval EFI_NO_MEDIA There was a media error.
|
||||
@retval Others Other errors as indicated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetDns6ServerFromDhcp6 (
|
||||
IN EFI_HANDLE Image,
|
||||
IN EFI_HANDLE Controller,
|
||||
OUT UINT32 *DnsServerCount,
|
||||
OUT EFI_IPv6_ADDRESS **DnsServerList
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,598 @@
|
|||
/** @file
|
||||
The header files of the driver binding and service binding protocol for DnsDxe driver.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _DNS_DRIVER_H_
|
||||
#define _DNS_DRIVER_H_
|
||||
|
||||
#include <Protocol/DriverBinding.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
///
|
||||
/// Dns service block
|
||||
///
|
||||
typedef struct _DNS_DRIVER_DATA DNS_DRIVER_DATA;
|
||||
|
||||
///
|
||||
/// Dns service block
|
||||
///
|
||||
typedef struct _DNS_SERVICE DNS_SERVICE;
|
||||
|
||||
///
|
||||
/// Dns instance block
|
||||
///
|
||||
typedef struct _DNS_INSTANCE DNS_INSTANCE;
|
||||
|
||||
#define DNS_SERVICE_SIGNATURE SIGNATURE_32 ('D', 'N', 'S', 'S')
|
||||
|
||||
#define DNS_INSTANCE_SIGNATURE SIGNATURE_32 ('D', 'N', 'S', 'I')
|
||||
|
||||
struct _DNS_DRIVER_DATA {
|
||||
EFI_EVENT Timer; /// Ticking timer for DNS cache update.
|
||||
|
||||
LIST_ENTRY Dns4CacheList;
|
||||
LIST_ENTRY Dns4ServerList;
|
||||
|
||||
LIST_ENTRY Dns6CacheList;
|
||||
LIST_ENTRY Dns6ServerList;
|
||||
};
|
||||
|
||||
struct _DNS_SERVICE {
|
||||
UINT32 Signature;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
|
||||
UINT16 Dns4ChildrenNum;
|
||||
LIST_ENTRY Dns4ChildrenList;
|
||||
|
||||
UINT16 Dns6ChildrenNum;
|
||||
LIST_ENTRY Dns6ChildrenList;
|
||||
|
||||
EFI_HANDLE ControllerHandle;
|
||||
EFI_HANDLE ImageHandle;
|
||||
|
||||
EFI_EVENT TimerToGetMap;
|
||||
|
||||
EFI_EVENT Timer; /// Ticking timer for packet retransmission.
|
||||
|
||||
UINT8 IpVersion;
|
||||
UDP_IO *ConnectUdp;
|
||||
};
|
||||
|
||||
struct _DNS_INSTANCE {
|
||||
UINT32 Signature;
|
||||
LIST_ENTRY Link;
|
||||
|
||||
EFI_DNS4_PROTOCOL Dns4;
|
||||
EFI_DNS6_PROTOCOL Dns6;
|
||||
|
||||
INTN State;
|
||||
BOOLEAN InDestroy;
|
||||
|
||||
DNS_SERVICE *Service;
|
||||
EFI_HANDLE ChildHandle;
|
||||
|
||||
EFI_DNS4_CONFIG_DATA Dns4CfgData;
|
||||
EFI_DNS6_CONFIG_DATA Dns6CfgData;
|
||||
|
||||
EFI_IP_ADDRESS SessionDnsServer;
|
||||
|
||||
NET_MAP Dns4TxTokens;
|
||||
NET_MAP Dns6TxTokens;
|
||||
|
||||
UDP_IO *UdpIo;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
UINTN NumberOfChildren;
|
||||
EFI_HANDLE *ChildHandleBuffer;
|
||||
} DNS_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT;
|
||||
|
||||
extern DNS_DRIVER_DATA *mDriverData;
|
||||
|
||||
#define DNS_SERVICE_FROM_THIS(a) \
|
||||
CR (a, DNS_SERVICE, ServiceBinding, DNS_SERVICE_SIGNATURE)
|
||||
|
||||
#define DNS_INSTANCE_FROM_THIS_PROTOCOL4(a) \
|
||||
CR (a, DNS_INSTANCE, Dns4, DNS_INSTANCE_SIGNATURE)
|
||||
|
||||
#define DNS_INSTANCE_FROM_THIS_PROTOCOL6(a) \
|
||||
CR (a, DNS_INSTANCE, Dns6, DNS_INSTANCE_SIGNATURE)
|
||||
|
||||
|
||||
/**
|
||||
Destroy the DNS instance and recycle the resources.
|
||||
|
||||
@param[in] Instance The pointer to the DNS instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DnsDestroyInstance (
|
||||
IN DNS_INSTANCE *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Create the DNS instance and initialize it.
|
||||
|
||||
@param[in] Service The pointer to the DNS service.
|
||||
@param[out] Instance The pointer to the DNS instance.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
|
||||
@retval EFI_SUCCESS The DNS instance is created.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DnsCreateInstance (
|
||||
IN DNS_SERVICE *Service,
|
||||
OUT DNS_INSTANCE **Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Callback function which provided by user to remove one node in NetDestroyLinkList process.
|
||||
|
||||
@param[in] Entry The entry to be removed.
|
||||
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been removed successfully.
|
||||
@retval Others Fail to remove the entry.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsDestroyChildEntryInHandleBuffer (
|
||||
IN LIST_ENTRY *Entry,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Config a NULL UDP that is used to keep the connection between UDP and DNS.
|
||||
|
||||
Just leave the Udp child unconfigured. When UDP is unloaded,
|
||||
DNS will be informed with DriverBinding Stop.
|
||||
|
||||
@param UdpIo The UDP_IO to configure
|
||||
@param Context The opaque parameter to the callback
|
||||
|
||||
@retval EFI_SUCCESS It always return EFI_SUCCESS directly.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsConfigNullUdp (
|
||||
IN UDP_IO *UdpIo,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Release all the resource used the DNS service binding instance.
|
||||
|
||||
@param DnsSb The Dns service binding instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DnsDestroyService (
|
||||
IN DNS_SERVICE *DnsSb
|
||||
);
|
||||
|
||||
/**
|
||||
Create then initialize a Dns service binding instance.
|
||||
|
||||
@param Controller The controller to install the DNS service
|
||||
binding on
|
||||
@param Image The driver binding image of the DNS driver
|
||||
@param IpVersion IpVersion for this service
|
||||
@param Service The variable to receive the created service
|
||||
binding instance.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance.
|
||||
@retval EFI_DEVICE_ERROR Failed to create a NULL UDP port to keep
|
||||
connection with UDP.
|
||||
@retval EFI_SUCCESS The service instance is created for the
|
||||
controller.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DnsCreateService (
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_HANDLE Image,
|
||||
IN UINT8 IpVersion,
|
||||
OUT DNS_SERVICE **Service
|
||||
);
|
||||
|
||||
/**
|
||||
Unloads an image.
|
||||
|
||||
@param ImageHandle Handle that identifies the image to be unloaded.
|
||||
|
||||
@retval EFI_SUCCESS The image has been unloaded.
|
||||
@retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsUnload (
|
||||
IN EFI_HANDLE ImageHandle
|
||||
);
|
||||
|
||||
/**
|
||||
This is the declaration of an EFI image entry point. This entry point is
|
||||
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
|
||||
both device drivers and bus drivers.
|
||||
|
||||
@param ImageHandle The firmware allocated handle for the UEFI image.
|
||||
@param SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The operation completed successfully.
|
||||
@retval Others An unexpected error occurred.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DnsDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns6DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns6DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns6DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||
then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param[in] ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
|
||||
If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
|
||||
|
||||
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing UEFI handle,
|
||||
then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns6ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param[in] ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dns6ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
## @file
|
||||
# Implementation of EFI_DNS4_PROTOCOL and EFI_DNS6_PROTOCOL interfaces.
|
||||
#
|
||||
# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DnsDxe
|
||||
FILE_GUID = b219e140-dffc-11e3-b956-0022681e6906
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = DnsDriverEntryPoint
|
||||
UNLOAD_IMAGE = DnsUnload
|
||||
MODULE_UNI_FILE = DnsDxe.uni
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
NetworkPkg/NetworkPkg.dec
|
||||
|
||||
[Sources]
|
||||
ComponentName.c
|
||||
DnsDriver.h
|
||||
DnsDriver.c
|
||||
DnsImpl.h
|
||||
DnsImpl.c
|
||||
DnsProtocol.c
|
||||
DnsDhcp.h
|
||||
DnsDhcp.c
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
BaseMemoryLib
|
||||
MemoryAllocationLib
|
||||
NetLib
|
||||
DebugLib
|
||||
DpcLib
|
||||
PrintLib
|
||||
UdpIoLib
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiDns4ServiceBindingProtocolGuid ## BY_START
|
||||
gEfiDns4ProtocolGuid ## BY_START
|
||||
gEfiUdp4ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiUdp4ProtocolGuid ## TO_START
|
||||
gEfiDhcp4ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDhcp4ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiManagedNetworkServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiManagedNetworkProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
gEfiDns6ServiceBindingProtocolGuid ## BY_START
|
||||
gEfiDns6ProtocolGuid ## BY_START
|
||||
gEfiUdp6ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiUdp6ProtocolGuid ## TO_START
|
||||
gEfiDhcp6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDhcp6ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
DnsDxeExtra.uni
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// /** @file
|
||||
// UEFI DNS DXE Driver.
|
||||
//
|
||||
// This driver provides UEFI 2.5 DNS protocols. It could work with an IPv4 and IPv6 stack.
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "UEFI DNS service"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This driver provides EFI DNS4 Protocol, EFI DNS6 Protocol, EFI DNS4 Service Binding Protocol and EFI DNS6 Service Binding Protocol. It could work with an IPv4 and IPv6 stack."
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// /** @file
|
||||
// DnsDxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"UEFI DNS DXE"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,341 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
Module Name:
|
||||
|
||||
Dpc.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Dpc.h"
|
||||
|
||||
//
|
||||
// Handle for the EFI_DPC_PROTOCOL instance
|
||||
//
|
||||
EFI_HANDLE mDpcHandle = NULL;
|
||||
|
||||
//
|
||||
// The EFI_DPC_PROTOCOL instances that is installed onto mDpcHandle
|
||||
//
|
||||
EFI_DPC_PROTOCOL mDpc = {
|
||||
DpcQueueDpc,
|
||||
DpcDispatchDpc
|
||||
};
|
||||
|
||||
//
|
||||
// Global variables used to meaasure the DPC Queue Depths
|
||||
//
|
||||
UINTN mDpcQueueDepth = 0;
|
||||
UINTN mMaxDpcQueueDepth = 0;
|
||||
|
||||
//
|
||||
// Free list of DPC entries. As DPCs are queued, entries are removed from this
|
||||
// free list. As DPC entries are dispatched, DPC entries are added to the free list.
|
||||
// If the free list is empty and a DPC is queued, the free list is grown by allocating
|
||||
// an additional set of DPC entries.
|
||||
//
|
||||
LIST_ENTRY mDpcEntryFreeList = INITIALIZE_LIST_HEAD_VARIABLE(mDpcEntryFreeList);
|
||||
|
||||
//
|
||||
// An array of DPC queues. A DPC queue is allocated for every leval EFI_TPL value.
|
||||
// As DPCs are queued, they are added to the end of the linked list.
|
||||
// As DPCs are dispatched, they are removed from the beginning of the linked list.
|
||||
//
|
||||
LIST_ENTRY mDpcQueue[TPL_HIGH_LEVEL + 1];
|
||||
|
||||
/**
|
||||
Add a Deferred Procedure Call to the end of the DPC queue.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param DpcTpl The EFI_TPL that the DPC should be invoked.
|
||||
@param DpcProcedure Pointer to the DPC's function.
|
||||
@param DpcContext Pointer to the DPC's context. Passed to DpcProcedure
|
||||
when DpcProcedure is invoked.
|
||||
|
||||
@retval EFI_SUCCESS The DPC was queued.
|
||||
@retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL.
|
||||
@retval EFI_INVALID_PARAMETER DpcProcedure is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to
|
||||
add the DPC to the queue.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DpcQueueDpc (
|
||||
IN EFI_DPC_PROTOCOL *This,
|
||||
IN EFI_TPL DpcTpl,
|
||||
IN EFI_DPC_PROCEDURE DpcProcedure,
|
||||
IN VOID *DpcContext OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS ReturnStatus;
|
||||
EFI_TPL OriginalTpl;
|
||||
DPC_ENTRY *DpcEntry;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// Make sure DpcTpl is valid
|
||||
//
|
||||
if (DpcTpl < TPL_APPLICATION || DpcTpl > TPL_HIGH_LEVEL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure DpcProcedure is valid
|
||||
//
|
||||
if (DpcProcedure == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Assume this function will succeed
|
||||
//
|
||||
ReturnStatus = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Raise the TPL level to TPL_HIGH_LEVEL for DPC list operation and save the
|
||||
// current TPL value so it can be restored when this function returns.
|
||||
//
|
||||
OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
//
|
||||
// Check to see if there are any entries in the DPC free list
|
||||
//
|
||||
if (IsListEmpty (&mDpcEntryFreeList)) {
|
||||
//
|
||||
// If the current TPL is greater than TPL_NOTIFY, then memory allocations
|
||||
// can not be performed, so the free list can not be expanded. In this case
|
||||
// return EFI_OUT_OF_RESOURCES.
|
||||
//
|
||||
if (OriginalTpl > TPL_NOTIFY) {
|
||||
ReturnStatus = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Add 64 DPC entries to the free list
|
||||
//
|
||||
for (Index = 0; Index < 64; Index++) {
|
||||
//
|
||||
// Lower the TPL level to perform a memory allocation
|
||||
//
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
|
||||
//
|
||||
// Allocate a new DPC entry
|
||||
//
|
||||
DpcEntry = AllocatePool (sizeof (DPC_ENTRY));
|
||||
|
||||
//
|
||||
// Raise the TPL level back to TPL_HIGH_LEVEL for DPC list operations
|
||||
//
|
||||
gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
//
|
||||
// If the allocation of a DPC entry fails, and the free list is empty,
|
||||
// then return EFI_OUT_OF_RESOURCES.
|
||||
//
|
||||
if (DpcEntry == NULL) {
|
||||
if (IsListEmpty (&mDpcEntryFreeList)) {
|
||||
ReturnStatus = EFI_OUT_OF_RESOURCES;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add the newly allocated DPC entry to the DPC free list
|
||||
//
|
||||
InsertTailList (&mDpcEntryFreeList, &DpcEntry->ListEntry);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the first node from the free list of DPCs
|
||||
//
|
||||
DpcEntry = (DPC_ENTRY *)(GetFirstNode (&mDpcEntryFreeList));
|
||||
|
||||
//
|
||||
// Remove the first node from the free list of DPCs
|
||||
//
|
||||
RemoveEntryList (&DpcEntry->ListEntry);
|
||||
|
||||
//
|
||||
// Fill in the DPC entry with the DpcProcedure and DpcContext
|
||||
//
|
||||
DpcEntry->DpcProcedure = DpcProcedure;
|
||||
DpcEntry->DpcContext = DpcContext;
|
||||
|
||||
//
|
||||
// Add the DPC entry to the end of the list for the specified DplTpl.
|
||||
//
|
||||
InsertTailList (&mDpcQueue[DpcTpl], &DpcEntry->ListEntry);
|
||||
|
||||
//
|
||||
// Increment the measured DPC queue depth across all TPLs
|
||||
//
|
||||
mDpcQueueDepth++;
|
||||
|
||||
//
|
||||
// Measure the maximum DPC queue depth across all TPLs
|
||||
//
|
||||
if (mDpcQueueDepth > mMaxDpcQueueDepth) {
|
||||
mMaxDpcQueueDepth = mDpcQueueDepth;
|
||||
}
|
||||
|
||||
Done:
|
||||
//
|
||||
// Restore the original TPL level when this function was called
|
||||
//
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl
|
||||
value greater than or equal to the current TPL are invoked in the order that
|
||||
they were queued. DPCs with higher DpcTpl values are invoked before DPCs with
|
||||
lower DpcTpl values.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
|
||||
@retval EFI_SUCCESS One or more DPCs were invoked.
|
||||
@retval EFI_NOT_FOUND No DPCs were invoked.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DpcDispatchDpc (
|
||||
IN EFI_DPC_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
EFI_STATUS ReturnStatus;
|
||||
EFI_TPL OriginalTpl;
|
||||
EFI_TPL Tpl;
|
||||
DPC_ENTRY *DpcEntry;
|
||||
|
||||
//
|
||||
// Assume that no DPCs will be invoked
|
||||
//
|
||||
ReturnStatus = EFI_NOT_FOUND;
|
||||
|
||||
//
|
||||
// Raise the TPL level to TPL_HIGH_LEVEL for DPC list operation and save the
|
||||
// current TPL value so it can be restored when this function returns.
|
||||
//
|
||||
OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
//
|
||||
// Check to see if there are 1 or more DPCs currently queued
|
||||
//
|
||||
if (mDpcQueueDepth > 0) {
|
||||
//
|
||||
// Loop from TPL_HIGH_LEVEL down to the current TPL value
|
||||
//
|
||||
for (Tpl = TPL_HIGH_LEVEL; Tpl >= OriginalTpl; Tpl--) {
|
||||
//
|
||||
// Check to see if the DPC queue is empty
|
||||
//
|
||||
while (!IsListEmpty (&mDpcQueue[Tpl])) {
|
||||
//
|
||||
// Retrieve the first DPC entry from the DPC queue specified by Tpl
|
||||
//
|
||||
DpcEntry = (DPC_ENTRY *)(GetFirstNode (&mDpcQueue[Tpl]));
|
||||
|
||||
//
|
||||
// Remove the first DPC entry from the DPC queue specified by Tpl
|
||||
//
|
||||
RemoveEntryList (&DpcEntry->ListEntry);
|
||||
|
||||
//
|
||||
// Decrement the measured DPC Queue Depth across all TPLs
|
||||
//
|
||||
mDpcQueueDepth--;
|
||||
|
||||
//
|
||||
// Lower the TPL to TPL value of the current DPC queue
|
||||
//
|
||||
gBS->RestoreTPL (Tpl);
|
||||
|
||||
//
|
||||
// Invoke the DPC passing in its context
|
||||
//
|
||||
(DpcEntry->DpcProcedure) (DpcEntry->DpcContext);
|
||||
|
||||
//
|
||||
// At least one DPC has been invoked, so set the return status to EFI_SUCCESS
|
||||
//
|
||||
ReturnStatus = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Raise the TPL level back to TPL_HIGH_LEVEL for DPC list operations
|
||||
//
|
||||
gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
//
|
||||
// Add the invoked DPC entry to the DPC free list
|
||||
//
|
||||
InsertTailList (&mDpcEntryFreeList, &DpcEntry->ListEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Restore the original TPL level when this function was called
|
||||
//
|
||||
gBS->RestoreTPL (OriginalTpl);
|
||||
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
The entry point for DPC driver which installs the EFI_DPC_PROTOCOL onto a new handle.
|
||||
|
||||
@param ImageHandle The image handle of the driver.
|
||||
@param SystemTable The system table.
|
||||
|
||||
@retval EFI_SUCCES The DPC queues were initialized and the EFI_DPC_PROTOCOL was
|
||||
installed onto a new handle.
|
||||
@retval Others Failed to install EFI_DPC_PROTOCOL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DpcDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
|
||||
//
|
||||
// ASSERT() if the EFI_DPC_PROTOCOL is already present in the handle database
|
||||
//
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiDpcProtocolGuid);
|
||||
|
||||
//
|
||||
// Initialize the DPC queue for all possible TPL values
|
||||
//
|
||||
for (Index = 0; Index <= TPL_HIGH_LEVEL; Index++) {
|
||||
InitializeListHead (&mDpcQueue[Index]);
|
||||
}
|
||||
|
||||
//
|
||||
// Install the EFI_DPC_PROTOCOL instance onto a new handle
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mDpcHandle,
|
||||
&gEfiDpcProtocolGuid,
|
||||
&mDpc,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
Module Name:
|
||||
|
||||
Dpc.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _DPC_H_
|
||||
#define _DPC_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Protocol/Dpc.h>
|
||||
|
||||
//
|
||||
// Internal data struture for managing DPCs. A DPC entry is either on the free
|
||||
// list or on a DPC queue at a specific EFI_TPL.
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY ListEntry;
|
||||
EFI_DPC_PROCEDURE DpcProcedure;
|
||||
VOID *DpcContext;
|
||||
} DPC_ENTRY;
|
||||
|
||||
/**
|
||||
Add a Deferred Procedure Call to the end of the DPC queue.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param DpcTpl The EFI_TPL that the DPC should be invoked.
|
||||
@param DpcProcedure Pointer to the DPC's function.
|
||||
@param DpcContext Pointer to the DPC's context. Passed to DpcProcedure
|
||||
when DpcProcedure is invoked.
|
||||
|
||||
@retval EFI_SUCCESS The DPC was queued.
|
||||
@retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL.
|
||||
@retval EFI_INVALID_PARAMETER DpcProcedure is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to
|
||||
add the DPC to the queue.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DpcQueueDpc (
|
||||
IN EFI_DPC_PROTOCOL *This,
|
||||
IN EFI_TPL DpcTpl,
|
||||
IN EFI_DPC_PROCEDURE DpcProcedure,
|
||||
IN VOID *DpcContext OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl
|
||||
value greater than or equal to the current TPL are invoked in the order that
|
||||
they were queued. DPCs with higher DpcTpl values are invoked before DPCs with
|
||||
lower DpcTpl values.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
|
||||
@retval EFI_SUCCESS One or more DPCs were invoked.
|
||||
@retval EFI_NOT_FOUND No DPCs were invoked.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DpcDispatchDpc (
|
||||
IN EFI_DPC_PROTOCOL *This
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
## @file
|
||||
# This module produces Deferred Procedure Call Protocol.
|
||||
#
|
||||
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DpcDxe
|
||||
MODULE_UNI_FILE = DpcDxe.uni
|
||||
FILE_GUID = A210F973-229D-4f4d-AA37-9895E6C9EABA
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = DpcDriverEntryPoint
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 EBC
|
||||
#
|
||||
|
||||
[Sources]
|
||||
Dpc.c
|
||||
Dpc.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
NetworkPkg/NetworkPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
BaseLib
|
||||
DebugLib
|
||||
UefiBootServicesTableLib
|
||||
MemoryAllocationLib
|
||||
|
||||
[Protocols]
|
||||
gEfiDpcProtocolGuid ## PRODUCES
|
||||
|
||||
[Depex]
|
||||
TRUE
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
DpcDxeExtra.uni
|
|
@ -0,0 +1,16 @@
|
|||
// /** @file
|
||||
// This module produces Deferred Procedure Call Protocol.
|
||||
//
|
||||
// This module produces Deferred Procedure Call Protocol.
|
||||
//
|
||||
// Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "Produces Deferred Procedure Call Protocol"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This module produces Deferred Procedure Call Protocol."
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// /** @file
|
||||
// DpcDxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"Deferred Procedure Call DXE Driver"
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,137 @@
|
|||
/** @file
|
||||
Declaration of the boot file download function.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_BOOT_HTTP_H__
|
||||
#define __EFI_HTTP_BOOT_HTTP_H__
|
||||
|
||||
#define HTTP_BOOT_REQUEST_TIMEOUT 5000 // 5 seconds in uints of millisecond.
|
||||
#define HTTP_BOOT_RESPONSE_TIMEOUT 5000 // 5 seconds in uints of millisecond.
|
||||
#define HTTP_BOOT_BLOCK_SIZE 1500
|
||||
|
||||
|
||||
|
||||
#define HTTP_USER_AGENT_EFI_HTTP_BOOT "UefiHttpBoot/1.0"
|
||||
|
||||
//
|
||||
// Record the data length and start address of a data block.
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY Link; // Link to the EntityDataList in HTTP_BOOT_CACHE_CONTENT
|
||||
UINT8 *Block; // If NULL, the data is in previous data block.
|
||||
UINT8 *DataStart; // Point to somewhere in the Block
|
||||
UINTN DataLength;
|
||||
} HTTP_BOOT_ENTITY_DATA;
|
||||
|
||||
//
|
||||
// Structure for a cache item
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY Link; // Link to the CacheList in driver's private data.
|
||||
EFI_HTTP_REQUEST_DATA *RequestData;
|
||||
HTTP_IO_RESPONSE_DATA *ResponseData; // Not include any message-body data.
|
||||
HTTP_BOOT_IMAGE_TYPE ImageType;
|
||||
UINTN EntityLength;
|
||||
LIST_ENTRY EntityDataList; // Entity data (message-body)
|
||||
} HTTP_BOOT_CACHE_CONTENT;
|
||||
|
||||
//
|
||||
// Callback data for HTTP_BODY_PARSER_CALLBACK()
|
||||
//
|
||||
typedef struct {
|
||||
EFI_STATUS Status;
|
||||
//
|
||||
// Cache info.
|
||||
//
|
||||
HTTP_BOOT_CACHE_CONTENT *Cache;
|
||||
BOOLEAN NewBlock;
|
||||
UINT8 *Block;
|
||||
|
||||
//
|
||||
// Caller provided buffer to load the file in.
|
||||
//
|
||||
UINTN CopyedSize;
|
||||
UINTN BufferSize;
|
||||
UINT8 *Buffer;
|
||||
|
||||
HTTP_BOOT_PRIVATE_DATA *Private;
|
||||
} HTTP_BOOT_CALLBACK_DATA;
|
||||
|
||||
/**
|
||||
Discover all the boot information for boot file.
|
||||
|
||||
@param[in, out] Private The pointer to the driver's private data.
|
||||
|
||||
@retval EFI_SUCCESS Successfully obtained all the boot information .
|
||||
@retval Others Failed to retrieve the boot information.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootDiscoverBootInfo (
|
||||
IN OUT HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
Create a HttpIo instance for the file download.
|
||||
|
||||
@param[in] Private The pointer to the driver's private data.
|
||||
|
||||
@retval EFI_SUCCESS Successfully created.
|
||||
@retval Others Failed to create HttpIo.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootCreateHttpIo (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
This function download the boot file by using UEFI HTTP protocol.
|
||||
|
||||
@param[in] Private The pointer to the driver's private data.
|
||||
@param[in] HeaderOnly Only request the response header, it could save a lot of time if
|
||||
the caller only want to know the size of the requested file.
|
||||
@param[in, out] BufferSize On input the size of Buffer in bytes. On output with a return
|
||||
code of EFI_SUCCESS, the amount of data transferred to
|
||||
Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
|
||||
the size of Buffer required to retrieve the requested file.
|
||||
@param[out] Buffer The memory buffer to transfer the file to. IF Buffer is NULL,
|
||||
then the size of the requested file is returned in
|
||||
BufferSize.
|
||||
@param[out] ImageType The image type of the downloaded file.
|
||||
|
||||
@retval EFI_SUCCESS The file was loaded.
|
||||
@retval EFI_INVALID_PARAMETER BufferSize is NULL or Buffer Size is not NULL but Buffer is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
|
||||
@retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
|
||||
BufferSize has been updated with the size needed to complete
|
||||
the request.
|
||||
@retval Others Unexpected error happened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootGetBootFile (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN BOOLEAN HeaderOnly,
|
||||
IN OUT UINTN *BufferSize,
|
||||
OUT UINT8 *Buffer,
|
||||
OUT HTTP_BOOT_IMAGE_TYPE *ImageType
|
||||
);
|
||||
|
||||
/**
|
||||
Clean up all cached data.
|
||||
|
||||
@param[in] Private The pointer to the driver's private data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpBootFreeCacheList (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,177 @@
|
|||
/** @file
|
||||
Implementation of EFI_COMPONENT_NAME_PROTOCOL and EFI_COMPONENT_NAME2_PROTOCOL protocol.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpBootDxe.h"
|
||||
|
||||
///
|
||||
/// Component Name Protocol instance
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_COMPONENT_NAME_PROTOCOL gHttpBootDxeComponentName = {
|
||||
(EFI_COMPONENT_NAME_GET_DRIVER_NAME) HttpBootDxeComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME_GET_CONTROLLER_NAME)HttpBootDxeComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
///
|
||||
/// Component Name 2 Protocol instance
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_COMPONENT_NAME2_PROTOCOL gHttpBootDxeComponentName2 = {
|
||||
HttpBootDxeComponentNameGetDriverName,
|
||||
HttpBootDxeComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
///
|
||||
/// Table of driver names
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_UNICODE_STRING_TABLE mHttpBootDxeDriverNameTable[] = {
|
||||
{ "eng;en", (CHAR16 *)L"UEFI HTTP Boot Driver" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
///
|
||||
/// Table of controller names
|
||||
///
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
EFI_UNICODE_STRING_TABLE mHttpBootDxeControllerNameTable[] = {
|
||||
{ "eng;en", (CHAR16 *)L"UEFI Http Boot Controller" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param Language A pointer to a three-character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
@param DriverName A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootDxeComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mHttpBootDxeDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN) (This != &gHttpBootDxeComponentName2)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param ControllerHandle The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
@param ChildHandle The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
@param Language A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
@param ControllerName A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language, from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootDxeComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NicHandle;
|
||||
UINT32 *Id;
|
||||
|
||||
if (ControllerHandle == NULL || ChildHandle != NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
NicHandle = HttpBootGetNicByIp4Children (ControllerHandle);
|
||||
if (NicHandle == NULL) {
|
||||
NicHandle = HttpBootGetNicByIp6Children(ControllerHandle);
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Try to retrieve the private data by caller ID GUID.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiCallerIdGuid,
|
||||
(VOID **) &Id,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mHttpBootDxeControllerNameTable,
|
||||
ControllerName,
|
||||
(BOOLEAN)(This != &gHttpBootDxeComponentName2)
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/** @file
|
||||
Declaration of HTTP boot driver's EFI_COMPONENT_NAME_PROTOCOL and
|
||||
EFI_COMPONENT_NAME2_PROTOCOL function.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_UEFI_HTTP_BOOT_COM_NAME_H__
|
||||
#define __EFI_UEFI_HTTP_BOOT_COM_NAME_H__
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user-readable name of the EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param Language A pointer to a three-character ISO 639-2 language identifier.
|
||||
This is the language of the driver name that that the caller
|
||||
is requesting, and it must match one of the languages specified
|
||||
in SupportedLanguages. The number of languages supported by a
|
||||
driver is up to the driver writer.
|
||||
@param DriverName A pointer to the Unicode string to return. This Unicode string
|
||||
is the name of the driver specified by This in the language
|
||||
specified by Language.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootDxeComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
@param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
@param ControllerHandle The handle of a controller that the driver specified by
|
||||
This is managing. This handle specifies the controller
|
||||
whose name is to be returned.
|
||||
@param ChildHandle The handle of the child controller to retrieve the name
|
||||
of. This is an optional parameter that may be NULL. It
|
||||
will be NULL for device drivers. It will also be NULL
|
||||
for a bus drivers that wish to retrieve the name of the
|
||||
bus controller. It will not be NULL for a bus driver
|
||||
that wishes to retrieve the name of a child controller.
|
||||
@param Language A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller name
|
||||
that the caller is requesting, and it must match one
|
||||
of the languages specified in SupportedLanguages. The
|
||||
number of languages supported by a driver is up to the
|
||||
driver writer.
|
||||
@param ControllerName A pointer to the Unicode string to return. This Unicode
|
||||
string is the name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the language specified
|
||||
by Language, from the point of view of the driver specified
|
||||
by This.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the user-readable name in the
|
||||
language specified by Language for the driver
|
||||
specified by This was returned in DriverName.
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE.
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently managing
|
||||
the controller specified by ControllerHandle and
|
||||
ChildHandle.
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootDxeComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME2_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,700 @@
|
|||
/** @file
|
||||
Helper functions for configuring or getting the parameters relating to HTTP Boot.
|
||||
|
||||
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpBootDxe.h"
|
||||
#include <Library/UefiBootManagerLib.h>
|
||||
|
||||
CHAR16 mHttpBootConfigStorageName[] = L"HTTP_BOOT_CONFIG_IFR_NVDATA";
|
||||
|
||||
/**
|
||||
Add new boot option for HTTP boot.
|
||||
|
||||
@param[in] Private Pointer to the driver private data.
|
||||
@param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6.
|
||||
@param[in] Description The description text of the boot option.
|
||||
@param[in] Uri The URI string of the boot file.
|
||||
|
||||
@retval EFI_SUCCESS The boot option is created successfully.
|
||||
@retval Others Failed to create new boot option.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootAddBootOption (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN BOOLEAN UsingIpv6,
|
||||
IN CHAR16 *Description,
|
||||
IN CHAR16 *Uri
|
||||
)
|
||||
{
|
||||
EFI_DEV_PATH *Node;
|
||||
EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
|
||||
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
||||
UINTN Length;
|
||||
CHAR8 AsciiUri[URI_STR_MAX_SIZE];
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
|
||||
|
||||
NewDevicePath = NULL;
|
||||
Node = NULL;
|
||||
TmpDevicePath = NULL;
|
||||
|
||||
if (StrLen (Description) == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Convert the scheme to all lower case.
|
||||
//
|
||||
for (Index = 0; Index < StrLen (Uri); Index++) {
|
||||
if (Uri[Index] == L':') {
|
||||
break;
|
||||
}
|
||||
if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
|
||||
Uri[Index] -= (CHAR16)(L'A' - L'a');
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Only accept empty URI, or http and https URI.
|
||||
//
|
||||
if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 8) != 0)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a new device path by appending the IP node and URI node to
|
||||
// the driver's parent device path
|
||||
//
|
||||
if (!UsingIpv6) {
|
||||
Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
|
||||
if (Node == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
|
||||
Node->Ipv4.Header.SubType = MSG_IPv4_DP;
|
||||
SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
|
||||
} else {
|
||||
Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
|
||||
if (Node == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
|
||||
Node->Ipv6.Header.SubType = MSG_IPv6_DP;
|
||||
SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
|
||||
}
|
||||
TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
|
||||
FreePool (Node);
|
||||
if (TmpDevicePath == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// Update the URI node with the input boot file URI.
|
||||
//
|
||||
UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri));
|
||||
Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);
|
||||
Node = AllocatePool (Length);
|
||||
if (Node == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
FreePool (TmpDevicePath);
|
||||
goto ON_EXIT;
|
||||
}
|
||||
Node->DevPath.Type = MESSAGING_DEVICE_PATH;
|
||||
Node->DevPath.SubType = MSG_URI_DP;
|
||||
SetDevicePathNodeLength (Node, Length);
|
||||
CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri));
|
||||
NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
|
||||
FreePool (Node);
|
||||
FreePool (TmpDevicePath);
|
||||
if (NewDevicePath == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Add a new load option.
|
||||
//
|
||||
Status = EfiBootManagerInitializeLoadOption (
|
||||
&NewOption,
|
||||
LoadOptionNumberUnassigned,
|
||||
LoadOptionTypeBoot,
|
||||
LOAD_OPTION_ACTIVE,
|
||||
Description,
|
||||
NewDevicePath,
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);
|
||||
EfiBootManagerFreeLoadOption (&NewOption);
|
||||
|
||||
ON_EXIT:
|
||||
|
||||
if (NewDevicePath != NULL) {
|
||||
FreePool (NewDevicePath);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
This function allows the caller to request the current
|
||||
configuration for one or more named elements. The resulting
|
||||
string is in <ConfigAltResp> format. Also, any and all alternative
|
||||
configuration strings shall be appended to the end of the
|
||||
current configuration string. If they are, they must appear
|
||||
after the current configuration. They must contain the same
|
||||
routing (GUID, NAME, PATH) as the current configuration string.
|
||||
They must have an additional description indicating the type of
|
||||
alternative configuration the string represents,
|
||||
"ALTCFG=<StringToken>". That <StringToken> (when
|
||||
converted from Hex UNICODE to binary) is a reference to a
|
||||
string in the associated string pack.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
|
||||
@param[in] Request A null-terminated Unicode string in
|
||||
<ConfigRequest> format. Note that this
|
||||
includes the routing information as well as
|
||||
the configurable name / value pairs. It is
|
||||
invalid for this string to be in
|
||||
<MultiConfigRequest> format.
|
||||
|
||||
@param[out] Progress On return, points to a character in the
|
||||
Request string. Points to the string's null
|
||||
terminator if request was successful. Points
|
||||
to the most recent "&" before the first
|
||||
failing name / value pair (or the beginning
|
||||
of the string if the failure is in the first
|
||||
name / value pair) if the request was not successful.
|
||||
|
||||
@param[out] Results A null-terminated Unicode string in
|
||||
<ConfigAltResp> format which has all values
|
||||
filled in for the names in the Request string.
|
||||
String to be allocated by the called function.
|
||||
|
||||
@retval EFI_SUCCESS The Results string is filled with the
|
||||
values corresponding to all requested
|
||||
names.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the
|
||||
parts of the results that must be
|
||||
stored awaiting possible future
|
||||
protocols.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER For example, passing in a NULL
|
||||
for the Request parameter
|
||||
would result in this type of
|
||||
error. In this case, the
|
||||
Progress parameter would be
|
||||
set to NULL.
|
||||
|
||||
@retval EFI_NOT_FOUND Routing data doesn't match any
|
||||
known driver. Progress set to the
|
||||
first character in the routing header.
|
||||
Note: There is no requirement that the
|
||||
driver validate the routing data. It
|
||||
must skip the <ConfigHdr> in order to
|
||||
process the names.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
|
||||
to most recent "&" before the
|
||||
error or the beginning of the
|
||||
string.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Unknown name. Progress points
|
||||
to the & before the name in
|
||||
question.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootFormExtractConfig (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN CONST EFI_STRING Request,
|
||||
OUT EFI_STRING *Progress,
|
||||
OUT EFI_STRING *Results
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
||||
EFI_STRING ConfigRequestHdr;
|
||||
EFI_STRING ConfigRequest;
|
||||
BOOLEAN AllocatedRequest;
|
||||
UINTN Size;
|
||||
|
||||
if (Progress == NULL || Results == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*Progress = Request;
|
||||
if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
ConfigRequestHdr = NULL;
|
||||
ConfigRequest = NULL;
|
||||
AllocatedRequest = FALSE;
|
||||
Size = 0;
|
||||
|
||||
CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
|
||||
//
|
||||
// Convert buffer data to <ConfigResp> by helper function BlockToConfig()
|
||||
//
|
||||
BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
|
||||
ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
|
||||
StrCpyS (CallbackInfo->HttpBootNvData.Description, DESCRIPTION_STR_MAX_SIZE / sizeof (CHAR16), HTTP_BOOT_DEFAULT_DESCRIPTION_STR);
|
||||
|
||||
ConfigRequest = Request;
|
||||
if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
|
||||
//
|
||||
// Request has no request element, construct full request string.
|
||||
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
|
||||
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
|
||||
//
|
||||
ConfigRequestHdr = HiiConstructConfigHdr (&gHttpBootConfigGuid, mHttpBootConfigStorageName, CallbackInfo->ChildHandle);
|
||||
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
|
||||
ConfigRequest = AllocateZeroPool (Size);
|
||||
if (ConfigRequest == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
AllocatedRequest = TRUE;
|
||||
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
|
||||
FreePool (ConfigRequestHdr);
|
||||
}
|
||||
|
||||
Status = gHiiConfigRouting->BlockToConfig (
|
||||
gHiiConfigRouting,
|
||||
ConfigRequest,
|
||||
(UINT8 *) &CallbackInfo->HttpBootNvData,
|
||||
BufferSize,
|
||||
Results,
|
||||
Progress
|
||||
);
|
||||
|
||||
//
|
||||
// Free the allocated config request string.
|
||||
//
|
||||
if (AllocatedRequest) {
|
||||
FreePool (ConfigRequest);
|
||||
ConfigRequest = NULL;
|
||||
}
|
||||
//
|
||||
// Set Progress string to the original request string.
|
||||
//
|
||||
if (Request == NULL) {
|
||||
*Progress = NULL;
|
||||
} else if (StrStr (Request, L"OFFSET") == NULL) {
|
||||
*Progress = Request + StrLen (Request);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
This function applies changes in a driver's configuration.
|
||||
Input is a Configuration, which has the routing data for this
|
||||
driver followed by name / value configuration pairs. The driver
|
||||
must apply those pairs to its configurable storage. If the
|
||||
driver's configuration is stored in a linear block of data
|
||||
and the driver's name / value pairs are in <BlockConfig>
|
||||
format, it may use the ConfigToBlock helper function (above) to
|
||||
simplify the job.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
|
||||
@param[in] Configuration A null-terminated Unicode string in
|
||||
<ConfigString> format.
|
||||
|
||||
@param[out] Progress A pointer to a string filled in with the
|
||||
offset of the most recent '&' before the
|
||||
first failing name / value pair (or the
|
||||
beginning of the string if the failure
|
||||
is in the first name / value pair) or
|
||||
the terminating NULL if all was
|
||||
successful.
|
||||
|
||||
@retval EFI_SUCCESS The results have been distributed or are
|
||||
awaiting distribution.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the
|
||||
parts of the results that must be
|
||||
stored awaiting possible future
|
||||
protocols.
|
||||
|
||||
@retval EFI_INVALID_PARAMETERS Passing in a NULL for the
|
||||
Results parameter would result
|
||||
in this type of error.
|
||||
|
||||
@retval EFI_NOT_FOUND Target for the specified routing data
|
||||
was not found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootFormRouteConfig (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN CONST EFI_STRING Configuration,
|
||||
OUT EFI_STRING *Progress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
||||
HTTP_BOOT_PRIVATE_DATA *Private;
|
||||
|
||||
if (Progress == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
*Progress = Configuration;
|
||||
|
||||
if (Configuration == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Check routing data in <ConfigHdr>.
|
||||
// Note: there is no name for Name/Value storage, only GUID will be checked
|
||||
//
|
||||
if (!HiiIsConfigHdrMatch (Configuration, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
|
||||
Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO (CallbackInfo);
|
||||
|
||||
BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);
|
||||
ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);
|
||||
|
||||
Status = gHiiConfigRouting->ConfigToBlock (
|
||||
gHiiConfigRouting,
|
||||
Configuration,
|
||||
(UINT8 *) &CallbackInfo->HttpBootNvData,
|
||||
&BufferSize,
|
||||
Progress
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a new boot option according to the configuration data.
|
||||
//
|
||||
HttpBootAddBootOption (
|
||||
Private,
|
||||
(CallbackInfo->HttpBootNvData.IpVersion == HTTP_BOOT_IP_VERSION_6) ? TRUE : FALSE,
|
||||
CallbackInfo->HttpBootNvData.Description,
|
||||
CallbackInfo->HttpBootNvData.Uri
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
This function is called to provide results data to the driver.
|
||||
This data consists of a unique key that is used to identify
|
||||
which data is either being passed back or being asked for.
|
||||
|
||||
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
||||
@param[in] Action Specifies the type of action taken by the browser.
|
||||
@param[in] QuestionId A unique value which is sent to the original
|
||||
exporting driver so that it can identify the type
|
||||
of data to expect. The format of the data tends to
|
||||
vary based on the opcode that generated the callback.
|
||||
@param[in] Type The type of value for the question.
|
||||
@param[in, out] Value A pointer to the data being sent to the original
|
||||
exporting driver.
|
||||
@param[out] ActionRequest On return, points to the action requested by the
|
||||
callback function.
|
||||
|
||||
@retval EFI_SUCCESS The callback successfully handled the action.
|
||||
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
|
||||
variable and its data.
|
||||
@retval EFI_DEVICE_ERROR The variable could not be saved.
|
||||
@retval EFI_UNSUPPORTED The specified Action is not supported by the
|
||||
callback.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootFormCallback (
|
||||
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
||||
IN EFI_BROWSER_ACTION Action,
|
||||
IN EFI_QUESTION_ID QuestionId,
|
||||
IN UINT8 Type,
|
||||
IN OUT EFI_IFR_TYPE_VALUE *Value,
|
||||
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
||||
)
|
||||
{
|
||||
EFI_INPUT_KEY Key;
|
||||
CHAR16 *Uri;
|
||||
UINTN UriLen;
|
||||
CHAR8 *AsciiUri;
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Uri = NULL;
|
||||
UriLen = 0;
|
||||
AsciiUri = NULL;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
if (This == NULL || Value == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
|
||||
|
||||
if (Action != EFI_BROWSER_ACTION_CHANGING) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
switch (QuestionId) {
|
||||
case KEY_INITIATOR_URI:
|
||||
//
|
||||
// Get user input URI string
|
||||
//
|
||||
Uri = HiiGetString (CallbackInfo->RegisteredHandle, Value->string, NULL);
|
||||
if(Uri == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// The URI should be either an empty string (for corporate environment) ,or http(s) for home environment.
|
||||
// Pop up a message box for the unsupported URI.
|
||||
//
|
||||
if (StrLen (Uri) != 0) {
|
||||
UriLen = StrLen (Uri) + 1;
|
||||
AsciiUri = AllocateZeroPool (UriLen);
|
||||
if (AsciiUri == NULL) {
|
||||
FreePool (Uri);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
UnicodeStrToAsciiStrS (Uri, AsciiUri, UriLen);
|
||||
|
||||
Status = HttpBootCheckUriScheme (AsciiUri);
|
||||
|
||||
if (Status == EFI_INVALID_PARAMETER) {
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "HttpBootFormCallback: %r.\n", Status));
|
||||
|
||||
CreatePopUp (
|
||||
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
||||
&Key,
|
||||
L"ERROR: Unsupported URI!",
|
||||
L"Only supports HTTP and HTTPS",
|
||||
NULL
|
||||
);
|
||||
} else if (Status == EFI_ACCESS_DENIED) {
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "HttpBootFormCallback: %r.\n", Status));
|
||||
|
||||
CreatePopUp (
|
||||
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
|
||||
&Key,
|
||||
L"ERROR: Unsupported URI!",
|
||||
L"HTTP is disabled",
|
||||
NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Uri != NULL) {
|
||||
FreePool (Uri);
|
||||
}
|
||||
|
||||
if (AsciiUri != NULL) {
|
||||
FreePool (AsciiUri);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize the configuration form.
|
||||
|
||||
@param[in] Private Pointer to the driver private data.
|
||||
|
||||
@retval EFI_SUCCESS The configuration form is initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootConfigFormInit (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
||||
VENDOR_DEVICE_PATH VendorDeviceNode;
|
||||
CHAR16 *MacString;
|
||||
CHAR16 *OldMenuString;
|
||||
CHAR16 MenuString[128];
|
||||
|
||||
CallbackInfo = &Private->CallbackInfo;
|
||||
|
||||
if (CallbackInfo->Initilized) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
CallbackInfo->Signature = HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE;
|
||||
|
||||
//
|
||||
// Construct device path node for EFI HII Config Access protocol,
|
||||
// which consists of controller physical device path and one hardware
|
||||
// vendor guid node.
|
||||
//
|
||||
ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
|
||||
VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;
|
||||
VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
|
||||
CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);
|
||||
SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
|
||||
CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
|
||||
Private->ParentDevicePath,
|
||||
(EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode
|
||||
);
|
||||
if (CallbackInfo->HiiVendorDevicePath == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
CallbackInfo->ConfigAccess.ExtractConfig = HttpBootFormExtractConfig;
|
||||
CallbackInfo->ConfigAccess.RouteConfig = HttpBootFormRouteConfig;
|
||||
CallbackInfo->ConfigAccess.Callback = HttpBootFormCallback;
|
||||
|
||||
//
|
||||
// Install Device Path Protocol and Config Access protocol to driver handle.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&CallbackInfo->ChildHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
CallbackInfo->HiiVendorDevicePath,
|
||||
&gEfiHiiConfigAccessProtocolGuid,
|
||||
&CallbackInfo->ConfigAccess,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Error;
|
||||
}
|
||||
|
||||
//
|
||||
// Publish our HII data.
|
||||
//
|
||||
CallbackInfo->RegisteredHandle = HiiAddPackages (
|
||||
&gHttpBootConfigGuid,
|
||||
CallbackInfo->ChildHandle,
|
||||
HttpBootDxeStrings,
|
||||
HttpBootConfigVfrBin,
|
||||
NULL
|
||||
);
|
||||
if (CallbackInfo->RegisteredHandle == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
//
|
||||
// Append MAC string in the menu help string
|
||||
//
|
||||
Status = NetLibGetMacString (Private->Controller, NULL, &MacString);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
OldMenuString = HiiGetString (
|
||||
CallbackInfo->RegisteredHandle,
|
||||
STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),
|
||||
NULL
|
||||
);
|
||||
UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
|
||||
HiiSetString (
|
||||
CallbackInfo->RegisteredHandle,
|
||||
STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),
|
||||
MenuString,
|
||||
NULL
|
||||
);
|
||||
|
||||
FreePool (MacString);
|
||||
FreePool (OldMenuString);
|
||||
|
||||
CallbackInfo->Initilized = TRUE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Error:
|
||||
|
||||
HttpBootConfigFormUnload (Private);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Unload the configuration form, this includes: delete all the configuration
|
||||
entries, uninstall the form callback protocol, and free the resources used.
|
||||
The form will only be unload completely when both IP4 and IP6 stack are stopped.
|
||||
|
||||
@param[in] Private Pointer to the driver private data.
|
||||
|
||||
@retval EFI_SUCCESS The configuration form is unloaded.
|
||||
@retval Others Failed to unload the form.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootConfigFormUnload (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
)
|
||||
{
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;
|
||||
|
||||
if (Private->Ip4Nic != NULL || Private->Ip6Nic != NULL) {
|
||||
//
|
||||
// Only unload the configuration form when both IP4 and IP6 stack are stopped.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
CallbackInfo = &Private->CallbackInfo;
|
||||
if (CallbackInfo->ChildHandle != NULL) {
|
||||
//
|
||||
// Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
|
||||
//
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
CallbackInfo->ChildHandle,
|
||||
&gEfiDevicePathProtocolGuid,
|
||||
CallbackInfo->HiiVendorDevicePath,
|
||||
&gEfiHiiConfigAccessProtocolGuid,
|
||||
&CallbackInfo->ConfigAccess,
|
||||
NULL
|
||||
);
|
||||
CallbackInfo->ChildHandle = NULL;
|
||||
}
|
||||
|
||||
if (CallbackInfo->HiiVendorDevicePath != NULL) {
|
||||
FreePool (CallbackInfo->HiiVendorDevicePath);
|
||||
CallbackInfo->HiiVendorDevicePath = NULL;
|
||||
}
|
||||
|
||||
if (CallbackInfo->RegisteredHandle != NULL) {
|
||||
//
|
||||
// Remove HII package list
|
||||
//
|
||||
HiiRemovePackages (CallbackInfo->RegisteredHandle);
|
||||
CallbackInfo->RegisteredHandle = NULL;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/** @file
|
||||
The header file of functions for configuring or getting the parameters
|
||||
relating to HTTP Boot.
|
||||
|
||||
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _HTTP_BOOT_CONFIG_H_
|
||||
#define _HTTP_BOOT_CONFIG_H_
|
||||
|
||||
|
||||
#include "HttpBootConfigNVDataStruc.h"
|
||||
|
||||
typedef struct _HTTP_BOOT_FORM_CALLBACK_INFO HTTP_BOOT_FORM_CALLBACK_INFO;
|
||||
|
||||
extern UINT8 HttpBootDxeStrings[];
|
||||
extern UINT8 HttpBootConfigVfrBin[];
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#define HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('H', 'B', 'f', 'c')
|
||||
|
||||
#define HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(Callback) \
|
||||
CR ( \
|
||||
Callback, \
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO, \
|
||||
ConfigAccess, \
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE \
|
||||
)
|
||||
|
||||
struct _HTTP_BOOT_FORM_CALLBACK_INFO {
|
||||
UINT32 Signature;
|
||||
BOOLEAN Initilized;
|
||||
EFI_HANDLE ChildHandle;
|
||||
EFI_DEVICE_PATH_PROTOCOL *HiiVendorDevicePath;
|
||||
EFI_HII_HANDLE RegisteredHandle;
|
||||
EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
|
||||
HTTP_BOOT_CONFIG_IFR_NVDATA HttpBootNvData;
|
||||
};
|
||||
|
||||
/**
|
||||
Initialize the configuration form.
|
||||
|
||||
@param[in] Private Pointer to the driver private data.
|
||||
|
||||
@retval EFI_SUCCESS The configuration form is initialized.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootConfigFormInit (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
Unload the configuration form, this includes: delete all the configuration
|
||||
entries, uninstall the form callback protocol, and free the resources used.
|
||||
The form will only be unload completely when both IP4 and IP6 stack are stopped.
|
||||
|
||||
@param[in] Private Pointer to the driver private data.
|
||||
|
||||
@retval EFI_SUCCESS The configuration form is unloaded.
|
||||
@retval Others Failed to unload the form.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootConfigFormUnload (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
/** @file
|
||||
Define NVData structures used by the HTTP Boot configuration component.
|
||||
|
||||
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _HTTP_BOOT_NVDATA_STRUC_H_
|
||||
#define _HTTP_BOOT_NVDATA_STRUC_H_
|
||||
|
||||
#include <Guid/HttpBootConfigHii.h>
|
||||
|
||||
#define HTTP_BOOT_IP_VERSION_4 0
|
||||
#define HTTP_BOOT_IP_VERSION_6 1
|
||||
|
||||
//
|
||||
// Macros used for an IPv4 or an IPv6 address.
|
||||
//
|
||||
#define URI_STR_MIN_SIZE 0
|
||||
#define URI_STR_MAX_SIZE 255
|
||||
|
||||
#define DESCRIPTION_STR_MIN_SIZE 6
|
||||
#define DESCRIPTION_STR_MAX_SIZE 75
|
||||
|
||||
#define CONFIGURATION_VARSTORE_ID 0x1234
|
||||
|
||||
#define FORMID_MAIN_FORM 1
|
||||
|
||||
#define KEY_INITIATOR_URI 0x101
|
||||
|
||||
#define HTTP_BOOT_DEFAULT_DESCRIPTION_STR L"UEFI HTTP"
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _HTTP_BOOT_CONFIG_IFR_NVDATA {
|
||||
UINT8 IpVersion;
|
||||
UINT8 Padding;
|
||||
CHAR16 Description[DESCRIPTION_STR_MAX_SIZE];
|
||||
CHAR16 Uri[URI_STR_MAX_SIZE];
|
||||
} HTTP_BOOT_CONFIG_IFR_NVDATA;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,21 @@
|
|||
/** @file
|
||||
String definitions for HTTP Boot configuration.
|
||||
|
||||
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#langdef en-US "English"
|
||||
|
||||
#string STR_HTTP_BOOT_CONFIG_FORM_TITLE #language en-US "HTTP Boot Configuration"
|
||||
#string STR_HTTP_BOOT_CONFIG_FORM_HELP #language en-US "Configure HTTP Boot parameters."
|
||||
#string STR_HTTP_BOOT_IP_VERSION_PROMPT #language en-US "Internet Protocol"
|
||||
#string STR_HTTP_BOOT_IP_VERSION_HELP #language en-US "Select the version of Internet Protocol."
|
||||
#string STR_HTTP_BOOT_IP_VERSION_4 #language en-US "IP4"
|
||||
#string STR_HTTP_BOOT_IP_VERSION_6 #language en-US "IP6"
|
||||
#string STR_BOOT_URI_PROMPT #language en-US "Boot URI"
|
||||
#string STR_BOOT_URI_HELP #language en-US "A new Boot Option will be created according to this Boot URI."
|
||||
#string STR_BOOT_DESCRIPTION_PROMPT #language en-US "Input the description"
|
||||
#string STR_NULL_STRING #language en-US ""
|
|
@ -0,0 +1,49 @@
|
|||
/** @file
|
||||
VFR file used by the HTTP Boot configuration component.
|
||||
|
||||
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpBootConfigNVDataStruc.h"
|
||||
|
||||
|
||||
formset
|
||||
guid = HTTP_BOOT_CONFIG_GUID,
|
||||
title = STRING_TOKEN(STR_HTTP_BOOT_CONFIG_FORM_TITLE),
|
||||
help = STRING_TOKEN(STR_HTTP_BOOT_CONFIG_FORM_HELP),
|
||||
|
||||
varstore HTTP_BOOT_CONFIG_IFR_NVDATA,
|
||||
name = HTTP_BOOT_CONFIG_IFR_NVDATA,
|
||||
guid = HTTP_BOOT_CONFIG_GUID;
|
||||
|
||||
form formid = FORMID_MAIN_FORM,
|
||||
title = STRING_TOKEN(STR_HTTP_BOOT_CONFIG_FORM_TITLE);
|
||||
|
||||
string varid = HTTP_BOOT_CONFIG_IFR_NVDATA.Description,
|
||||
prompt = STRING_TOKEN(STR_BOOT_DESCRIPTION_PROMPT),
|
||||
help = STRING_TOKEN(STR_NULL_STRING),
|
||||
minsize = DESCRIPTION_STR_MIN_SIZE,
|
||||
maxsize = DESCRIPTION_STR_MAX_SIZE,
|
||||
endstring;
|
||||
|
||||
oneof varid = HTTP_BOOT_CONFIG_IFR_NVDATA.IpVersion,
|
||||
prompt = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_PROMPT),
|
||||
help = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_HELP),
|
||||
option text = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_4), value = HTTP_BOOT_IP_VERSION_4, flags = DEFAULT;
|
||||
option text = STRING_TOKEN(STR_HTTP_BOOT_IP_VERSION_6), value = HTTP_BOOT_IP_VERSION_6, flags = 0;
|
||||
endoneof;
|
||||
|
||||
string varid = HTTP_BOOT_CONFIG_IFR_NVDATA.Uri,
|
||||
prompt = STRING_TOKEN(STR_BOOT_URI_PROMPT),
|
||||
help = STRING_TOKEN(STR_BOOT_URI_HELP),
|
||||
flags = INTERACTIVE,
|
||||
key = KEY_INITIATOR_URI,
|
||||
minsize = URI_STR_MIN_SIZE,
|
||||
maxsize = URI_STR_MAX_SIZE,
|
||||
endstring;
|
||||
endform;
|
||||
|
||||
endformset;
|
|
@ -0,0 +1,912 @@
|
|||
/** @file
|
||||
Functions implementation related with DHCPv4 for HTTP boot driver.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "HttpBootDxe.h"
|
||||
|
||||
//
|
||||
// This is a map from the interested DHCP4 option tags' index to the tag value.
|
||||
//
|
||||
UINT8 mInterestedDhcp4Tags[HTTP_BOOT_DHCP4_TAG_INDEX_MAX] = {
|
||||
DHCP4_TAG_BOOTFILE_LEN,
|
||||
DHCP4_TAG_OVERLOAD,
|
||||
DHCP4_TAG_MSG_TYPE,
|
||||
DHCP4_TAG_SERVER_ID,
|
||||
DHCP4_TAG_VENDOR_CLASS_ID,
|
||||
DHCP4_TAG_BOOTFILE,
|
||||
DHCP4_TAG_DNS_SERVER
|
||||
};
|
||||
|
||||
//
|
||||
// There are 4 times retries with the value of 4, 8, 16 and 32, refers to UEFI 2.5 spec.
|
||||
//
|
||||
UINT32 mHttpDhcpTimeout[4] = {4, 8, 16, 32};
|
||||
|
||||
/**
|
||||
Build the options buffer for the DHCPv4 request packet.
|
||||
|
||||
@param[in] Private Pointer to HTTP boot driver private data.
|
||||
@param[out] OptList Pointer to the option pointer array.
|
||||
@param[in] Buffer Pointer to the buffer to contain the option list.
|
||||
|
||||
@return Index The count of the built-in options.
|
||||
|
||||
**/
|
||||
UINT32
|
||||
HttpBootBuildDhcp4Options (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
OUT EFI_DHCP4_PACKET_OPTION **OptList,
|
||||
IN UINT8 *Buffer
|
||||
)
|
||||
{
|
||||
HTTP_BOOT_DHCP4_OPTION_ENTRY OptEnt;
|
||||
UINT16 Value;
|
||||
UINT32 Index;
|
||||
|
||||
Index = 0;
|
||||
OptList[0] = (EFI_DHCP4_PACKET_OPTION *) Buffer;
|
||||
|
||||
//
|
||||
// Append parameter request list option.
|
||||
//
|
||||
OptList[Index]->OpCode = DHCP4_TAG_PARA_LIST;
|
||||
OptList[Index]->Length = 27;
|
||||
OptEnt.Para = (HTTP_BOOT_DHCP4_OPTION_PARA *) OptList[Index]->Data;
|
||||
OptEnt.Para->ParaList[0] = DHCP4_TAG_NETMASK;
|
||||
OptEnt.Para->ParaList[1] = DHCP4_TAG_TIME_OFFSET;
|
||||
OptEnt.Para->ParaList[2] = DHCP4_TAG_ROUTER;
|
||||
OptEnt.Para->ParaList[3] = DHCP4_TAG_TIME_SERVER;
|
||||
OptEnt.Para->ParaList[4] = DHCP4_TAG_NAME_SERVER;
|
||||
OptEnt.Para->ParaList[5] = DHCP4_TAG_DNS_SERVER;
|
||||
OptEnt.Para->ParaList[6] = DHCP4_TAG_HOSTNAME;
|
||||
OptEnt.Para->ParaList[7] = DHCP4_TAG_BOOTFILE_LEN;
|
||||
OptEnt.Para->ParaList[8] = DHCP4_TAG_DOMAINNAME;
|
||||
OptEnt.Para->ParaList[9] = DHCP4_TAG_ROOTPATH;
|
||||
OptEnt.Para->ParaList[10] = DHCP4_TAG_EXTEND_PATH;
|
||||
OptEnt.Para->ParaList[11] = DHCP4_TAG_EMTU;
|
||||
OptEnt.Para->ParaList[12] = DHCP4_TAG_TTL;
|
||||
OptEnt.Para->ParaList[13] = DHCP4_TAG_BROADCAST;
|
||||
OptEnt.Para->ParaList[14] = DHCP4_TAG_NIS_DOMAIN;
|
||||
OptEnt.Para->ParaList[15] = DHCP4_TAG_NIS_SERVER;
|
||||
OptEnt.Para->ParaList[16] = DHCP4_TAG_NTP_SERVER;
|
||||
OptEnt.Para->ParaList[17] = DHCP4_TAG_VENDOR;
|
||||
OptEnt.Para->ParaList[18] = DHCP4_TAG_REQUEST_IP;
|
||||
OptEnt.Para->ParaList[19] = DHCP4_TAG_LEASE;
|
||||
OptEnt.Para->ParaList[20] = DHCP4_TAG_SERVER_ID;
|
||||
OptEnt.Para->ParaList[21] = DHCP4_TAG_T1;
|
||||
OptEnt.Para->ParaList[22] = DHCP4_TAG_T2;
|
||||
OptEnt.Para->ParaList[23] = DHCP4_TAG_VENDOR_CLASS_ID;
|
||||
OptEnt.Para->ParaList[25] = DHCP4_TAG_BOOTFILE;
|
||||
OptEnt.Para->ParaList[26] = DHCP4_TAG_UUID;
|
||||
Index++;
|
||||
OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);
|
||||
|
||||
//
|
||||
// Append UUID/Guid-based client identifier option
|
||||
//
|
||||
OptList[Index]->OpCode = DHCP4_TAG_UUID;
|
||||
OptList[Index]->Length = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_UUID);
|
||||
OptEnt.Uuid = (HTTP_BOOT_DHCP4_OPTION_UUID *) OptList[Index]->Data;
|
||||
OptEnt.Uuid->Type = 0;
|
||||
if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *) OptEnt.Uuid->Guid))) {
|
||||
//
|
||||
// Zero the Guid to indicate NOT programable if failed to get system Guid.
|
||||
//
|
||||
ZeroMem (OptEnt.Uuid->Guid, sizeof (EFI_GUID));
|
||||
}
|
||||
Index++;
|
||||
OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);
|
||||
|
||||
//
|
||||
// Append client network device interface option
|
||||
//
|
||||
OptList[Index]->OpCode = DHCP4_TAG_UNDI;
|
||||
OptList[Index]->Length = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_UNDI);
|
||||
OptEnt.Undi = (HTTP_BOOT_DHCP4_OPTION_UNDI *) OptList[Index]->Data;
|
||||
|
||||
if (Private->Nii != NULL) {
|
||||
OptEnt.Undi->Type = Private->Nii->Type;
|
||||
OptEnt.Undi->MajorVer = Private->Nii->MajorVer;
|
||||
OptEnt.Undi->MinorVer = Private->Nii->MinorVer;
|
||||
} else {
|
||||
OptEnt.Undi->Type = DEFAULT_UNDI_TYPE;
|
||||
OptEnt.Undi->MajorVer = DEFAULT_UNDI_MAJOR;
|
||||
OptEnt.Undi->MinorVer = DEFAULT_UNDI_MINOR;
|
||||
}
|
||||
|
||||
Index++;
|
||||
OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);
|
||||
|
||||
//
|
||||
// Append client system architecture option
|
||||
//
|
||||
OptList[Index]->OpCode = DHCP4_TAG_ARCH;
|
||||
OptList[Index]->Length = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_ARCH);
|
||||
OptEnt.Arch = (HTTP_BOOT_DHCP4_OPTION_ARCH *) OptList[Index]->Data;
|
||||
Value = HTONS (EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE);
|
||||
CopyMem (&OptEnt.Arch->Type, &Value, sizeof (UINT16));
|
||||
Index++;
|
||||
OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);
|
||||
|
||||
//
|
||||
// Append vendor class identify option
|
||||
//
|
||||
OptList[Index]->OpCode = DHCP4_TAG_VENDOR_CLASS_ID;
|
||||
OptList[Index]->Length = (UINT8) sizeof (HTTP_BOOT_DHCP4_OPTION_CLID);
|
||||
OptEnt.Clid = (HTTP_BOOT_DHCP4_OPTION_CLID *) OptList[Index]->Data;
|
||||
CopyMem (
|
||||
OptEnt.Clid,
|
||||
DEFAULT_CLASS_ID_DATA,
|
||||
sizeof (HTTP_BOOT_DHCP4_OPTION_CLID)
|
||||
);
|
||||
HttpBootUintnToAscDecWithFormat (
|
||||
EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE,
|
||||
OptEnt.Clid->ArchitectureType,
|
||||
sizeof (OptEnt.Clid->ArchitectureType)
|
||||
);
|
||||
|
||||
if (Private->Nii != NULL) {
|
||||
CopyMem (OptEnt.Clid->InterfaceName, Private->Nii->StringId, sizeof (OptEnt.Clid->InterfaceName));
|
||||
HttpBootUintnToAscDecWithFormat (Private->Nii->MajorVer, OptEnt.Clid->UndiMajor, sizeof (OptEnt.Clid->UndiMajor));
|
||||
HttpBootUintnToAscDecWithFormat (Private->Nii->MinorVer, OptEnt.Clid->UndiMinor, sizeof (OptEnt.Clid->UndiMinor));
|
||||
}
|
||||
|
||||
Index++;
|
||||
|
||||
return Index;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse a certain dhcp4 option by OptTag in Buffer, and return with start pointer.
|
||||
|
||||
@param[in] Buffer Pointer to the option buffer.
|
||||
@param[in] Length Length of the option buffer.
|
||||
@param[in] OptTag Tag of the required option.
|
||||
|
||||
@retval NULL Failed to find the required option.
|
||||
@retval Others The position of the required option.
|
||||
|
||||
**/
|
||||
EFI_DHCP4_PACKET_OPTION *
|
||||
HttpBootParseDhcp4Options (
|
||||
IN UINT8 *Buffer,
|
||||
IN UINT32 Length,
|
||||
IN UINT8 OptTag
|
||||
)
|
||||
{
|
||||
EFI_DHCP4_PACKET_OPTION *Option;
|
||||
UINT32 Offset;
|
||||
|
||||
Option = (EFI_DHCP4_PACKET_OPTION *) Buffer;
|
||||
Offset = 0;
|
||||
|
||||
while (Offset < Length && Option->OpCode != DHCP4_TAG_EOP) {
|
||||
|
||||
if (Option->OpCode == OptTag) {
|
||||
//
|
||||
// Found the required option.
|
||||
//
|
||||
return Option;
|
||||
}
|
||||
|
||||
//
|
||||
// Skip the current option to the next.
|
||||
//
|
||||
if (Option->OpCode == DHCP4_TAG_PAD) {
|
||||
Offset++;
|
||||
} else {
|
||||
Offset += Option->Length + 2;
|
||||
}
|
||||
|
||||
Option = (EFI_DHCP4_PACKET_OPTION *) (Buffer + Offset);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Cache the DHCPv4 packet.
|
||||
|
||||
@param[in] Dst Pointer to the cache buffer for DHCPv4 packet.
|
||||
@param[in] Src Pointer to the DHCPv4 packet to be cached.
|
||||
|
||||
@retval EFI_SUCCESS Packet is copied.
|
||||
@retval EFI_BUFFER_TOO_SMALL Cache buffer is not big enough to hold the packet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootCacheDhcp4Packet (
|
||||
IN EFI_DHCP4_PACKET *Dst,
|
||||
IN EFI_DHCP4_PACKET *Src
|
||||
)
|
||||
{
|
||||
if (Dst->Size < Src->Length) {
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
CopyMem (&Dst->Dhcp4, &Src->Dhcp4, Src->Length);
|
||||
Dst->Length = Src->Length;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse the cached DHCPv4 packet, including all the options.
|
||||
|
||||
@param[in] Cache4 Pointer to cached DHCPv4 packet.
|
||||
|
||||
@retval EFI_SUCCESS Parsed the DHCPv4 packet successfully.
|
||||
@retval EFI_DEVICE_ERROR Failed to parse an invalid packet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootParseDhcp4Packet (
|
||||
IN HTTP_BOOT_DHCP4_PACKET_CACHE *Cache4
|
||||
)
|
||||
{
|
||||
EFI_DHCP4_PACKET *Offer;
|
||||
EFI_DHCP4_PACKET_OPTION **Options;
|
||||
UINTN Index;
|
||||
EFI_DHCP4_PACKET_OPTION *Option;
|
||||
BOOLEAN IsProxyOffer;
|
||||
BOOLEAN IsHttpOffer;
|
||||
BOOLEAN IsDnsOffer;
|
||||
BOOLEAN IpExpressedUri;
|
||||
UINT8 *Ptr8;
|
||||
EFI_STATUS Status;
|
||||
HTTP_BOOT_OFFER_TYPE OfferType;
|
||||
EFI_IPv4_ADDRESS IpAddr;
|
||||
BOOLEAN FileFieldOverloaded;
|
||||
|
||||
IsDnsOffer = FALSE;
|
||||
IpExpressedUri = FALSE;
|
||||
IsProxyOffer = FALSE;
|
||||
IsHttpOffer = FALSE;
|
||||
FileFieldOverloaded = FALSE;
|
||||
|
||||
ZeroMem (Cache4->OptList, sizeof (Cache4->OptList));
|
||||
|
||||
Offer = &Cache4->Packet.Offer;
|
||||
Options = Cache4->OptList;
|
||||
|
||||
//
|
||||
// Parse DHCPv4 options in this offer, and store the pointers.
|
||||
// First, try to parse DHCPv4 options from the DHCP optional parameters field.
|
||||
//
|
||||
for (Index = 0; Index < HTTP_BOOT_DHCP4_TAG_INDEX_MAX; Index++) {
|
||||
Options[Index] = HttpBootParseDhcp4Options (
|
||||
Offer->Dhcp4.Option,
|
||||
GET_OPTION_BUFFER_LEN (Offer),
|
||||
mInterestedDhcp4Tags[Index]
|
||||
);
|
||||
}
|
||||
//
|
||||
// Second, Check if bootfilename and serverhostname is overloaded to carry DHCP options refers to rfc-2132.
|
||||
// If yes, try to parse options from the BootFileName field, then ServerName field.
|
||||
//
|
||||
Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_OVERLOAD];
|
||||
if (Option != NULL) {
|
||||
if ((Option->Data[0] & HTTP_BOOT_DHCP4_OVERLOAD_FILE) != 0) {
|
||||
FileFieldOverloaded = TRUE;
|
||||
for (Index = 0; Index < HTTP_BOOT_DHCP4_TAG_INDEX_MAX; Index++) {
|
||||
if (Options[Index] == NULL) {
|
||||
Options[Index] = HttpBootParseDhcp4Options (
|
||||
(UINT8 *) Offer->Dhcp4.Header.BootFileName,
|
||||
sizeof (Offer->Dhcp4.Header.BootFileName),
|
||||
mInterestedDhcp4Tags[Index]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((Option->Data[0] & HTTP_BOOT_DHCP4_OVERLOAD_SERVER_NAME) != 0) {
|
||||
for (Index = 0; Index < HTTP_BOOT_DHCP4_TAG_INDEX_MAX; Index++) {
|
||||
if (Options[Index] == NULL) {
|
||||
Options[Index] = HttpBootParseDhcp4Options (
|
||||
(UINT8 *) Offer->Dhcp4.Header.ServerName,
|
||||
sizeof (Offer->Dhcp4.Header.ServerName),
|
||||
mInterestedDhcp4Tags[Index]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The offer with "yiaddr" is a proxy offer.
|
||||
//
|
||||
if (Offer->Dhcp4.Header.YourAddr.Addr[0] == 0) {
|
||||
IsProxyOffer = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// The offer with "HTTPClient" is a Http offer.
|
||||
//
|
||||
Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_CLASS_ID];
|
||||
if ((Option != NULL) && (Option->Length >= 10) &&
|
||||
(CompareMem (Option->Data, DEFAULT_CLASS_ID_DATA, 10) == 0)) {
|
||||
IsHttpOffer = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// The offer with Domain Server is a DNS offer.
|
||||
//
|
||||
Option = Options[HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER];
|
||||
if (Option != NULL) {
|
||||
IsDnsOffer = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse boot file name:
|
||||
// Boot URI information is provided thru 'file' field in DHCP Header or option 67.
|
||||
// According to RFC 2132, boot file name should be read from DHCP option 67 (bootfile name) if present.
|
||||
// Otherwise, read from boot file field in DHCP header.
|
||||
//
|
||||
if (Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
|
||||
//
|
||||
// RFC 2132, Section 9.5 does not strictly state Bootfile name (option 67) is null
|
||||
// terminated string. So force to append null terminated character at the end of string.
|
||||
//
|
||||
Ptr8 = (UINT8*)&Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data[0];
|
||||
Ptr8 += Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Length;
|
||||
if (*(Ptr8 - 1) != '\0') {
|
||||
*Ptr8 = '\0';
|
||||
}
|
||||
} else if (!FileFieldOverloaded && Offer->Dhcp4.Header.BootFileName[0] != 0) {
|
||||
//
|
||||
// If the bootfile is not present and bootfilename is present in DHCPv4 packet, just parse it.
|
||||
// Do not count dhcp option header here, or else will destroy the serverhostname.
|
||||
//
|
||||
Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE] = (EFI_DHCP4_PACKET_OPTION *)
|
||||
(&Offer->Dhcp4.Header.BootFileName[0] -
|
||||
OFFSET_OF (EFI_DHCP4_PACKET_OPTION, Data[0]));
|
||||
}
|
||||
|
||||
//
|
||||
// Http offer must have a boot URI.
|
||||
//
|
||||
if (IsHttpOffer && Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE] == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to retrieve the IP of HTTP server from URI.
|
||||
//
|
||||
if (IsHttpOffer) {
|
||||
Status = HttpParseUrl (
|
||||
(CHAR8*) Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data,
|
||||
(UINT32) AsciiStrLen ((CHAR8*) Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data),
|
||||
FALSE,
|
||||
&Cache4->UriParser
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Status = HttpUrlGetIp4 (
|
||||
(CHAR8*) Options[HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE]->Data,
|
||||
Cache4->UriParser,
|
||||
&IpAddr
|
||||
);
|
||||
IpExpressedUri = !EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
//
|
||||
// Determine offer type of the DHCPv4 packet.
|
||||
//
|
||||
if (IsHttpOffer) {
|
||||
if (IpExpressedUri) {
|
||||
if (IsProxyOffer) {
|
||||
OfferType = HttpOfferTypeProxyIpUri;
|
||||
} else {
|
||||
OfferType = IsDnsOffer ? HttpOfferTypeDhcpIpUriDns : HttpOfferTypeDhcpIpUri;
|
||||
}
|
||||
} else {
|
||||
if (!IsProxyOffer) {
|
||||
OfferType = IsDnsOffer ? HttpOfferTypeDhcpNameUriDns : HttpOfferTypeDhcpNameUri;
|
||||
} else {
|
||||
OfferType = HttpOfferTypeProxyNameUri;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!IsProxyOffer) {
|
||||
OfferType = IsDnsOffer ? HttpOfferTypeDhcpDns : HttpOfferTypeDhcpOnly;
|
||||
} else {
|
||||
if (Cache4->UriParser != NULL) {
|
||||
FreePool (Cache4->UriParser);
|
||||
}
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
Cache4->OfferType = OfferType;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Cache all the received DHCPv4 offers, and set OfferIndex and OfferCount.
|
||||
|
||||
@param[in] Private Pointer to HTTP boot driver private data.
|
||||
@param[in] RcvdOffer Pointer to the received offer packet.
|
||||
|
||||
@retval EFI_SUCCESS Cache and parse the packet successfully.
|
||||
@retval Others Operation failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootCacheDhcp4Offer (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN EFI_DHCP4_PACKET *RcvdOffer
|
||||
)
|
||||
{
|
||||
HTTP_BOOT_DHCP4_PACKET_CACHE *Cache4;
|
||||
EFI_DHCP4_PACKET *Offer;
|
||||
HTTP_BOOT_OFFER_TYPE OfferType;
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM);
|
||||
Cache4 = &Private->OfferBuffer[Private->OfferNum].Dhcp4;
|
||||
Offer = &Cache4->Packet.Offer;
|
||||
|
||||
//
|
||||
// Cache the content of DHCPv4 packet firstly.
|
||||
//
|
||||
Status = HttpBootCacheDhcp4Packet (Offer, RcvdOffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate the DHCPv4 packet, and parse the options and offer type.
|
||||
//
|
||||
if (EFI_ERROR (HttpBootParseDhcp4Packet (Cache4))) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Determine whether cache the current offer by type, and record OfferIndex and OfferCount.
|
||||
//
|
||||
OfferType = Cache4->OfferType;
|
||||
ASSERT (OfferType < HttpOfferTypeMax);
|
||||
ASSERT (Private->OfferCount[OfferType] < HTTP_BOOT_OFFER_MAX_NUM);
|
||||
Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;
|
||||
Private->OfferCount[OfferType]++;
|
||||
Private->OfferNum++;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Select an DHCPv4 or DHCP6 offer, and record SelectIndex and SelectProxyType.
|
||||
|
||||
@param[in] Private Pointer to HTTP boot driver private data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpBootSelectDhcpOffer (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
)
|
||||
{
|
||||
Private->SelectIndex = 0;
|
||||
Private->SelectProxyType = HttpOfferTypeMax;
|
||||
|
||||
if (Private->FilePathUri != NULL) {
|
||||
//
|
||||
// We are in home environment, the URI is already specified.
|
||||
// Just need to choose a DHCP offer.
|
||||
// The offer with DNS server address takes priority here.
|
||||
//
|
||||
if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
|
||||
}
|
||||
|
||||
} else {
|
||||
//
|
||||
// We are in corporate environment.
|
||||
//
|
||||
// Priority1: HttpOfferTypeDhcpIpUri or HttpOfferTypeDhcpIpUriDns
|
||||
// Priority2: HttpOfferTypeDhcpNameUriDns
|
||||
// Priority3: HttpOfferTypeDhcpOnly + HttpOfferTypeProxyIpUri
|
||||
// Priority4: HttpOfferTypeDhcpDns + HttpOfferTypeProxyIpUri
|
||||
// Priority5: HttpOfferTypeDhcpDns + HttpOfferTypeProxyNameUri
|
||||
// Priority6: HttpOfferTypeDhcpDns + HttpOfferTypeDhcpNameUri
|
||||
//
|
||||
if (Private->OfferCount[HttpOfferTypeDhcpIpUri] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUri][0] + 1;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpIpUriDns] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpIpUriDns][0] + 1;
|
||||
|
||||
}else if (Private->OfferCount[HttpOfferTypeDhcpNameUriDns] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpNameUriDns][0] + 1;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpOnly] > 0 &&
|
||||
Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpOnly][0] + 1;
|
||||
Private->SelectProxyType = HttpOfferTypeProxyIpUri;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
|
||||
Private->OfferCount[HttpOfferTypeProxyIpUri] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
|
||||
Private->SelectProxyType = HttpOfferTypeProxyIpUri;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
|
||||
Private->OfferCount[HttpOfferTypeProxyNameUri] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
|
||||
Private->SelectProxyType = HttpOfferTypeProxyNameUri;
|
||||
|
||||
} else if (Private->OfferCount[HttpOfferTypeDhcpDns] > 0 &&
|
||||
Private->OfferCount[HttpOfferTypeDhcpNameUri] > 0) {
|
||||
|
||||
Private->SelectIndex = Private->OfferIndex[HttpOfferTypeDhcpDns][0] + 1;
|
||||
Private->SelectProxyType = HttpOfferTypeDhcpNameUri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
EFI_DHCP4_CALLBACK is provided by the consumer of the EFI DHCPv4 Protocol driver
|
||||
to intercept events that occurred in the configuration process.
|
||||
|
||||
@param[in] This Pointer to the EFI DHCPv4 Protocol.
|
||||
@param[in] Context Pointer to the context set by EFI_DHCP4_PROTOCOL.Configure().
|
||||
@param[in] CurrentState The current operational state of the EFI DHCPv4 Protocol driver.
|
||||
@param[in] Dhcp4Event The event that occurs in the current state, which usually means a
|
||||
state transition.
|
||||
@param[in] Packet The DHCPv4 packet that is going to be sent or already received.
|
||||
@param[out] NewPacket The packet that is used to replace the above Packet.
|
||||
|
||||
@retval EFI_SUCCESS Tells the EFI DHCPv4 Protocol driver to continue the DHCP process.
|
||||
@retval EFI_NOT_READY Only used in the Dhcp4Selecting state. The EFI DHCPv4 Protocol
|
||||
driver will continue to wait for more DHCPOFFER packets until the
|
||||
retry timeout expires.
|
||||
@retval EFI_ABORTED Tells the EFI DHCPv4 Protocol driver to abort the current process
|
||||
and return to the Dhcp4Init or Dhcp4InitReboot state.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootDhcp4CallBack (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
IN VOID *Context,
|
||||
IN EFI_DHCP4_STATE CurrentState,
|
||||
IN EFI_DHCP4_EVENT Dhcp4Event,
|
||||
IN EFI_DHCP4_PACKET *Packet OPTIONAL,
|
||||
OUT EFI_DHCP4_PACKET **NewPacket OPTIONAL
|
||||
)
|
||||
{
|
||||
HTTP_BOOT_PRIVATE_DATA *Private;
|
||||
EFI_DHCP4_PACKET_OPTION *MaxMsgSize;
|
||||
UINT16 Value;
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN Received;
|
||||
|
||||
if ((Dhcp4Event != Dhcp4SendDiscover) &&
|
||||
(Dhcp4Event != Dhcp4RcvdOffer) &&
|
||||
(Dhcp4Event != Dhcp4SendRequest) &&
|
||||
(Dhcp4Event != Dhcp4RcvdAck) &&
|
||||
(Dhcp4Event != Dhcp4SelectOffer)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Private = (HTTP_BOOT_PRIVATE_DATA *) Context;
|
||||
|
||||
//
|
||||
// Override the Maximum DHCP Message Size.
|
||||
//
|
||||
MaxMsgSize = HttpBootParseDhcp4Options (
|
||||
Packet->Dhcp4.Option,
|
||||
GET_OPTION_BUFFER_LEN (Packet),
|
||||
DHCP4_TAG_MAXMSG
|
||||
);
|
||||
if (MaxMsgSize != NULL) {
|
||||
Value = HTONS (HTTP_BOOT_DHCP4_PACKET_MAX_SIZE);
|
||||
CopyMem (MaxMsgSize->Data, &Value, sizeof (Value));
|
||||
}
|
||||
|
||||
//
|
||||
// Callback to user if any packets sent or received.
|
||||
//
|
||||
if (Private->HttpBootCallback != NULL && Dhcp4Event != Dhcp4SelectOffer) {
|
||||
Received = (BOOLEAN) (Dhcp4Event == Dhcp4RcvdOffer || Dhcp4Event == Dhcp4RcvdAck);
|
||||
Status = Private->HttpBootCallback->Callback (
|
||||
Private->HttpBootCallback,
|
||||
HttpBootDhcp4,
|
||||
Received,
|
||||
Packet->Length,
|
||||
&Packet->Dhcp4
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
switch (Dhcp4Event) {
|
||||
case Dhcp4RcvdOffer:
|
||||
Status = EFI_NOT_READY;
|
||||
if (Packet->Length > HTTP_BOOT_DHCP4_PACKET_MAX_SIZE) {
|
||||
//
|
||||
// Ignore the incoming packets which exceed the maximum length.
|
||||
//
|
||||
break;
|
||||
}
|
||||
if (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM) {
|
||||
//
|
||||
// Cache the DHCPv4 offers to OfferBuffer[] for select later, and record
|
||||
// the OfferIndex and OfferCount.
|
||||
// If error happens, just ignore this packet and continue to wait more offer.
|
||||
//
|
||||
HttpBootCacheDhcp4Offer (Private, Packet);
|
||||
}
|
||||
break;
|
||||
|
||||
case Dhcp4SelectOffer:
|
||||
//
|
||||
// Select offer according to the priority in UEFI spec, and record the SelectIndex
|
||||
// and SelectProxyType.
|
||||
//
|
||||
HttpBootSelectDhcpOffer (Private);
|
||||
|
||||
if (Private->SelectIndex == 0) {
|
||||
Status = EFI_ABORTED;
|
||||
} else {
|
||||
*NewPacket = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp4.Packet.Offer;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will register the IPv4 gateway address to the network device.
|
||||
|
||||
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
|
||||
|
||||
@retval EFI_SUCCESS The new IP configuration has been configured successfully.
|
||||
@retval Others Failed to configure the address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootRegisterIp4Gateway (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
|
||||
|
||||
ASSERT (!Private->UsingIpv6);
|
||||
|
||||
Ip4Config2 = Private->Ip4Config2;
|
||||
|
||||
//
|
||||
// Configure the gateway if valid.
|
||||
//
|
||||
if (!EFI_IP4_EQUAL (&Private->GatewayIp, &mZeroIp4Addr)) {
|
||||
Status = Ip4Config2->SetData (
|
||||
Ip4Config2,
|
||||
Ip4Config2DataTypeGateway,
|
||||
sizeof (EFI_IPv4_ADDRESS),
|
||||
&Private->GatewayIp
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function will register the default DNS addresses to the network device.
|
||||
|
||||
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
|
||||
@param[in] DataLength Size of the buffer pointed to by DnsServerData in bytes.
|
||||
@param[in] DnsServerData Point a list of DNS server address in an array
|
||||
of EFI_IPv4_ADDRESS instances.
|
||||
|
||||
@retval EFI_SUCCESS The DNS configuration has been configured successfully.
|
||||
@retval Others Failed to configure the address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootRegisterIp4Dns (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN UINTN DataLength,
|
||||
IN VOID *DnsServerData
|
||||
)
|
||||
{
|
||||
EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
|
||||
|
||||
ASSERT (!Private->UsingIpv6);
|
||||
|
||||
Ip4Config2 = Private->Ip4Config2;
|
||||
|
||||
return Ip4Config2->SetData (
|
||||
Ip4Config2,
|
||||
Ip4Config2DataTypeDnsServer,
|
||||
DataLength,
|
||||
DnsServerData
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function will switch the IP4 configuration policy to Static.
|
||||
|
||||
@param[in] Private Pointer to HTTP boot driver private data.
|
||||
|
||||
@retval EFI_SUCCESS The policy is already configured to static.
|
||||
@retval Others Other error as indicated..
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootSetIp4Policy (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
)
|
||||
{
|
||||
EFI_IP4_CONFIG2_POLICY Policy;
|
||||
EFI_STATUS Status;
|
||||
EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
|
||||
UINTN DataSize;
|
||||
|
||||
Ip4Config2 = Private->Ip4Config2;
|
||||
|
||||
DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);
|
||||
Status = Ip4Config2->GetData (
|
||||
Ip4Config2,
|
||||
Ip4Config2DataTypePolicy,
|
||||
&DataSize,
|
||||
&Policy
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Policy != Ip4Config2PolicyStatic) {
|
||||
Policy = Ip4Config2PolicyStatic;
|
||||
Status= Ip4Config2->SetData (
|
||||
Ip4Config2,
|
||||
Ip4Config2DataTypePolicy,
|
||||
sizeof (EFI_IP4_CONFIG2_POLICY),
|
||||
&Policy
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Start the D.O.R.A DHCPv4 process to acquire the IPv4 address and other Http boot information.
|
||||
|
||||
@param[in] Private Pointer to HTTP boot driver private data.
|
||||
|
||||
@retval EFI_SUCCESS The D.O.R.A process successfully finished.
|
||||
@retval Others Failed to finish the D.O.R.A process.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootDhcp4Dora (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
)
|
||||
{
|
||||
EFI_DHCP4_PROTOCOL *Dhcp4;
|
||||
UINT32 OptCount;
|
||||
EFI_DHCP4_PACKET_OPTION *OptList[HTTP_BOOT_DHCP4_OPTION_MAX_NUM];
|
||||
UINT8 Buffer[HTTP_BOOT_DHCP4_OPTION_MAX_SIZE];
|
||||
EFI_DHCP4_CONFIG_DATA Config;
|
||||
EFI_STATUS Status;
|
||||
EFI_DHCP4_MODE_DATA Mode;
|
||||
|
||||
Dhcp4 = Private->Dhcp4;
|
||||
ASSERT (Dhcp4 != NULL);
|
||||
|
||||
Status = HttpBootSetIp4Policy (Private);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Build option list for the request packet.
|
||||
//
|
||||
OptCount = HttpBootBuildDhcp4Options (Private, OptList, Buffer);
|
||||
ASSERT (OptCount > 0);
|
||||
|
||||
ZeroMem (&Config, sizeof(Config));
|
||||
Config.OptionCount = OptCount;
|
||||
Config.OptionList = OptList;
|
||||
Config.Dhcp4Callback = HttpBootDhcp4CallBack;
|
||||
Config.CallbackContext = Private;
|
||||
Config.DiscoverTryCount = HTTP_BOOT_DHCP_RETRIES;
|
||||
Config.DiscoverTimeout = mHttpDhcpTimeout;
|
||||
|
||||
//
|
||||
// Configure the DHCPv4 instance for HTTP boot.
|
||||
//
|
||||
Status = Dhcp4->Configure (Dhcp4, &Config);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the record fields for DHCPv4 offer in private data.
|
||||
//
|
||||
Private->OfferNum = 0;
|
||||
ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
|
||||
ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));
|
||||
|
||||
//
|
||||
// Start DHCPv4 D.O.R.A. process to acquire IPv4 address.
|
||||
//
|
||||
Status = Dhcp4->Start (Dhcp4, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the acquired IPv4 address and store them.
|
||||
//
|
||||
Status = Dhcp4->GetModeData (Dhcp4, &Mode);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
ASSERT (Mode.State == Dhcp4Bound);
|
||||
CopyMem (&Private->StationIp, &Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&Private->SubnetMask, &Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
|
||||
CopyMem (&Private->GatewayIp, &Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
Status = HttpBootRegisterIp4Gateway (Private);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
AsciiPrint ("\n Station IP address is ");
|
||||
HttpBootShowIp4Addr (&Private->StationIp.v4);
|
||||
AsciiPrint ("\n");
|
||||
|
||||
ON_EXIT:
|
||||
if (EFI_ERROR (Status)) {
|
||||
Dhcp4->Stop (Dhcp4);
|
||||
Dhcp4->Configure (Dhcp4, NULL);
|
||||
} else {
|
||||
ZeroMem (&Config, sizeof (EFI_DHCP4_CONFIG_DATA));
|
||||
Dhcp4->Configure (Dhcp4, &Config);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
/** @file
|
||||
Functions declaration related with DHCPv4 for HTTP boot driver.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_UEFI_HTTP_BOOT_DHCP4_H__
|
||||
#define __EFI_UEFI_HTTP_BOOT_DHCP4_H__
|
||||
|
||||
#define HTTP_BOOT_DHCP4_OPTION_MAX_NUM 16
|
||||
#define HTTP_BOOT_DHCP4_OPTION_MAX_SIZE 312
|
||||
#define HTTP_BOOT_DHCP4_PACKET_MAX_SIZE 1472
|
||||
|
||||
#define HTTP_BOOT_DHCP4_OPCODE_REQUEST 1
|
||||
#define HTTP_BOOT_DHCP4_OPCODE_REPLY 2
|
||||
#define HTTP_BOOT_DHCP4_MSG_TYPE_REQUEST 3
|
||||
#define HTTP_BOOT_DHCP4_MAGIC 0x63538263 // network byte order
|
||||
|
||||
#define HTTP_BOOT_DHCP4_OVERLOAD_FILE 1
|
||||
#define HTTP_BOOT_DHCP4_OVERLOAD_SERVER_NAME 2
|
||||
|
||||
///
|
||||
/// HTTP Tag definition that identifies the processor
|
||||
/// and programming environment of the client system.
|
||||
/// These identifiers are defined by IETF:
|
||||
/// http://www.ietf.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml
|
||||
///
|
||||
#if defined (MDE_CPU_IA32)
|
||||
#define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE HTTP_CLIENT_ARCH_IA32
|
||||
#elif defined (MDE_CPU_X64)
|
||||
#define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE HTTP_CLIENT_ARCH_X64
|
||||
#elif defined (MDE_CPU_ARM)
|
||||
#define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE HTTP_CLIENT_ARCH_ARM
|
||||
#elif defined (MDE_CPU_AARCH64)
|
||||
#define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE HTTP_CLIENT_ARCH_AARCH64
|
||||
#elif defined (MDE_CPU_EBC)
|
||||
#define EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE HTTP_CLIENT_ARCH_EBC
|
||||
#endif
|
||||
|
||||
/// DHCP offer types among HTTP boot.
|
||||
/// Dhcp4 and Dhcp6 share this definition, and corresponding
|
||||
/// relatioinship is as follows:
|
||||
/// Dhcp4Discover <> Dhcp6Solicit
|
||||
/// Dhcp4Offer <> Dhcp6Advertise
|
||||
/// Dhcp4Request <> Dhcp6Request
|
||||
/// Dhcp4Ack <> DHcp6Reply
|
||||
///
|
||||
typedef enum {
|
||||
//
|
||||
// <IP address, IP expressed URI>
|
||||
//
|
||||
HttpOfferTypeDhcpIpUri,
|
||||
//
|
||||
// <IP address, IP expressed URI, Name-server>
|
||||
//
|
||||
HttpOfferTypeDhcpIpUriDns,
|
||||
//
|
||||
// <IP address, Domain-name expressed URI, Name-server>
|
||||
//
|
||||
HttpOfferTypeDhcpNameUriDns,
|
||||
//
|
||||
// <IP address, Name-server>
|
||||
//
|
||||
HttpOfferTypeDhcpDns,
|
||||
//
|
||||
// <IP address>
|
||||
//
|
||||
HttpOfferTypeDhcpOnly,
|
||||
//
|
||||
// <Domain-name expressed URI> or
|
||||
// <Domain-name expressed URI, Name-server (will be ignored)>
|
||||
//
|
||||
HttpOfferTypeProxyNameUri,
|
||||
//
|
||||
// <IP expressed URI> or
|
||||
// <IP expressed URI, Name-server (will be ignored)>
|
||||
//
|
||||
HttpOfferTypeProxyIpUri,
|
||||
//
|
||||
// <IP address, Domain-name expressed URI>
|
||||
//
|
||||
HttpOfferTypeDhcpNameUri,
|
||||
HttpOfferTypeMax
|
||||
} HTTP_BOOT_OFFER_TYPE;
|
||||
|
||||
#define HTTP_BOOT_DHCP_RETRIES 4
|
||||
#define HTTP_BOOT_OFFER_MAX_NUM 16
|
||||
|
||||
// The array index of the DHCP4 option tag interested
|
||||
//
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE_LEN 0
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_OVERLOAD 1
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_MSG_TYPE 2
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_SERVER_ID 3
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_CLASS_ID 4
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_BOOTFILE 5
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER 6
|
||||
#define HTTP_BOOT_DHCP4_TAG_INDEX_MAX 7
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
UINT8 ParaList[135];
|
||||
} HTTP_BOOT_DHCP4_OPTION_PARA;
|
||||
|
||||
typedef struct {
|
||||
UINT16 Size;
|
||||
} HTTP_BOOT_DHCP4_OPTION_MAX_MESG_SIZE;
|
||||
|
||||
typedef struct {
|
||||
UINT8 Type;
|
||||
UINT8 MajorVer;
|
||||
UINT8 MinorVer;
|
||||
} HTTP_BOOT_DHCP4_OPTION_UNDI;
|
||||
|
||||
typedef struct {
|
||||
UINT8 Type;
|
||||
} HTTP_BOOT_DHCP4_OPTION_MESG;
|
||||
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
} HTTP_BOOT_DHCP4_OPTION_ARCH;
|
||||
|
||||
typedef struct {
|
||||
UINT8 ClassIdentifier[11];
|
||||
UINT8 ArchitecturePrefix[5];
|
||||
UINT8 ArchitectureType[5];
|
||||
UINT8 Lit3[1];
|
||||
UINT8 InterfaceName[4];
|
||||
UINT8 Lit4[1];
|
||||
UINT8 UndiMajor[3];
|
||||
UINT8 UndiMinor[3];
|
||||
} HTTP_BOOT_DHCP4_OPTION_CLID;
|
||||
|
||||
typedef struct {
|
||||
UINT8 Type;
|
||||
UINT8 Guid[16];
|
||||
} HTTP_BOOT_DHCP4_OPTION_UUID;
|
||||
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
UINT16 Layer;
|
||||
} HTTP_BOOT_OPTION_BOOT_ITEM;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
typedef union {
|
||||
HTTP_BOOT_DHCP4_OPTION_PARA *Para;
|
||||
HTTP_BOOT_DHCP4_OPTION_UNDI *Undi;
|
||||
HTTP_BOOT_DHCP4_OPTION_ARCH *Arch;
|
||||
HTTP_BOOT_DHCP4_OPTION_CLID *Clid;
|
||||
HTTP_BOOT_DHCP4_OPTION_UUID *Uuid;
|
||||
HTTP_BOOT_DHCP4_OPTION_MESG *Mesg;
|
||||
HTTP_BOOT_DHCP4_OPTION_MAX_MESG_SIZE *MaxMesgSize;
|
||||
} HTTP_BOOT_DHCP4_OPTION_ENTRY;
|
||||
|
||||
#define GET_NEXT_DHCP_OPTION(Opt) \
|
||||
(EFI_DHCP4_PACKET_OPTION *) ((UINT8 *) (Opt) + \
|
||||
sizeof (EFI_DHCP4_PACKET_OPTION) + (Opt)->Length - 1)
|
||||
|
||||
#define GET_OPTION_BUFFER_LEN(Pkt) \
|
||||
((Pkt)->Length - sizeof (EFI_DHCP4_HEADER) - 4)
|
||||
|
||||
#define DEFAULT_CLASS_ID_DATA "HTTPClient:Arch:xxxxx:UNDI:003000"
|
||||
#define DEFAULT_UNDI_TYPE 1
|
||||
#define DEFAULT_UNDI_MAJOR 3
|
||||
#define DEFAULT_UNDI_MINOR 0
|
||||
|
||||
typedef struct {
|
||||
UINT32 Reserved;
|
||||
} HTTP_BOOT_VENDOR_OPTION;
|
||||
|
||||
#define HTTP_CACHED_DHCP4_PACKET_MAX_SIZE (OFFSET_OF (EFI_DHCP4_PACKET, Dhcp4) + HTTP_BOOT_DHCP4_PACKET_MAX_SIZE)
|
||||
|
||||
typedef union {
|
||||
EFI_DHCP4_PACKET Offer;
|
||||
EFI_DHCP4_PACKET Ack;
|
||||
UINT8 Buffer[HTTP_CACHED_DHCP4_PACKET_MAX_SIZE];
|
||||
} HTTP_BOOT_DHCP4_PACKET;
|
||||
|
||||
typedef struct {
|
||||
//
|
||||
// URI component
|
||||
//
|
||||
CHAR8 *Scheme;
|
||||
CHAR8 *Authority;
|
||||
CHAR8 *Path;
|
||||
CHAR8 *Query;
|
||||
CHAR8 *Fragment; /// TODO: may not required in HTTP URL
|
||||
|
||||
CHAR8 *RegName; /// Point to somewhere in Authority
|
||||
BOOLEAN AddrIsOk;
|
||||
EFI_IP_ADDRESS Address;
|
||||
UINT16 Port;
|
||||
} HTTP_BOOT_URI_CONTENT;
|
||||
|
||||
typedef struct {
|
||||
HTTP_BOOT_DHCP4_PACKET Packet;
|
||||
HTTP_BOOT_OFFER_TYPE OfferType;
|
||||
VOID *UriParser;
|
||||
EFI_DHCP4_PACKET_OPTION *OptList[HTTP_BOOT_DHCP4_TAG_INDEX_MAX];
|
||||
} HTTP_BOOT_DHCP4_PACKET_CACHE;
|
||||
|
||||
/**
|
||||
Select an DHCPv4 or DHCP6 offer, and record SelectIndex and SelectProxyType.
|
||||
|
||||
@param[in] Private Pointer to HTTP boot driver private data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
HttpBootSelectDhcpOffer (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
Start the D.O.R.A DHCPv4 process to acquire the IPv4 address and other Http boot information.
|
||||
|
||||
@param[in] Private Pointer to HTTP_BOOT private data.
|
||||
|
||||
@retval EFI_SUCCESS The D.O.R.A process successfully finished.
|
||||
@retval Others Failed to finish the D.O.R.A process.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootDhcp4Dora (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
This function will register the default DNS addresses to the network device.
|
||||
|
||||
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
|
||||
@param[in] DataLength Size of the buffer pointed to by DnsServerData in bytes.
|
||||
@param[in] DnsServerData Point a list of DNS server address in an array
|
||||
of EFI_IPv4_ADDRESS instances.
|
||||
|
||||
@retval EFI_SUCCESS The DNS configuration has been configured successfully.
|
||||
@retval Others Failed to configure the address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootRegisterIp4Dns (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN UINTN DataLength,
|
||||
IN VOID *DnsServerData
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,169 @@
|
|||
/** @file
|
||||
Functions declaration related with DHCPv6 for HTTP boot driver.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#ifndef __EFI_HTTP_BOOT_DHCP6_H__
|
||||
#define __EFI_HTTP_BOOT_DHCP6_H__
|
||||
|
||||
#define HTTP_BOOT_OFFER_MAX_NUM 16
|
||||
#define HTTP_BOOT_DHCP6_OPTION_MAX_NUM 16
|
||||
#define HTTP_BOOT_DHCP6_OPTION_MAX_SIZE 312
|
||||
#define HTTP_BOOT_DHCP6_PACKET_MAX_SIZE 1472
|
||||
#define HTTP_BOOT_IP6_ROUTE_TABLE_TIMEOUT 10
|
||||
#define HTTP_BOOT_DEFAULT_HOPLIMIT 64
|
||||
#define HTTP_BOOT_DEFAULT_LIFETIME 50000
|
||||
|
||||
#define HTTP_BOOT_DHCP6_ENTERPRISE_NUM 343 // TODO: IANA TBD: temporarily using Intel's
|
||||
#define HTTP_BOOT_DHCP6_MAX_BOOT_FILE_SIZE 65535 // It's a limitation of bit length, 65535*512 bytes.
|
||||
|
||||
#define HTTP_BOOT_DHCP6_IDX_IA_NA 0
|
||||
#define HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL 1
|
||||
#define HTTP_BOOT_DHCP6_IDX_BOOT_FILE_PARAM 2
|
||||
#define HTTP_BOOT_DHCP6_IDX_VENDOR_CLASS 3
|
||||
#define HTTP_BOOT_DHCP6_IDX_DNS_SERVER 4
|
||||
#define HTTP_BOOT_DHCP6_IDX_MAX 5
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT16 OpCode[256];
|
||||
} HTTP_BOOT_DHCP6_OPTION_ORO;
|
||||
|
||||
typedef struct {
|
||||
UINT8 Type;
|
||||
UINT8 MajorVer;
|
||||
UINT8 MinorVer;
|
||||
} HTTP_BOOT_DHCP6_OPTION_UNDI;
|
||||
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
} HTTP_BOOT_DHCP6_OPTION_ARCH;
|
||||
|
||||
typedef struct {
|
||||
UINT8 ClassIdentifier[11];
|
||||
UINT8 ArchitecturePrefix[5];
|
||||
UINT8 ArchitectureType[5];
|
||||
UINT8 Lit3[1];
|
||||
UINT8 InterfaceName[4];
|
||||
UINT8 Lit4[1];
|
||||
UINT8 UndiMajor[3];
|
||||
UINT8 UndiMinor[3];
|
||||
} HTTP_BOOT_CLASS_ID;
|
||||
|
||||
typedef struct {
|
||||
UINT32 Vendor;
|
||||
UINT16 ClassLen;
|
||||
HTTP_BOOT_CLASS_ID ClassId;
|
||||
} HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
typedef union {
|
||||
HTTP_BOOT_DHCP6_OPTION_ORO *Oro;
|
||||
HTTP_BOOT_DHCP6_OPTION_UNDI *Undi;
|
||||
HTTP_BOOT_DHCP6_OPTION_ARCH *Arch;
|
||||
HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS *VendorClass;
|
||||
} HTTP_BOOT_DHCP6_OPTION_ENTRY;
|
||||
|
||||
#define HTTP_CACHED_DHCP6_PACKET_MAX_SIZE (OFFSET_OF (EFI_DHCP6_PACKET, Dhcp6) + HTTP_BOOT_DHCP6_PACKET_MAX_SIZE)
|
||||
|
||||
typedef union {
|
||||
EFI_DHCP6_PACKET Offer;
|
||||
EFI_DHCP6_PACKET Ack;
|
||||
UINT8 Buffer[HTTP_CACHED_DHCP6_PACKET_MAX_SIZE];
|
||||
} HTTP_BOOT_DHCP6_PACKET;
|
||||
|
||||
typedef struct {
|
||||
HTTP_BOOT_DHCP6_PACKET Packet;
|
||||
HTTP_BOOT_OFFER_TYPE OfferType;
|
||||
EFI_DHCP6_PACKET_OPTION *OptList[HTTP_BOOT_DHCP6_IDX_MAX];
|
||||
VOID *UriParser;
|
||||
} HTTP_BOOT_DHCP6_PACKET_CACHE;
|
||||
|
||||
#define GET_NEXT_DHCP6_OPTION(Opt) \
|
||||
(EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \
|
||||
sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1)
|
||||
|
||||
#define GET_DHCP6_OPTION_SIZE(Pkt) \
|
||||
((Pkt)->Length - sizeof (EFI_DHCP6_HEADER))
|
||||
|
||||
/**
|
||||
Start the S.A.R.R DHCPv6 process to acquire the IPv6 address and other Http boot information.
|
||||
|
||||
@param[in] Private Pointer to HTTP_BOOT private data.
|
||||
|
||||
@retval EFI_SUCCESS The S.A.R.R process successfully finished.
|
||||
@retval Others Failed to finish the S.A.R.R process.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootDhcp6Sarr (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
Set the IP6 policy to Automatic.
|
||||
|
||||
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
|
||||
|
||||
@retval EFI_SUCCESS Switch the IP policy succesfully.
|
||||
@retval Others Unexpect error happened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootSetIp6Policy (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
This function will register the default DNS addresses to the network device.
|
||||
|
||||
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
|
||||
@param[in] DataLength Size of the buffer pointed to by DnsServerData in bytes.
|
||||
@param[in] DnsServerData Point a list of DNS server address in an array
|
||||
of EFI_IPv6_ADDRESS instances.
|
||||
|
||||
@retval EFI_SUCCESS The DNS configuration has been configured successfully.
|
||||
@retval Others Failed to configure the address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootSetIp6Dns (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private,
|
||||
IN UINTN DataLength,
|
||||
IN VOID *DnsServerData
|
||||
);
|
||||
|
||||
/**
|
||||
This function will register the IPv6 gateway address to the network device.
|
||||
|
||||
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
|
||||
|
||||
@retval EFI_SUCCESS The new IP configuration has been configured successfully.
|
||||
@retval Others Failed to configure the address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootSetIp6Gateway (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
/**
|
||||
This function will register the station IP address.
|
||||
|
||||
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
|
||||
|
||||
@retval EFI_SUCCESS The new IP address has been configured successfully.
|
||||
@retval Others Failed to configure the address.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
HttpBootSetIp6Address (
|
||||
IN HTTP_BOOT_PRIVATE_DATA *Private
|
||||
);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,524 @@
|
|||
/** @file
|
||||
UEFI HTTP boot driver's private data structure and interfaces declaration.
|
||||
|
||||
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_HTTP_BOOT_DXE_H__
|
||||
#define __EFI_HTTP_BOOT_DXE_H__
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <IndustryStandard/Http11.h>
|
||||
#include <IndustryStandard/Dhcp.h>
|
||||
|
||||
//
|
||||
// Libraries
|
||||
//
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiHiiServicesLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/HttpLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/DpcLib.h>
|
||||
|
||||
//
|
||||
// UEFI Driver Model Protocols
|
||||
//
|
||||
#include <Protocol/DriverBinding.h>
|
||||
#include <Protocol/ComponentName2.h>
|
||||
#include <Protocol/ComponentName.h>
|
||||
|
||||
//
|
||||
// Consumed Protocols
|
||||
//
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
#include <Protocol/HiiConfigAccess.h>
|
||||
#include <Protocol/NetworkInterfaceIdentifier.h>
|
||||
#include <Protocol/Dhcp4.h>
|
||||
#include <Protocol/Dhcp6.h>
|
||||
#include <Protocol/Dns6.h>
|
||||
#include <Protocol/Http.h>
|
||||
#include <Protocol/Ip4Config2.h>
|
||||
#include <Protocol/Ip6Config.h>
|
||||
#include <Protocol/RamDisk.h>
|
||||
#include <Protocol/AdapterInformation.h>
|
||||
|
||||
//
|
||||
// Produced Protocols
|
||||
//
|
||||
#include <Protocol/LoadFile.h>
|
||||
#include <Protocol/HttpBootCallback.h>
|
||||
|
||||
//
|
||||
// Consumed Guids
|
||||
//
|
||||
#include <Guid/HttpBootConfigHii.h>
|
||||
|
||||
//
|
||||
// Driver Version
|
||||
//
|
||||
#define HTTP_BOOT_DXE_VERSION 0xa
|
||||
|
||||
//
|
||||
// Standard Media Types defined in
|
||||
// http://www.iana.org/assignments/media-types
|
||||
//
|
||||
#define HTTP_CONTENT_TYPE_APP_EFI "application/efi"
|
||||
#define HTTP_CONTENT_TYPE_APP_IMG "application/vnd.efi-img"
|
||||
#define HTTP_CONTENT_TYPE_APP_ISO "application/vnd.efi-iso"
|
||||
|
||||
//
|
||||
// Protocol instances
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gHttpBootDxeDriverBinding;
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gHttpBootDxeComponentName2;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gHttpBootDxeComponentName;
|
||||
|
||||
//
|
||||
// Private data structure
|
||||
//
|
||||
typedef struct _HTTP_BOOT_PRIVATE_DATA HTTP_BOOT_PRIVATE_DATA;
|
||||
typedef struct _HTTP_BOOT_VIRTUAL_NIC HTTP_BOOT_VIRTUAL_NIC;
|
||||
|
||||
typedef enum {
|
||||
ImageTypeEfi,
|
||||
ImageTypeVirtualCd,
|
||||
ImageTypeVirtualDisk,
|
||||
ImageTypeMax
|
||||
} HTTP_BOOT_IMAGE_TYPE;
|
||||
|
||||
//
|
||||
// Include files with internal function prototypes
|
||||
//
|
||||
#include "HttpBootComponentName.h"
|
||||
#include "HttpBootDhcp4.h"
|
||||
#include "HttpBootDhcp6.h"
|
||||
#include "HttpBootImpl.h"
|
||||
#include "HttpBootSupport.h"
|
||||
#include "HttpBootClient.h"
|
||||
#include "HttpBootConfig.h"
|
||||
|
||||
typedef union {
|
||||
HTTP_BOOT_DHCP4_PACKET_CACHE Dhcp4;
|
||||
HTTP_BOOT_DHCP6_PACKET_CACHE Dhcp6;
|
||||
} HTTP_BOOT_DHCP_PACKET_CACHE;
|
||||
|
||||
struct _HTTP_BOOT_VIRTUAL_NIC {
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE Controller;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_LOAD_FILE_PROTOCOL LoadFile;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
HTTP_BOOT_PRIVATE_DATA *Private;
|
||||
};
|
||||
|
||||
#define HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO(Callback) \
|
||||
CR ( \
|
||||
Callback, \
|
||||
HTTP_BOOT_PRIVATE_DATA, \
|
||||
CallbackInfo, \
|
||||
HTTP_BOOT_PRIVATE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
#define HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_PROTOCOL(CallbackProtocol) \
|
||||
CR ( \
|
||||
CallbackProtocol, \
|
||||
HTTP_BOOT_PRIVATE_DATA, \
|
||||
LoadFileCallback, \
|
||||
HTTP_BOOT_PRIVATE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
struct _HTTP_BOOT_PRIVATE_DATA {
|
||||
UINT32 Signature;
|
||||
EFI_HANDLE Controller;
|
||||
|
||||
HTTP_BOOT_VIRTUAL_NIC *Ip4Nic;
|
||||
HTTP_BOOT_VIRTUAL_NIC *Ip6Nic;
|
||||
|
||||
//
|
||||
// Cousumed children
|
||||
//
|
||||
EFI_HANDLE Ip6Child;
|
||||
EFI_HANDLE Dhcp4Child;
|
||||
EFI_HANDLE Dhcp6Child;
|
||||
HTTP_IO HttpIo;
|
||||
BOOLEAN HttpCreated;
|
||||
|
||||
//
|
||||
// Consumed protocol
|
||||
//
|
||||
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
|
||||
EFI_IP6_PROTOCOL *Ip6;
|
||||
EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
|
||||
EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
|
||||
EFI_DHCP4_PROTOCOL *Dhcp4;
|
||||
EFI_DHCP6_PROTOCOL *Dhcp6;
|
||||
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
|
||||
|
||||
|
||||
//
|
||||
// Produced protocol
|
||||
//
|
||||
EFI_LOAD_FILE_PROTOCOL LoadFile;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
UINT32 Id;
|
||||
EFI_HTTP_BOOT_CALLBACK_PROTOCOL *HttpBootCallback;
|
||||
EFI_HTTP_BOOT_CALLBACK_PROTOCOL LoadFileCallback;
|
||||
|
||||
//
|
||||
// Data for the default HTTP Boot callback protocol
|
||||
//
|
||||
UINT64 FileSize;
|
||||
UINT64 ReceivedSize;
|
||||
UINT32 Percentage;
|
||||
|
||||
//
|
||||
// HII callback info block
|
||||
//
|
||||
HTTP_BOOT_FORM_CALLBACK_INFO CallbackInfo;
|
||||
|
||||
//
|
||||
// Mode data
|
||||
//
|
||||
BOOLEAN UsingIpv6;
|
||||
BOOLEAN Started;
|
||||
EFI_IP_ADDRESS StationIp;
|
||||
EFI_IP_ADDRESS SubnetMask;
|
||||
EFI_IP_ADDRESS GatewayIp;
|
||||
EFI_IP_ADDRESS ServerIp;
|
||||
UINT16 Port;
|
||||
UINT32 DnsServerCount;
|
||||
EFI_IP_ADDRESS *DnsServerIp;
|
||||
|
||||
//
|
||||
// The URI string attempt to download through HTTP, may point to
|
||||
// the memory in cached DHCP offer, or to the memory in FilePathUri.
|
||||
//
|
||||
CHAR8 *BootFileUri;
|
||||
VOID *BootFileUriParser;
|
||||
UINTN BootFileSize;
|
||||
BOOLEAN NoGateway;
|
||||
HTTP_BOOT_IMAGE_TYPE ImageType;
|
||||
|
||||
//
|
||||
// URI string extracted from the input FilePath parameter.
|
||||
//
|
||||
CHAR8 *FilePathUri;
|
||||
VOID *FilePathUriParser;
|
||||
|
||||
//
|
||||
// Cached HTTP data
|
||||
//
|
||||
LIST_ENTRY CacheList;
|
||||
|
||||
//
|
||||
// Cached DHCP offer
|
||||
//
|
||||
// OfferIndex records the index of DhcpOffer[] buffer, and OfferCount records the num of each type of offer.
|
||||
//
|
||||
// It supposed that
|
||||
//
|
||||
// OfferNum: 8
|
||||
// OfferBuffer: [ProxyNameUri, DhcpNameUri, DhcpIpUri, ProxyNameUri, ProxyIpUri, DhcpOnly, DhcpIpUri, DhcpNameUriDns]
|
||||
// (OfferBuffer is 0-based.)
|
||||
//
|
||||
// And assume that (DhcpIpUri is the first priority actually.)
|
||||
//
|
||||
// SelectIndex: 5
|
||||
// SelectProxyType: HttpOfferTypeProxyIpUri
|
||||
// (SelectIndex is 1-based, and 0 means no one is selected.)
|
||||
//
|
||||
// So it should be
|
||||
//
|
||||
// DhcpIpUri DhcpNameUriDns DhcpDns DhcpOnly ProxyNameUri ProxyIpUri DhcpNameUri
|
||||
// OfferCount: [ 2, 1, 0, 1, 2, 1, 1]
|
||||
//
|
||||
// OfferIndex: {[ 2, 7, 0, 5, 0, *4, 1]
|
||||
// [ 6, 0, 0, 0, 3, 0, 0]
|
||||
// [ 0, 0, 0, 0, 0, 0, 0]
|
||||
// ... ]}
|
||||
// (OfferIndex is 0-based.)
|
||||
//
|
||||
//
|
||||
UINT32 SelectIndex;
|
||||
UINT32 SelectProxyType;
|
||||
HTTP_BOOT_DHCP_PACKET_CACHE OfferBuffer[HTTP_BOOT_OFFER_MAX_NUM];
|
||||
UINT32 OfferNum;
|
||||
UINT32 OfferCount[HttpOfferTypeMax];
|
||||
UINT32 OfferIndex[HttpOfferTypeMax][HTTP_BOOT_OFFER_MAX_NUM];
|
||||
};
|
||||
|
||||
#define HTTP_BOOT_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('H', 'B', 'P', 'D')
|
||||
#define HTTP_BOOT_VIRTUAL_NIC_SIGNATURE SIGNATURE_32 ('H', 'B', 'V', 'N')
|
||||
#define HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE(a) CR (a, HTTP_BOOT_PRIVATE_DATA, LoadFile, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
|
||||
#define HTTP_BOOT_PRIVATE_DATA_FROM_ID(a) CR (a, HTTP_BOOT_PRIVATE_DATA, Id, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
|
||||
#define HTTP_BOOT_VIRTUAL_NIC_FROM_LOADFILE(a) CR (a, HTTP_BOOT_VIRTUAL_NIC, LoadFile, HTTP_BOOT_VIRTUAL_NIC_SIGNATURE)
|
||||
extern EFI_LOAD_FILE_PROTOCOL gHttpBootDxeLoadFile;
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootIp4DxeDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootIp4DxeDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootIp4DxeDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller. If a child device is provided,
|
||||
it further tests to see if this driver supports creating a handle for the specified child device.
|
||||
|
||||
This function checks to see if the driver specified by This supports the device specified by
|
||||
ControllerHandle. Drivers will typically use the device path attached to
|
||||
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||||
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||||
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||||
performed by this function must be very small, and take as little time as possible to execute. This
|
||||
function must not change the state of any hardware devices, and this function must be aware that the
|
||||
device specified by ControllerHandle may already be managed by the same driver or a
|
||||
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||||
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||||
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||||
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||||
to guarantee the state of ControllerHandle is not modified by this function.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For bus drivers, if this parameter is not NULL, then
|
||||
the bus driver must determine if the bus controller specified
|
||||
by ControllerHandle and the child controller specified
|
||||
by RemainingDevicePath are both supported by this
|
||||
bus driver.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by the driver
|
||||
specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by a different
|
||||
driver or an application that requires exclusive access.
|
||||
Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the driver specified by This.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootIp6DxeDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Starts a device controller or a bus controller.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||||
common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||||
EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||||
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||||
parameter is ignored by device drivers, and is optional for bus
|
||||
drivers. For a bus driver, if this parameter is NULL, then handles
|
||||
for all the children of Controller are created by this driver.
|
||||
If this parameter is not NULL and the first Device Path Node is
|
||||
not the End of Device Path Node, then only the handle for the
|
||||
child device specified by the first Device Path Node of
|
||||
RemainingDevicePath is created by this driver.
|
||||
If the first Device Path Node of RemainingDevicePath is
|
||||
the End of Device Path Node, no child handle is created by this
|
||||
driver.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootIp6DxeDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stops a device controller or a bus controller.
|
||||
|
||||
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
HttpBootIp6DxeDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||||
);
|
||||
#endif
|
|
@ -0,0 +1,99 @@
|
|||
## @file
|
||||
# This modules produce the Load File Protocol for UEFI HTTP boot.
|
||||
#
|
||||
# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = HttpBootDxe
|
||||
FILE_GUID = ecebcb00-d9c8-11e4-af3d-8cdcd426c973
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = HttpBootDxeDriverEntryPoint
|
||||
UNLOAD_IMAGE = NetLibDefaultUnload
|
||||
MODULE_UNI_FILE = HttpBootDxe.uni
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
NetworkPkg/NetworkPkg.dec
|
||||
|
||||
[Sources]
|
||||
HttpBootConfigNVDataStruc.h
|
||||
HttpBootDxe.h
|
||||
HttpBootDxe.c
|
||||
HttpBootConfig.h
|
||||
HttpBootConfig.c
|
||||
HttpBootComponentName.h
|
||||
HttpBootComponentName.c
|
||||
HttpBootImpl.h
|
||||
HttpBootImpl.c
|
||||
HttpBootDhcp4.h
|
||||
HttpBootDhcp4.c
|
||||
HttpBootDhcp6.h
|
||||
HttpBootDhcp6.c
|
||||
HttpBootSupport.h
|
||||
HttpBootSupport.c
|
||||
HttpBootClient.h
|
||||
HttpBootClient.c
|
||||
HttpBootConfigVfr.vfr
|
||||
HttpBootConfigStrings.uni
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
MemoryAllocationLib
|
||||
BaseLib
|
||||
UefiLib
|
||||
DevicePathLib
|
||||
DebugLib
|
||||
NetLib
|
||||
HttpLib
|
||||
HiiLib
|
||||
PrintLib
|
||||
DpcLib
|
||||
UefiHiiServicesLib
|
||||
UefiBootManagerLib
|
||||
|
||||
[Protocols]
|
||||
## TO_START
|
||||
## BY_START
|
||||
gEfiDevicePathProtocolGuid
|
||||
|
||||
gEfiLoadFileProtocolGuid ## BY_START
|
||||
gEfiHttpServiceBindingProtocolGuid ## CONSUMES
|
||||
gEfiHttpProtocolGuid ## CONSUMES
|
||||
gEfiDhcp4ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiDhcp4ProtocolGuid ## TO_START
|
||||
gEfiIp4Config2ProtocolGuid ## TO_START
|
||||
gEfiDhcp6ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiDhcp6ProtocolGuid ## TO_START
|
||||
gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiIp6ServiceBindingProtocolGuid ## TO_START
|
||||
gEfiIp6ProtocolGuid ## TO_START
|
||||
gEfiIp6ConfigProtocolGuid ## TO_START
|
||||
gEfiNetworkInterfaceIdentifierProtocolGuid_31 ## SOMETIMES_CONSUMES
|
||||
gEfiRamDiskProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiHiiConfigAccessProtocolGuid ## BY_START
|
||||
gEfiHttpBootCallbackProtocolGuid ## SOMETIMES_PRODUCES
|
||||
gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[Guids]
|
||||
## SOMETIMES_CONSUMES ## GUID # HiiIsConfigHdrMatch mHttpBootConfigStorageName
|
||||
## SOMETIMES_PRODUCES ## GUID # HiiConstructConfigHdr mHttpBootConfigStorageName
|
||||
## SOMETIMES_PRODUCES ## GUID # HiiGetBrowserData mHttpBootConfigStorageName
|
||||
## SOMETIMES_CONSUMES ## HII
|
||||
gHttpBootConfigGuid
|
||||
gEfiVirtualCdGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
gEfiVirtualDiskGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
gEfiAdapterInfoUndiIpv6SupportGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
|
||||
[Pcd]
|
||||
gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections ## CONSUMES
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
HttpBootDxeExtra.uni
|
|
@ -0,0 +1,18 @@
|
|||
// /** @file
|
||||
// UEFI HTTP boot service.
|
||||
//
|
||||
// This driver provides EFI Load File Protocol which is used to download
|
||||
// the boot image from HTTP server. It could work with an IPv4 or IPv6 stack.
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "UEFI HTTP boot service"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This driver provides EFI Load File Protocol which is used to download the boot image from HTTP server. It could work with an IPv4 or IPv6 stack."
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue