sync sources wuth new edk2

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2019-09-04 13:44:38 +03:00
parent 01473834b9
commit 15dada20e6
441 changed files with 200955 additions and 2666 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@
.DS_Store
*.swp
*.lock
*.bak
*~
# /CloverPackage/

View File

@ -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

View File

@ -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

View File

@ -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
#

View File

@ -153,7 +153,7 @@
gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
# gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES

View File

@ -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;
}

View File

@ -26,8 +26,8 @@
[Packages]
CloverPkg.dec
MdePkg/MdePkg.dec
# MdeModulePkg/MdeModulePkg.dec
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
MdeModulePkg/MdeModulePkg.dec
# IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
BaseLib

View File

@ -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.

View File

@ -1262,7 +1262,7 @@ extern EFI_GUID gEfiShellProtocolGuid;
enum ShellVersion {
SHELL_MAJOR_VERSION = 2,
SHELL_MINOR_VERSION = 204
SHELL_MINOR_VERSION = 205
};
#endif

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
**/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 :

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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 ()

View File

@ -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

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
#

View File

@ -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;
}

View File

@ -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

View File

@ -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."

View File

@ -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"

View File

@ -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"

View File

@ -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
);
}

View File

@ -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

View File

@ -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

View File

@ -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."

View File

@ -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"

1667
NetworkPkg/ArpDxe/ArpImpl.c Normal file

File diff suppressed because it is too large Load Diff

770
NetworkPkg/ArpDxe/ArpImpl.h Normal file
View File

@ -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

739
NetworkPkg/ArpDxe/ArpMain.c Normal file
View File

@ -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;
}

View File

@ -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)
);
}

View File

@ -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)
);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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."

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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)
);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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."

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
);
}

758
NetworkPkg/DnsDxe/DnsDhcp.c Normal file
View File

@ -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;
}

141
NetworkPkg/DnsDxe/DnsDhcp.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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."

View File

@ -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"

2243
NetworkPkg/DnsDxe/DnsImpl.c Normal file

File diff suppressed because it is too large Load Diff

1209
NetworkPkg/DnsDxe/DnsImpl.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

341
NetworkPkg/DpcDxe/Dpc.c Normal file
View File

@ -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;
}

80
NetworkPkg/DpcDxe/Dpc.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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."

View File

@ -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

View File

@ -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

View File

@ -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)
);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 ""

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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