Import ArpDxe, Dhcp4Dxe, Ip4Dxe, Mtftp4Dxe, PxeBcDxe and PxeDhcp4Dxe.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3492 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
162
MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c
Normal file
162
MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
ComponentName.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Dhcp4Impl.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DhcpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
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
|
||||
//
|
||||
EFI_COMPONENT_NAME_PROTOCOL gDhcp4ComponentName = {
|
||||
DhcpComponentNameGetDriverName,
|
||||
DhcpComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
static EFI_UNICODE_STRING_TABLE mDhcpDriverNameTable[] = {
|
||||
{
|
||||
"eng",
|
||||
L"DHCP Protocol Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DhcpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
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.
|
||||
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.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCES - The Unicode string for the Driver specified by This
|
||||
and the language specified by Language was returned
|
||||
in DriverName.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - DriverName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return LookupUnicodeString (
|
||||
Language,
|
||||
gDhcp4ComponentName.SupportedLanguages,
|
||||
mDhcpDriverNameTable,
|
||||
DriverName
|
||||
);
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by an EFI Driver.
|
||||
|
||||
Arguments:
|
||||
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
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.
|
||||
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.
|
||||
Language - A pointer to a three character ISO 639-2 language
|
||||
identifier. This is the language of the controller 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.
|
||||
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.
|
||||
|
||||
Returns:
|
||||
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.
|
||||
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - ChildHandle isn't NULL and isn't a valid EFI_HANDLE.
|
||||
EFI_INVALID_PARAMETER - Language is NULL.
|
||||
EFI_INVALID_PARAMETER - ControllerName is NULL.
|
||||
EFI_UNSUPPORTED - The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
EFI_UNSUPPORTED - The driver specified by This does not support the
|
||||
language specified by Language.
|
||||
|
||||
--*/
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
665
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
Normal file
665
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
Normal file
@@ -0,0 +1,665 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
Dhcp4Driver.c
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#include "Dhcp4Impl.h"
|
||||
#include "Dhcp4Driver.h"
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gDhcp4DriverBinding = {
|
||||
Dhcp4DriverBindingSupported,
|
||||
Dhcp4DriverBindingStart,
|
||||
Dhcp4DriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EFI_SERVICE_BINDING_PROTOCOL mDhcp4ServiceBindingTemplete = {
|
||||
Dhcp4ServiceBindingCreateChild,
|
||||
Dhcp4ServiceBindingDestroyChild
|
||||
};
|
||||
|
||||
//@MT: EFI_DRIVER_ENTRY_POINT (Dhcp4DriverEntryPoint)
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Entry point of the DHCP driver to install various protocols.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - The driver's image handle
|
||||
SystemTable - The system table
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - All the related protocols are installed.
|
||||
Others - Failed to install the protocols.
|
||||
|
||||
--*/
|
||||
{
|
||||
return NetLibInstallAllDriverProtocols (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gDhcp4DriverBinding,
|
||||
ImageHandle,
|
||||
&gDhcp4ComponentName,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test to see if DHCP driver supports the ControllerHandle.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ControllerHandle Handle of device to test
|
||||
@param RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCES This driver supports 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 UdpIo The UDP IO port to configure
|
||||
@param Context The context to the function
|
||||
|
||||
@retval EFI_SUCCESS The UDP IO port is successfully configured.
|
||||
@retval Others Failed to configure the UDP child.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpConfigUdpIo (
|
||||
IN UDP_IO_PORT *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;
|
||||
|
||||
NetZeroMem (&UdpConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
NetZeroMem (&UdpConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
|
||||
NetZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
return UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfigData);;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Destory the DHCP service. The Dhcp4 service may be partly initialized,
|
||||
or partly destoried. If a resource is destoried, it is marked as so in
|
||||
case the destory failed and being called again later.
|
||||
|
||||
@param DhcpSb The DHCP service instance to destory.
|
||||
|
||||
@retval EFI_SUCCESS The DHCP service is successfully closed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp4CloseService (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
)
|
||||
{
|
||||
DhcpCleanLease (DhcpSb);
|
||||
|
||||
if (DhcpSb->UdpIo != NULL) {
|
||||
UdpIoFreePort (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 Controller The controller to install DHCP service binding
|
||||
protocol onto
|
||||
@param ImageHandle The driver's image handle
|
||||
@param 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.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
Dhcp4CreateService (
|
||||
IN EFI_HANDLE Controller,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT DHCP_SERVICE **Service
|
||||
)
|
||||
{
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_STATUS Status;
|
||||
|
||||
*Service = NULL;
|
||||
DhcpSb = NetAllocateZeroPool (sizeof (DHCP_SERVICE));
|
||||
|
||||
if (DhcpSb == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
DhcpSb->Signature = DHCP_SERVICE_SIGNATURE;
|
||||
DhcpSb->ServiceBinding = mDhcp4ServiceBindingTemplete;
|
||||
DhcpSb->ServiceState = DHCP_UNCONFIGED;
|
||||
DhcpSb->InDestory = FALSE;
|
||||
DhcpSb->Controller = Controller;
|
||||
DhcpSb->Image = ImageHandle;
|
||||
NetListInit (&DhcpSb->Children);
|
||||
DhcpSb->DhcpState = Dhcp4Stopped;
|
||||
DhcpSb->Xid = NET_RANDOM (NetRandomInitSeed ());
|
||||
|
||||
//
|
||||
// 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 = UdpIoCreatePort (Controller, ImageHandle, DhcpConfigUdpIo, 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 (EFI_MAC_ADDRESS));
|
||||
|
||||
*Service = DhcpSb;
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
Dhcp4CloseService (DhcpSb);
|
||||
NetFreePool (DhcpSb);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ControllerHandle Handle of device to bind driver to
|
||||
@param RemainingDevicePath Optional parameter use to pick a specific child
|
||||
device to start.
|
||||
|
||||
@retval EFI_SUCCES 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;
|
||||
}
|
||||
|
||||
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);
|
||||
NetFreePool (DhcpSb);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ControllerHandle Handle of device to stop driver on
|
||||
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
|
||||
of children is zero stop the entire bus driver.
|
||||
@param ChildHandleBuffer List of Child Handles to Stop.
|
||||
|
||||
@retval EFI_SUCCES 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;
|
||||
DHCP_PROTOCOL *Instance;
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// 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 (DhcpSb->InDestory) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
DhcpSb->InDestory = TRUE;
|
||||
|
||||
//
|
||||
// Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild
|
||||
// may cause other child to be deleted.
|
||||
//
|
||||
while (!NetListIsEmpty (&DhcpSb->Children)) {
|
||||
Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link);
|
||||
Dhcp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle);
|
||||
}
|
||||
|
||||
if (DhcpSb->NumChildren != 0) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
DhcpSb->ServiceState = DHCP_DESTORY;
|
||||
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
NicHandle,
|
||||
&gEfiDhcp4ServiceBindingProtocolGuid,
|
||||
ServiceBinding
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Dhcp4CloseService (DhcpSb);
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
NetFreePool (DhcpSb);
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
DhcpSb->InDestory = FALSE;
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize a new DHCP child
|
||||
|
||||
@param DhcpSb The dhcp service instance
|
||||
@param Instance The dhcp instance to initialize
|
||||
|
||||
@return None
|
||||
|
||||
**/
|
||||
VOID
|
||||
DhcpInitProtocol (
|
||||
IN DHCP_SERVICE *DhcpSb,
|
||||
IN DHCP_PROTOCOL *Instance
|
||||
)
|
||||
{
|
||||
Instance->Signature = DHCP_PROTOCOL_SIGNATURE;
|
||||
CopyMem (&Instance->Dhcp4Protocol, &mDhcp4ProtocolTemplate, sizeof (EFI_DHCP4_PROTOCOL));
|
||||
NetListInit (&Instance->Link);
|
||||
Instance->Handle = NULL;
|
||||
Instance->Service = DhcpSb;
|
||||
Instance->InDestory = FALSE;
|
||||
Instance->CompletionEvent = NULL;
|
||||
Instance->RenewRebindEvent = NULL;
|
||||
Instance->Token = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Creates a child handle with a set of DHCP4 services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If
|
||||
it is NULL, then a new handle is created. If it
|
||||
is not NULL, then the DHCP4 services are added to
|
||||
the existing child handle.
|
||||
|
||||
@retval EFI_SUCCES The child handle was created with the DHCP4
|
||||
services
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources 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 = NetAllocatePool (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)) {
|
||||
NetFreePool (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
|
||||
);
|
||||
|
||||
NetFreePool (Instance);
|
||||
return Status;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
NetListInsertTail (&DhcpSb->Children, &Instance->Link);
|
||||
DhcpSb->NumChildren++;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a set of DHCP4 services.
|
||||
|
||||
@param This Protocol instance pointer.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The DHCP4 service is removed from the child handle
|
||||
@retval EFI_UNSUPPORTED The child handle does not support the DHCP4
|
||||
service
|
||||
@retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
|
||||
@retval EFI_ACCESS_DENIED The child handle could not be destroyed because
|
||||
its DHCP4 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 destoried more than once. For example,
|
||||
// Dhcp4DriverBindingStop will destory all of its children.
|
||||
// when caller driver is being stopped, it will destory the
|
||||
// dhcp child it opens.
|
||||
//
|
||||
if (Instance->InDestory) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
Instance->InDestory = 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.
|
||||
//
|
||||
Status = gBS->UninstallProtocolInterface (
|
||||
ChildHandle,
|
||||
&gEfiDhcp4ProtocolGuid,
|
||||
Dhcp
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Instance->InDestory = FALSE;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (DhcpSb->ActiveChild == Instance) {
|
||||
DhcpYieldControl (DhcpSb);
|
||||
}
|
||||
|
||||
NetListRemoveEntry (&Instance->Link);
|
||||
DhcpSb->NumChildren--;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
NetFreePool (Instance);
|
||||
return EFI_SUCCESS;
|
||||
}
|
67
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h
Normal file
67
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
Dhcp4Driver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Header for the DHCP4 driver
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_DRIVER_H__
|
||||
#define __EFI_DHCP4_DRIVER_H__
|
||||
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gDhcp4ComponentName;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4ServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
Dhcp4ServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
#endif
|
65
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
Normal file
65
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
Normal file
@@ -0,0 +1,65 @@
|
||||
#/** @file
|
||||
# Component name for module Dhcp4
|
||||
#
|
||||
# Copyright (c) 2007, Intel Corporation
|
||||
#
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = Dhcp4Dxe
|
||||
FILE_GUID = 94734718-0BBC-47fb-96A5-EE7A5AE6A2AD
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
ENTRY_POINT = Dhcp4DriverEntryPoint
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
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
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
DebugLib
|
||||
NetLib
|
||||
UdpIoLib
|
||||
|
||||
|
||||
[Protocols]
|
||||
gEfiUdp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDhcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiUdp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiDhcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
|
77
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.msa
Normal file
77
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.msa
Normal file
@@ -0,0 +1,77 @@
|
||||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<MsaHeader>
|
||||
<ModuleName>Dhcp4Dxe</ModuleName>
|
||||
<ModuleType>DXE_DRIVER</ModuleType>
|
||||
<GuidValue>94734718-0BBC-47fb-96A5-EE7A5AE6A2AD</GuidValue>
|
||||
<Version>1.0</Version>
|
||||
<Abstract>Component name for module Dhcp4</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2007, Intel Corporation. All rights reserved.</Copyright>
|
||||
<License>All rights reserved. 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.</License>
|
||||
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
|
||||
</MsaHeader>
|
||||
<ModuleDefinitions>
|
||||
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
|
||||
<BinaryModule>false</BinaryModule>
|
||||
<OutputFileBasename>Dhcp4Dxe</OutputFileBasename>
|
||||
</ModuleDefinitions>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>DebugLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiDriverEntryPoint</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiBootServicesTableLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>UefiLib</Keyword>
|
||||
</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">
|
||||
<Keyword>BaseLib</Keyword>
|
||||
</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>Dhcp4Impl.h</Filename>
|
||||
<Filename>Dhcp4Option.h</Filename>
|
||||
<Filename>Dhcp4Option.c</Filename>
|
||||
<Filename>Dhcp4Driver.c</Filename>
|
||||
<Filename>Dhcp4Driver.h</Filename>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
<Filename>Dhcp4Io.h</Filename>
|
||||
<Filename>Dhcp4Io.c</Filename>
|
||||
<Filename>Dhcp4Impl.c</Filename>
|
||||
</SourceFiles>
|
||||
<PackageDependencies>
|
||||
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
|
||||
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
|
||||
</PackageDependencies>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiDhcp4ProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiUdp4ProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiDhcp4ServiceBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">
|
||||
<ProtocolCName>gEfiUdp4ServiceBindingProtocolGuid</ProtocolCName>
|
||||
</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>Dhcp4DriverEntryPoint</ModuleEntryPoint>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
914
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
Normal file
914
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
Normal file
@@ -0,0 +1,914 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
Dhcp4Impl.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This file implement the EFI_DHCP4_PROTOCOL interface.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include "Dhcp4Impl.h"
|
||||
|
||||
|
||||
/**
|
||||
Get the current operation parameter and lease for the network interface.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
@param Dhcp4ModeData The variable to save the DHCP mode data.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameter is invalid
|
||||
@retval EFI_SUCCESS The Dhcp4ModeData is updated with the current
|
||||
operation parameter.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4GetModeData (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
OUT EFI_DHCP4_MODE_DATA *Dhcp4ModeData
|
||||
)
|
||||
{
|
||||
DHCP_PROTOCOL *Instance;
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
DHCP_PARAMETER *Para;
|
||||
EFI_TPL OldTpl;
|
||||
IP4_ADDR Ip;
|
||||
|
||||
//
|
||||
// First validate the parameters.
|
||||
//
|
||||
if ((This == NULL) || (Dhcp4ModeData == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
DhcpSb = Instance->Service;
|
||||
|
||||
//
|
||||
// Caller can use GetModeData to retrieve current DHCP states
|
||||
// no matter whether it is the active child or not.
|
||||
//
|
||||
Dhcp4ModeData->State = DhcpSb->DhcpState;
|
||||
CopyMem (&Dhcp4ModeData->ConfigData, &DhcpSb->ActiveConfig, sizeof (EFI_DHCP4_CONFIG_DATA));
|
||||
CopyMem (&Dhcp4ModeData->ClientMacAddress, &DhcpSb->Mac, sizeof (EFI_MAC_ADDRESS));
|
||||
|
||||
Ip = HTONL (DhcpSb->ClientAddr);
|
||||
NetCopyMem (&Dhcp4ModeData->ClientAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
Ip = HTONL (DhcpSb->Netmask);
|
||||
NetCopyMem (&Dhcp4ModeData->SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
Ip = HTONL (DhcpSb->ServerAddr);
|
||||
NetCopyMem (&Dhcp4ModeData->ServerAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));
|
||||
|
||||
Para = DhcpSb->Para;
|
||||
|
||||
if (Para != NULL) {
|
||||
Ip = HTONL (Para->Router);
|
||||
NetCopyMem (&Dhcp4ModeData->RouterAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));
|
||||
Dhcp4ModeData->LeaseTime = Para->Lease;
|
||||
} else {
|
||||
NetZeroMem (&Dhcp4ModeData->RouterAddress, sizeof (EFI_IPv4_ADDRESS));
|
||||
Dhcp4ModeData->LeaseTime = 0xffffffff;
|
||||
}
|
||||
|
||||
Dhcp4ModeData->ReplyPacket = DhcpSb->Selected;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
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
|
||||
|
||||
@return None
|
||||
|
||||
**/
|
||||
VOID
|
||||
DhcpCleanConfigure (
|
||||
IN EFI_DHCP4_CONFIG_DATA *Config
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
|
||||
if (Config->DiscoverTimeout != NULL) {
|
||||
NetFreePool (Config->DiscoverTimeout);
|
||||
}
|
||||
|
||||
if (Config->RequestTimeout != NULL) {
|
||||
NetFreePool (Config->RequestTimeout);
|
||||
}
|
||||
|
||||
if (Config->OptionList != NULL) {
|
||||
for (Index = 0; Index < Config->OptionCount; Index++) {
|
||||
if (Config->OptionList[Index] != NULL) {
|
||||
NetFreePool (Config->OptionList[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
NetFreePool (Config->OptionList);
|
||||
}
|
||||
|
||||
NetZeroMem (Config, sizeof (EFI_DHCP4_CONFIG_DATA));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Allocate memory for configure parameter such as timeout value for Dst,
|
||||
then copy the configure parameter from Src to Dst.
|
||||
|
||||
@param Dst The destination DHCP configure data.
|
||||
@param Src The source DHCP configure data.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
|
||||
@retval EFI_SUCCESS The configure is copied.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DhcpCopyConfigure (
|
||||
IN EFI_DHCP4_CONFIG_DATA *Dst,
|
||||
IN EFI_DHCP4_CONFIG_DATA *Src
|
||||
)
|
||||
{
|
||||
EFI_DHCP4_PACKET_OPTION **DstOptions;
|
||||
EFI_DHCP4_PACKET_OPTION **SrcOptions;
|
||||
INTN Len;
|
||||
UINT32 Index;
|
||||
|
||||
CopyMem (Dst, Src, sizeof (EFI_DHCP4_CONFIG_DATA));
|
||||
Dst->DiscoverTimeout = NULL;
|
||||
Dst->RequestTimeout = NULL;
|
||||
Dst->OptionList = NULL;
|
||||
|
||||
//
|
||||
// Allocate a memory then copy DiscoverTimeout to it
|
||||
//
|
||||
if (Src->DiscoverTimeout != NULL) {
|
||||
Len = Src->DiscoverTryCount * sizeof (UINT32);
|
||||
Dst->DiscoverTimeout = NetAllocatePool (Len);
|
||||
|
||||
if (Dst->DiscoverTimeout == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Src->DiscoverTryCount; Index++) {
|
||||
Dst->DiscoverTimeout[Index] = NET_MAX (Src->DiscoverTimeout[Index], 1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate a memory then copy RequestTimeout to it
|
||||
//
|
||||
if (Src->RequestTimeout != NULL) {
|
||||
Len = Src->RequestTryCount * sizeof (UINT32);
|
||||
Dst->RequestTimeout = NetAllocatePool (Len);
|
||||
|
||||
if (Dst->RequestTimeout == NULL) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Src->RequestTryCount; Index++) {
|
||||
Dst->RequestTimeout[Index] = NET_MAX (Src->RequestTimeout[Index], 1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate an array of dhcp option point, then allocate memory
|
||||
// for each option and copy the source option to it
|
||||
//
|
||||
if (Src->OptionList != NULL) {
|
||||
Len = Src->OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *);
|
||||
Dst->OptionList = NetAllocateZeroPool (Len);
|
||||
|
||||
if (Dst->OptionList == NULL) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
DstOptions = Dst->OptionList;
|
||||
SrcOptions = Src->OptionList;
|
||||
|
||||
for (Index = 0; Index < Src->OptionCount; Index++) {
|
||||
Len = sizeof (EFI_DHCP4_PACKET_OPTION) + NET_MAX (SrcOptions[Index]->Length - 1, 0);
|
||||
|
||||
DstOptions[Index] = NetAllocatePool (Len);
|
||||
|
||||
if (DstOptions[Index] == NULL) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
NetCopyMem (DstOptions[Index], SrcOptions[Index], Len);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
DhcpCleanConfigure (Dst);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
@return None
|
||||
|
||||
**/
|
||||
VOID
|
||||
DhcpYieldControl (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
)
|
||||
{
|
||||
EFI_DHCP4_CONFIG_DATA *Config;
|
||||
DHCP_PROTOCOL *Instance;
|
||||
|
||||
Instance = DhcpSb->ActiveChild;
|
||||
Config = &DhcpSb->ActiveConfig;
|
||||
|
||||
DhcpSb->ServiceState = DHCP_UNCONFIGED;
|
||||
DhcpSb->ActiveChild = NULL;
|
||||
|
||||
if (Config->DiscoverTimeout != NULL) {
|
||||
NetFreePool (Config->DiscoverTimeout);
|
||||
|
||||
Config->DiscoverTryCount = 0;
|
||||
Config->DiscoverTimeout = NULL;
|
||||
}
|
||||
|
||||
if (Config->RequestTimeout != NULL) {
|
||||
NetFreePool (Config->RequestTimeout);
|
||||
|
||||
Config->RequestTryCount = 0;
|
||||
Config->RequestTimeout = NULL;
|
||||
}
|
||||
|
||||
Config->Dhcp4Callback = NULL;
|
||||
Config->CallbackContext = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Configure the DHCP protocol instance and its underlying DHCP service
|
||||
for operation. If Dhcp4CfgData is NULL and the child is currently
|
||||
controlling the DHCP service, release the control.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
@param Dhcp4CfgData The DHCP configure data.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameters are invalid.
|
||||
@retval EFI_ACCESS_DENIED The service isn't in one of configurable states,
|
||||
or there is already an active child.
|
||||
@retval EFI_OUT_OF_RESOURCE Failed to allocate some resources.
|
||||
@retval EFI_SUCCESS The child is configured.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4Configure (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
IN EFI_DHCP4_CONFIG_DATA *Dhcp4CfgData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_DHCP4_CONFIG_DATA *Config;
|
||||
DHCP_PROTOCOL *Instance;
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
UINT32 Index;
|
||||
IP4_ADDR Ip;
|
||||
|
||||
//
|
||||
// First validate the parameters
|
||||
//
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Dhcp4CfgData != NULL) {
|
||||
if (Dhcp4CfgData->DiscoverTryCount && (Dhcp4CfgData->DiscoverTimeout == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Dhcp4CfgData->RequestTryCount && (Dhcp4CfgData->RequestTimeout == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (Dhcp4CfgData->OptionCount && (Dhcp4CfgData->OptionList == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
NetCopyMem (&Ip, &Dhcp4CfgData->ClientAddress, sizeof (IP4_ADDR));
|
||||
|
||||
if ((Ip != 0) && !Ip4IsUnicast (NTOHL (Ip), 0)) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
|
||||
DhcpSb = Instance->Service;
|
||||
Config = &DhcpSb->ActiveConfig;
|
||||
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
|
||||
if ((DhcpSb->DhcpState != Dhcp4Stopped) &&
|
||||
(DhcpSb->DhcpState != Dhcp4Init) &&
|
||||
(DhcpSb->DhcpState != Dhcp4InitReboot) &&
|
||||
(DhcpSb->DhcpState != Dhcp4Bound)) {
|
||||
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if ((DhcpSb->ActiveChild != NULL) && (DhcpSb->ActiveChild != Instance)) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (Dhcp4CfgData != NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
DhcpCleanConfigure (Config);
|
||||
|
||||
if (EFI_ERROR (DhcpCopyConfigure (Config, Dhcp4CfgData))) {
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
DhcpSb->UserOptionLen = 0;
|
||||
|
||||
for (Index = 0; Index < Dhcp4CfgData->OptionCount; Index++) {
|
||||
DhcpSb->UserOptionLen += Dhcp4CfgData->OptionList[Index]->Length + 2;
|
||||
}
|
||||
|
||||
DhcpSb->ActiveChild = Instance;
|
||||
|
||||
if (DhcpSb->DhcpState == Dhcp4Stopped) {
|
||||
DhcpSb->ClientAddr = EFI_NTOHL (Dhcp4CfgData->ClientAddress);
|
||||
|
||||
if (DhcpSb->ClientAddr != 0) {
|
||||
DhcpSb->DhcpState = Dhcp4InitReboot;
|
||||
} else {
|
||||
DhcpSb->DhcpState = Dhcp4Init;
|
||||
}
|
||||
}
|
||||
|
||||
DhcpSb->ServiceState = DHCP_CONFIGED;
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
} else if (DhcpSb->ActiveChild == Instance) {
|
||||
Status = EFI_SUCCESS;
|
||||
DhcpYieldControl (DhcpSb);
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start the DHCP process.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
@param CompletionEvent The event to signal is address is acquired.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameters are invalid.
|
||||
@retval EFI_NOT_STARTED The protocol hasn't been configured.
|
||||
@retval EFI_ALREADY_STARTED The DHCP process has already been started.
|
||||
@retval EFI_SUCCESS The DHCP process is started.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4Start (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
IN EFI_EVENT CompletionEvent OPTIONAL
|
||||
)
|
||||
{
|
||||
DHCP_PROTOCOL *Instance;
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// First validate the parameters
|
||||
//
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
DhcpSb = Instance->Service;
|
||||
|
||||
if (DhcpSb->DhcpState == Dhcp4Stopped) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
if ((DhcpSb->DhcpState != Dhcp4Init) && (DhcpSb->DhcpState != Dhcp4InitReboot)) {
|
||||
Status = EFI_ALREADY_STARTED;
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
DhcpSb->IoStatus = EFI_ALREADY_STARTED;
|
||||
|
||||
if (EFI_ERROR (Status = DhcpInitRequest (DhcpSb))) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Start/Restart the receiving.
|
||||
//
|
||||
Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);
|
||||
|
||||
if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Instance->CompletionEvent = CompletionEvent;
|
||||
|
||||
//
|
||||
// Restore the TPL now, don't call poll function at NET_TPL_LOCK.
|
||||
//
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
if (CompletionEvent == NULL) {
|
||||
while (DhcpSb->IoStatus == EFI_ALREADY_STARTED) {
|
||||
DhcpSb->UdpIo->Udp->Poll (DhcpSb->UdpIo->Udp);
|
||||
}
|
||||
|
||||
return DhcpSb->IoStatus;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Request an extra manual renew/rebind.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
@param RebindRequest TRUE if request a rebind, otherwise renew it
|
||||
@param CompletionEvent Event to signal when complete
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameters are invalid
|
||||
@retval EFI_NOT_STARTED The DHCP protocol hasn't been started.
|
||||
@retval EFI_ACCESS_DENIED The DHCP protocol isn't in Bound state.
|
||||
@retval EFI_SUCCESS The DHCP is renewed/rebound.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4RenewRebind (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
IN BOOLEAN RebindRequest,
|
||||
IN EFI_EVENT CompletionEvent OPTIONAL
|
||||
)
|
||||
{
|
||||
DHCP_PROTOCOL *Instance;
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// First validate the parameters
|
||||
//
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
DhcpSb = Instance->Service;
|
||||
|
||||
if (DhcpSb->DhcpState == Dhcp4Stopped) {
|
||||
Status = EFI_NOT_STARTED;
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
if (DhcpSb->DhcpState != Dhcp4Bound) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
if (DHCP_IS_BOOTP (DhcpSb->Para)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Transit the states then send a extra DHCP request
|
||||
//
|
||||
if (!RebindRequest) {
|
||||
DhcpSetState (DhcpSb, Dhcp4Renewing, FALSE);
|
||||
} else {
|
||||
DhcpSetState (DhcpSb, Dhcp4Rebinding, FALSE);
|
||||
}
|
||||
|
||||
Status = DhcpSendMessage (
|
||||
DhcpSb,
|
||||
DhcpSb->Selected,
|
||||
DhcpSb->Para,
|
||||
DHCP_MSG_REQUEST,
|
||||
"Extra renew/rebind by the application"
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DhcpSetState (DhcpSb, Dhcp4Bound, FALSE);
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
DhcpSb->ExtraRefresh = TRUE;
|
||||
DhcpSb->IoStatus = EFI_ALREADY_STARTED;
|
||||
Instance->RenewRebindEvent = CompletionEvent;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
|
||||
if (CompletionEvent == NULL) {
|
||||
while (DhcpSb->IoStatus == EFI_ALREADY_STARTED) {
|
||||
DhcpSb->UdpIo->Udp->Poll (DhcpSb->UdpIo->Udp);
|
||||
}
|
||||
|
||||
return DhcpSb->IoStatus;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ON_ERROR:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Release the current acquired lease.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameter is invalid
|
||||
@retval EFI_DEVICE_ERROR Failed to transmit the DHCP release packet
|
||||
@retval EFI_ACCESS_DENIED The DHCP service isn't in one of the connected
|
||||
state.
|
||||
@retval EFI_SUCCESS The lease is released.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4Release (
|
||||
IN EFI_DHCP4_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
DHCP_PROTOCOL *Instance;
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// First validate the parameters
|
||||
//
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
DhcpSb = Instance->Service;
|
||||
|
||||
if ((DhcpSb->DhcpState != Dhcp4InitReboot) && (DhcpSb->DhcpState != Dhcp4Bound)) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
if (!DHCP_IS_BOOTP (DhcpSb->Para) && (DhcpSb->DhcpState == Dhcp4Bound)) {
|
||||
Status = DhcpSendMessage (
|
||||
DhcpSb,
|
||||
DhcpSb->Selected,
|
||||
DhcpSb->Para,
|
||||
DHCP_MSG_RELEASE,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
DhcpCleanLease (DhcpSb);
|
||||
|
||||
ON_EXIT:
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop the current DHCP process. After this, other DHCP child
|
||||
can gain control of the service, configure and use it.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameter is invalid.
|
||||
@retval EFI_SUCCESS The DHCP process is stopped.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4Stop (
|
||||
IN EFI_DHCP4_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
DHCP_PROTOCOL *Instance;
|
||||
DHCP_SERVICE *DhcpSb;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// First validate the parameters
|
||||
//
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = DHCP_INSTANCE_FROM_THIS (This);
|
||||
|
||||
if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);
|
||||
DhcpSb = Instance->Service;
|
||||
|
||||
DhcpCleanLease (DhcpSb);
|
||||
|
||||
DhcpSb->DhcpState = Dhcp4Stopped;
|
||||
DhcpSb->ServiceState = DHCP_UNCONFIGED;
|
||||
|
||||
NET_RESTORE_TPL (OldTpl);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Build a new DHCP packet from the seed packet. Options may be deleted or
|
||||
appended. The caller should free the NewPacket when finished using it.
|
||||
|
||||
@param This The DHCP protocol instance.
|
||||
@param SeedPacket The seed packet to start with
|
||||
@param DeleteCount The number of options to delete
|
||||
@param DeleteList The options to delete from the packet
|
||||
@param AppendCount The number of options to append
|
||||
@param AppendList The options to append to the packet
|
||||
@param NewPacket The new packet, allocated and built by this
|
||||
function.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameters are invalid.
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
|
||||
@retval EFI_SUCCESS The packet is build.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4Build (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
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
|
||||
)
|
||||
{
|
||||
//
|
||||
// First validate the parameters
|
||||
//
|
||||
if ((This == NULL) || (NewPacket == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((SeedPacket == NULL) || (SeedPacket->Dhcp4.Magik != DHCP_OPTION_MAGIC) ||
|
||||
EFI_ERROR (DhcpValidateOptions (SeedPacket, NULL))) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (((DeleteCount == 0) && (AppendCount == 0)) ||
|
||||
((DeleteCount != 0) && (DeleteList == NULL)) ||
|
||||
((AppendCount != 0) && (AppendList == NULL))) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return DhcpBuild (
|
||||
SeedPacket,
|
||||
DeleteCount,
|
||||
DeleteList,
|
||||
AppendCount,
|
||||
AppendList,
|
||||
NewPacket
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Transmit and receive a packet through this DHCP service.
|
||||
This is unsupported.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
@param Token The transmit and receive instance
|
||||
|
||||
@retval EFI_UNSUPPORTED It always returns unsupported.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4TransmitReceive (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
IN EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token
|
||||
)
|
||||
{
|
||||
//
|
||||
// This function is for PXE, leave it for now
|
||||
//
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Callback function for DhcpIterateOptions. This callback sets the
|
||||
EFI_DHCP4_PACKET_OPTION array in the DHCP_PARSE_CONTEXT to point
|
||||
the individual DHCP option in the packet.
|
||||
|
||||
@param Tag The DHCP option type
|
||||
@param Len length of the DHCP option data
|
||||
@param Data The DHCP option data
|
||||
@param Context The context, to pass several parameters in.
|
||||
|
||||
@retval EFI_SUCCESS It always returns EFI_SUCCESS
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
Dhcp4ParseCheckOption (
|
||||
IN UINT8 Tag,
|
||||
IN UINT8 Len,
|
||||
IN UINT8 *Data,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
DHCP_PARSE_CONTEXT *Parse;
|
||||
|
||||
Parse = (DHCP_PARSE_CONTEXT *) Context;
|
||||
Parse->Index++;
|
||||
|
||||
if (Parse->Index < Parse->OptionCount) {
|
||||
//
|
||||
// Use _CR to get the memory position of EFI_DHCP4_PACKET_OPTION for
|
||||
// the EFI_DHCP4_PACKET_OPTION->Data because DhcpIterateOptions only
|
||||
// pass in the point to option data.
|
||||
//
|
||||
Parse->Option[Parse->Index - 1] = _CR (Data, EFI_DHCP4_PACKET_OPTION, Data);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Parse the DHCP options in the Packet into the PacketOptionList.
|
||||
User should allocate this array of EFI_DHCP4_PACKET_OPTION points.
|
||||
|
||||
@param This The DHCP protocol instance
|
||||
@param Packet The DHCP packet to parse
|
||||
@param OptionCount On input, the size of the PacketOptionList; On
|
||||
output, the actual number of options processed.
|
||||
@param PacketOptionList The array of EFI_DHCP4_PACKET_OPTION points
|
||||
|
||||
@retval EFI_INVALID_PARAMETER The parameters are invalid.
|
||||
@retval EFI_BUFFER_TOO_SMALL A bigger array of points is needed.
|
||||
@retval EFI_SUCCESS The options are parsed.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EfiDhcp4Parse (
|
||||
IN EFI_DHCP4_PROTOCOL *This,
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
IN OUT UINT32 *OptionCount,
|
||||
OUT EFI_DHCP4_PACKET_OPTION *PacketOptionList[] OPTIONAL
|
||||
)
|
||||
{
|
||||
DHCP_PARSE_CONTEXT Context;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// First validate the parameters
|
||||
//
|
||||
if ((This == NULL) || (Packet == NULL) || (OptionCount == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Packet->Size < Packet->Length + 2 * sizeof (UINT32)) ||
|
||||
(Packet->Dhcp4.Magik != DHCP_OPTION_MAGIC) ||
|
||||
EFI_ERROR (DhcpValidateOptions (Packet, NULL))) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((*OptionCount != 0) && (PacketOptionList == NULL)) {
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
NetZeroMem (PacketOptionList, *OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));
|
||||
|
||||
Context.Option = PacketOptionList;
|
||||
Context.OptionCount = *OptionCount;
|
||||
Context.Index = 0;
|
||||
|
||||
Status = DhcpIterateOptions (Packet, Dhcp4ParseCheckOption, &Context);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
*OptionCount = Context.Index;
|
||||
|
||||
if (Context.Index > Context.OptionCount) {
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_DHCP4_PROTOCOL mDhcp4ProtocolTemplate = {
|
||||
EfiDhcp4GetModeData,
|
||||
EfiDhcp4Configure,
|
||||
EfiDhcp4Start,
|
||||
EfiDhcp4RenewRebind,
|
||||
EfiDhcp4Release,
|
||||
EfiDhcp4Stop,
|
||||
EfiDhcp4Build,
|
||||
EfiDhcp4TransmitReceive,
|
||||
EfiDhcp4Parse
|
||||
};
|
159
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h
Normal file
159
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
Dhcp4Impl.h
|
||||
|
||||
Abstract:
|
||||
|
||||
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
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_IMPL_H__
|
||||
#define __EFI_DHCP4_IMPL_H__
|
||||
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/Dhcp4.h>
|
||||
#include <Protocol/Udp4.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"
|
||||
|
||||
enum {
|
||||
DHCP_SERVICE_SIGNATURE = EFI_SIGNATURE_32 ('D', 'H', 'C', 'P'),
|
||||
DHCP_PROTOCOL_SIGNATURE = EFI_SIGNATURE_32 ('d', 'h', 'c', 'p'),
|
||||
|
||||
//
|
||||
// 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 DESTORY if it is (partly)
|
||||
// destoried.
|
||||
//
|
||||
DHCP_UNCONFIGED = 0,
|
||||
DHCP_CONFIGED,
|
||||
DHCP_DESTORY,
|
||||
};
|
||||
|
||||
typedef struct _DHCP_PROTOCOL {
|
||||
UINT32 Signature;
|
||||
EFI_DHCP4_PROTOCOL Dhcp4Protocol;
|
||||
NET_LIST_ENTRY Link;
|
||||
EFI_HANDLE Handle;
|
||||
DHCP_SERVICE *Service;
|
||||
|
||||
BOOLEAN InDestory;
|
||||
|
||||
EFI_EVENT CompletionEvent;
|
||||
EFI_EVENT RenewRebindEvent;
|
||||
|
||||
EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token;
|
||||
};
|
||||
|
||||
//
|
||||
// DHCP driver is specical in that it is a singleton. Although it
|
||||
// has a service binding, there can be only one active child.
|
||||
//
|
||||
typedef struct _DHCP_SERVICE {
|
||||
UINT32 Signature;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
|
||||
INTN ServiceState; // CONFIGED, UNCONFIGED, and DESTORY
|
||||
BOOLEAN InDestory;
|
||||
|
||||
EFI_HANDLE Controller;
|
||||
EFI_HANDLE Image;
|
||||
|
||||
NET_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_PORT *UdpIo; // Udp child receiving all DHCP message
|
||||
UDP_IO_PORT *LeaseIoPort; // Udp child with lease IP
|
||||
NET_BUF *LastPacket; // The last sent packet for retransmission
|
||||
EFI_MAC_ADDRESS Mac;
|
||||
UINT8 HwType;
|
||||
UINT8 HwLen;
|
||||
|
||||
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
|
||||
INTN CurRetry;
|
||||
INTN MaxRetries;
|
||||
|
||||
UINT32 WaitOffer; // Time to collect the offers
|
||||
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;
|
||||
|
||||
VOID
|
||||
DhcpYieldControl (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
);
|
||||
|
||||
#endif
|
1631
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c
Normal file
1631
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c
Normal file
File diff suppressed because it is too large
Load Diff
115
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h
Normal file
115
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
Dhcp4Io.h
|
||||
|
||||
Abstract:
|
||||
|
||||
The DHCP4 protocol implementation.
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_IO_H__
|
||||
#define __EFI_DHCP4_IO_H__
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/UdpIoLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
|
||||
enum {
|
||||
DHCP_WAIT_OFFER = 3, // Time to wait the offers
|
||||
DHCP_DEFAULT_LEASE = 7 *24 *60 *60, // Seven days as default.
|
||||
DHCP_SERVER_PORT = 67,
|
||||
DHCP_CLIENT_PORT = 68,
|
||||
|
||||
//
|
||||
// BOOTP header "op" field
|
||||
//
|
||||
BOOTP_REQUEST = 1,
|
||||
BOOTP_REPLY = 2,
|
||||
|
||||
//
|
||||
// DHCP message types
|
||||
//
|
||||
DHCP_MSG_DISCOVER = 1,
|
||||
DHCP_MSG_OFFER = 2,
|
||||
DHCP_MSG_REQUEST = 3,
|
||||
DHCP_MSG_DECLINE = 4,
|
||||
DHCP_MSG_ACK = 5,
|
||||
DHCP_MSG_NAK = 6,
|
||||
DHCP_MSG_RELEASE = 7,
|
||||
DHCP_MSG_INFORM = 8,
|
||||
|
||||
//
|
||||
// DHCP notify user type
|
||||
//
|
||||
DHCP_NOTIFY_COMPLETION = 1,
|
||||
DHCP_NOTIFY_RENEWREBIND,
|
||||
DHCP_NOTIFY_ALL,
|
||||
};
|
||||
|
||||
#define DHCP_IS_BOOTP(Parameter) (((Parameter) == NULL) || ((Parameter)->DhcpType == 0))
|
||||
|
||||
#define DHCP_CONNECTED(State) \
|
||||
(((State) == Dhcp4Bound) || ((State) == (Dhcp4Renewing)) || ((State) == Dhcp4Rebinding))
|
||||
|
||||
EFI_STATUS
|
||||
DhcpSetState (
|
||||
IN DHCP_SERVICE *DhcpSb,
|
||||
IN INTN State,
|
||||
IN BOOLEAN CallUser
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
DhcpSendMessage (
|
||||
IN DHCP_SERVICE *DhcpSb,
|
||||
IN EFI_DHCP4_PACKET *Seed,
|
||||
IN DHCP_PARAMETER *Para,
|
||||
IN UINT8 Type,
|
||||
IN UINT8 *Msg
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
DhcpOnTimerTick (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
VOID
|
||||
DhcpInput (
|
||||
NET_BUF *UdpPacket,
|
||||
UDP_POINTS *Points,
|
||||
EFI_STATUS IoStatus,
|
||||
VOID *Context
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
DhcpInitRequest (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
);
|
||||
|
||||
VOID
|
||||
DhcpCleanLease (
|
||||
IN DHCP_SERVICE *DhcpSb
|
||||
);
|
||||
|
||||
#endif
|
906
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c
Normal file
906
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c
Normal file
@@ -0,0 +1,906 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
Dhcp4Option.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Function to validate, parse, process the DHCP options
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#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.
|
||||
//
|
||||
STATIC
|
||||
DHCP_OPTION_FORMAT
|
||||
DhcpOptionFormats [] = {
|
||||
{DHCP_TAG_NETMASK, DHCP_OPTION_IP, 1, 1 , TRUE},
|
||||
{DHCP_TAG_TIME_OFFSET, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP_TAG_ROUTER, DHCP_OPTION_IP, 1, -1 , TRUE},
|
||||
{DHCP_TAG_TIME_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NAME_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_DNS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_LOG_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_COOKIE_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_LPR_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_IMPRESS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_RL_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_HOSTNAME, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_BOOTFILE_LEN, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP_TAG_DUMP, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_DOMAINNAME, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_SWAP_SERVER, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP_TAG_ROOTPATH, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_EXTEND_PATH, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_IPFORWARD, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP_TAG_NONLOCAL_SRR, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP_TAG_POLICY_SRR, DHCP_OPTION_IPPAIR, 1, -1 , FALSE},
|
||||
{DHCP_TAG_EMTU, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP_TAG_TTL, DHCP_OPTION_INT8, 1, 1 , FALSE},
|
||||
{DHCP_TAG_PATHMTU_AGE, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP_TAG_PATHMTU_PLATEAU,DHCP_OPTION_INT16, 1, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_IFMTU, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP_TAG_SUBNET_LOCAL, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP_TAG_BROADCAST, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP_TAG_DISCOVER_MASK, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP_TAG_SUPPLY_MASK, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP_TAG_DISCOVER_ROUTE, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP_TAG_ROUTER_SOLICIT, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP_TAG_STATIC_ROUTE, DHCP_OPTION_IPPAIR, 1, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_TRAILER, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
{DHCP_TAG_ARPAGE, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP_TAG_ETHER_ENCAP, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
|
||||
{DHCP_TAG_TCP_TTL, DHCP_OPTION_INT8, 1, 1 , FALSE},
|
||||
{DHCP_TAG_KEEP_INTERVAL, DHCP_OPTION_INT32, 1, 1 , FALSE},
|
||||
{DHCP_TAG_KEEP_GARBAGE, DHCP_OPTION_SWITCH, 1, 1 , FALSE},
|
||||
|
||||
{DHCP_TAG_NIS_DOMAIN, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NIS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NTP_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_VENDOR, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NBNS, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NBDD, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NBTYPE, DHCP_OPTION_INT8, 1, 1 , FALSE},
|
||||
{DHCP_TAG_NBSCOPE, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_XFONT, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_XDM, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_REQUEST_IP, DHCP_OPTION_IP, 1, 1 , FALSE},
|
||||
{DHCP_TAG_LEASE, DHCP_OPTION_INT32, 1, 1 , TRUE},
|
||||
{DHCP_TAG_OVERLOAD, DHCP_OPTION_INT8, 1, 1 , TRUE},
|
||||
{DHCP_TAG_TYPE, DHCP_OPTION_INT8, 1, 1 , TRUE},
|
||||
{DHCP_TAG_SERVER_ID, DHCP_OPTION_IP, 1, 1 , TRUE},
|
||||
{DHCP_TAG_PARA_LIST, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_MESSAGE, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_MAXMSG, DHCP_OPTION_INT16, 1, 1 , FALSE},
|
||||
{DHCP_TAG_T1, DHCP_OPTION_INT32, 1, 1 , TRUE},
|
||||
{DHCP_TAG_T2, DHCP_OPTION_INT32, 1, 1 , TRUE},
|
||||
{DHCP_TAG_VENDOR_CLASS, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_CLIENT_ID, DHCP_OPTION_INT8, 2, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_NISPLUS, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NISPLUS_SERVER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_TFTP, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
{DHCP_TAG_BOOTFILE, DHCP_OPTION_INT8, 1, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_MOBILEIP, DHCP_OPTION_IP, 0, -1 , FALSE},
|
||||
{DHCP_TAG_SMTP, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_POP3, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_NNTP, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_WWW, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_FINGER, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_IRC, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_STTALK, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
{DHCP_TAG_STDA, DHCP_OPTION_IP, 1, -1 , FALSE},
|
||||
|
||||
{DHCP_TAG_CLASSLESS_ROUTE,DHCP_OPTION_INT8, 5, -1 , FALSE},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Binary search the DhcpOptionFormats array to find the format
|
||||
information about a specific option.
|
||||
|
||||
@param Tag The option's tag.
|
||||
|
||||
@return The point to the option's format, NULL if not found.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
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 Format The option's format
|
||||
@param OptValue The value of the option
|
||||
@param Len The length of the option value
|
||||
|
||||
@return TRUE is the option is valid, otherwise FALSE.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
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 Tag The DHCP option tag
|
||||
@param Len The length of the option
|
||||
@param Data The value of the DHCP option
|
||||
@param 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
|
||||
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
DhcpGetParameter (
|
||||
IN UINT8 Tag,
|
||||
IN INTN Len,
|
||||
IN UINT8 *Data,
|
||||
IN DHCP_PARAMETER *Para
|
||||
)
|
||||
{
|
||||
switch (Tag) {
|
||||
case DHCP_TAG_NETMASK:
|
||||
Para->NetMask = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP_TAG_ROUTER:
|
||||
//
|
||||
// Return the first router to consumer which is the preferred one
|
||||
//
|
||||
Para->Router = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP_TAG_LEASE:
|
||||
Para->Lease = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP_TAG_OVERLOAD:
|
||||
Para->Overload = *Data;
|
||||
|
||||
if ((Para->Overload < 1) || (Para->Overload > 3)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
|
||||
case DHCP_TAG_TYPE:
|
||||
Para->DhcpType = *Data;
|
||||
|
||||
if ((Para->DhcpType < 1) || (Para->DhcpType > 9)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
|
||||
case DHCP_TAG_SERVER_ID:
|
||||
Para->ServerId = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP_TAG_T1:
|
||||
Para->T1 = NetGetUint32 (Data);
|
||||
break;
|
||||
|
||||
case DHCP_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 DHCP_TAG_EOP.
|
||||
|
||||
@param Buffer The buffer which contains DHCP options
|
||||
@param BufLen The length of the buffer
|
||||
@param Check The callback function for each option found
|
||||
@param Context The opaque parameter for the Check
|
||||
@param Overload variable to save the value of DHCP_TAG_OVERLOAD
|
||||
option.
|
||||
|
||||
@retval EFI_SUCCESS All the options are valid
|
||||
@retval EFI_INVALID_PARAMETER The options are mal-formated.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
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 == DHCP_TAG_PAD) {
|
||||
Cur++;
|
||||
continue;
|
||||
} else if (Tag == DHCP_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 == DHCP_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 Packet The DHCP packet to check the options for
|
||||
@param Check The callback function to be called for each option
|
||||
found
|
||||
@param Context The opaque parameter for Check
|
||||
|
||||
@retval EFI_SUCCESS The DHCP packet's options are well formated
|
||||
@retval Others 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 (
|
||||
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 (
|
||||
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 Tag The current option to check
|
||||
@param Len The length of the option data
|
||||
@param Data The option data
|
||||
@param Context The context, which is a array of 256
|
||||
DHCP_OPTION_COUNT.
|
||||
|
||||
@retval EFI_SUCCESS It always returns EFI_SUCCESS.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
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 = OpCount[Tag].Offset + Len;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Call back function to DhcpiterateOptions to consolidate each option's
|
||||
data. There are maybe several occurance of the same option.
|
||||
|
||||
@param Tag The option to consolidate its data
|
||||
@param Len The length of option data
|
||||
@param Data The data of the option's current occurance
|
||||
@param 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
|
||||
|
||||
**/
|
||||
STATIC
|
||||
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;
|
||||
}
|
||||
|
||||
NetCopyMem (Buf + OptCount[Tag].Offset, Data, Len);
|
||||
|
||||
OptCount[Tag].Offset = OptCount[Tag].Offset + Len;
|
||||
Options[Index].Len = 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 continous 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 Packet The DHCP packet to parse the options
|
||||
@param Count The number of valid dhcp options present in the
|
||||
packet
|
||||
@param OptionPoint The array that contains the DHCP options. Caller
|
||||
should free it.
|
||||
|
||||
@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 = NetAllocateZeroPool (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 = TotalLen + OptCount[Index].Offset;
|
||||
OptCount[Index].Offset = 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 = NetAllocateZeroPool (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)) {
|
||||
NetFreePool (Options);
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
*OptionPoint = Options;
|
||||
|
||||
ON_EXIT:
|
||||
NetFreePool (OptCount);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Validate the packet's options. If necessary, allocate
|
||||
and fill in the interested parameters.
|
||||
|
||||
@param Packet The packet to validate the options
|
||||
@param 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;
|
||||
}
|
||||
|
||||
Updated = FALSE;
|
||||
NetZeroMem (&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)) {
|
||||
if ((*Para = NetAllocatePool (sizeof (DHCP_PARAMETER))) == NULL) {
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto ON_EXIT;
|
||||
}
|
||||
|
||||
CopyMem (*Para, &Parameter, sizeof (DHCP_PARAMETER));
|
||||
}
|
||||
|
||||
ON_EXIT:
|
||||
NetFreePool (AllOption);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Append an option to the memory, if the option is longer than
|
||||
255 bytes, splits it into several options.
|
||||
|
||||
@param Buf The buffer to append the option to
|
||||
@param Tag The option's tag
|
||||
@param DataLen The length of the option's data
|
||||
@param Data The option's data
|
||||
|
||||
@return The position to append the next option
|
||||
|
||||
**/
|
||||
UINT8 *
|
||||
DhcpAppendOption (
|
||||
IN 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 = NET_MIN (255, DataLen - Index * 255);
|
||||
|
||||
*(Buf++) = Tag;
|
||||
*(Buf++) = (UINT8) Len;
|
||||
NetCopyMem (Buf, Data + Index * 255, 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 SeedPacket The seed packet to start with
|
||||
@param DeleteCount The number of options to delete
|
||||
@param DeleteList The options to delete from the packet
|
||||
@param AppendCount The number of options to append
|
||||
@param AppendList The options to append to the packet
|
||||
@param NewPacket The new packet, allocated and built by this
|
||||
function.
|
||||
|
||||
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
|
||||
@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 = NetAllocatePool (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;
|
||||
}
|
||||
|
||||
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 *) NetAllocatePool (Len);
|
||||
|
||||
if (Packet == NULL) {
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
Packet->Size = Len;
|
||||
Packet->Length = 0;
|
||||
CopyMem (&Packet->Dhcp4.Header, &SeedPacket->Dhcp4.Header, sizeof (EFI_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++) = DHCP_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) {
|
||||
NetFreePool (SeedOptions);
|
||||
}
|
||||
|
||||
NetFreePool (Mark);
|
||||
return Status;
|
||||
}
|
266
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.h
Normal file
266
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.h
Normal file
@@ -0,0 +1,266 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
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:
|
||||
|
||||
Dhcp4Option.h
|
||||
|
||||
Abstract:
|
||||
|
||||
To validate, parse and process the DHCP options
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __EFI_DHCP4_OPTION_H__
|
||||
#define __EFI_DHCP4_OPTION_H__
|
||||
|
||||
//
|
||||
// DHCP option tags (types)
|
||||
//
|
||||
enum {
|
||||
//
|
||||
// RFC1497 vendor extensions
|
||||
//
|
||||
DHCP_TAG_PAD = 0, // Pad Option
|
||||
DHCP_TAG_EOP = 255, // End Option
|
||||
DHCP_TAG_NETMASK = 1, // Subnet Mask
|
||||
DHCP_TAG_TIME_OFFSET = 2, // Time Offset from UTC
|
||||
DHCP_TAG_ROUTER = 3, // Router option,
|
||||
DHCP_TAG_TIME_SERVER = 4, // Time Server
|
||||
DHCP_TAG_NAME_SERVER = 5, // Name Server
|
||||
DHCP_TAG_DNS_SERVER = 6, // Domain Name Server
|
||||
DHCP_TAG_LOG_SERVER = 7, // Log Server
|
||||
DHCP_TAG_COOKIE_SERVER = 8, // Cookie Server
|
||||
DHCP_TAG_LPR_SERVER = 9, // LPR Print Server
|
||||
DHCP_TAG_IMPRESS_SERVER = 10, // Impress Server
|
||||
DHCP_TAG_RL_SERVER = 11, // Resource Location Server
|
||||
DHCP_TAG_HOSTNAME = 12, // Host Name
|
||||
DHCP_TAG_BOOTFILE_LEN = 13, // Boot File Size
|
||||
DHCP_TAG_DUMP = 14, // Merit Dump File
|
||||
DHCP_TAG_DOMAINNAME = 15, // Domain Name
|
||||
DHCP_TAG_SWAP_SERVER = 16, // Swap Server
|
||||
DHCP_TAG_ROOTPATH = 17, // Root path
|
||||
DHCP_TAG_EXTEND_PATH = 18, // Extensions Path
|
||||
|
||||
//
|
||||
// IP Layer Parameters per Host
|
||||
//
|
||||
DHCP_TAG_IPFORWARD = 19, // IP Forwarding Enable/Disable
|
||||
DHCP_TAG_NONLOCAL_SRR = 20, // on-Local Source Routing Enable/Disable
|
||||
DHCP_TAG_POLICY_SRR = 21, // Policy Filter
|
||||
DHCP_TAG_EMTU = 22, // Maximum Datagram Reassembly Size
|
||||
DHCP_TAG_TTL = 23, // Default IP Time-to-live
|
||||
DHCP_TAG_PATHMTU_AGE = 24, // Path MTU Aging Timeout
|
||||
DHCP_TAG_PATHMTU_PLATEAU = 25, // Path MTU Plateau Table
|
||||
|
||||
//
|
||||
// IP Layer Parameters per Interface
|
||||
//
|
||||
DHCP_TAG_IFMTU = 26, // Interface MTU
|
||||
DHCP_TAG_SUBNET_LOCAL = 27, // All Subnets are Local
|
||||
DHCP_TAG_BROADCAST = 28, // Broadcast Address
|
||||
DHCP_TAG_DISCOVER_MASK = 29, // Perform Mask Discovery
|
||||
DHCP_TAG_SUPPLY_MASK = 30, // Mask Supplier
|
||||
DHCP_TAG_DISCOVER_ROUTE = 31, // Perform Router Discovery
|
||||
DHCP_TAG_ROUTER_SOLICIT = 32, // Router Solicitation Address
|
||||
DHCP_TAG_STATIC_ROUTE = 33, // Static Route
|
||||
|
||||
//
|
||||
// Link Layer Parameters per Interface
|
||||
//
|
||||
DHCP_TAG_TRAILER = 34, // Trailer Encapsulation
|
||||
DHCP_TAG_ARPAGE = 35, // ARP Cache Timeout
|
||||
DHCP_TAG_ETHER_ENCAP = 36, // Ethernet Encapsulation
|
||||
|
||||
//
|
||||
// TCP Parameters
|
||||
//
|
||||
DHCP_TAG_TCP_TTL = 37, // TCP Default TTL
|
||||
DHCP_TAG_KEEP_INTERVAL = 38, // TCP Keepalive Interval
|
||||
DHCP_TAG_KEEP_GARBAGE = 39, // TCP Keepalive Garbage
|
||||
|
||||
//
|
||||
// Application and Service Parameters
|
||||
//
|
||||
DHCP_TAG_NIS_DOMAIN = 40, // Network Information Service Domain
|
||||
DHCP_TAG_NIS_SERVER = 41, // Network Information Servers
|
||||
DHCP_TAG_NTP_SERVER = 42, // Network Time Protocol Servers
|
||||
DHCP_TAG_VENDOR = 43, // Vendor Specific Information
|
||||
DHCP_TAG_NBNS = 44, // NetBIOS over TCP/IP Name Server
|
||||
DHCP_TAG_NBDD = 45, // NetBIOS Datagram Distribution Server
|
||||
DHCP_TAG_NBTYPE = 46, // NetBIOS over TCP/IP Node Type
|
||||
DHCP_TAG_NBSCOPE = 47, // NetBIOS over TCP/IP Scope
|
||||
DHCP_TAG_XFONT = 48, // X Window System Font Server
|
||||
DHCP_TAG_XDM = 49, // X Window System Display Manager
|
||||
DHCP_TAG_NISPLUS = 64, // Network Information Service+ Domain
|
||||
DHCP_TAG_NISPLUS_SERVER = 65, // Network Information Service+ Servers
|
||||
DHCP_TAG_MOBILEIP = 68, // Mobile IP Home Agent
|
||||
DHCP_TAG_SMTP = 69, // Simple Mail Transport Protocol Server
|
||||
DHCP_TAG_POP3 = 70, // Post Office Protocol (POP3) Server
|
||||
DHCP_TAG_NNTP = 71, // Network News Transport Protocol Server
|
||||
DHCP_TAG_WWW = 72, // Default World Wide Web (WWW) Server
|
||||
DHCP_TAG_FINGER = 73, // Default Finger Server
|
||||
DHCP_TAG_IRC = 74, // Default Internet Relay Chat (IRC) Server
|
||||
DHCP_TAG_STTALK = 75, // StreetTalk Server
|
||||
DHCP_TAG_STDA = 76, // StreetTalk Directory Assistance Server
|
||||
DHCP_TAG_CLASSLESS_ROUTE = 121, // Classless Route
|
||||
|
||||
//
|
||||
// DHCP Extensions
|
||||
//
|
||||
DHCP_TAG_REQUEST_IP = 50, // Requested IP Address
|
||||
DHCP_TAG_LEASE = 51, // IP Address Lease Time
|
||||
DHCP_TAG_OVERLOAD = 52, // Option Overload
|
||||
DHCP_TAG_TFTP = 66, // TFTP server name
|
||||
DHCP_TAG_BOOTFILE = 67, // Bootfile name
|
||||
DHCP_TAG_TYPE = 53, // DHCP Message Type
|
||||
DHCP_TAG_SERVER_ID = 54, // Server Identifier
|
||||
DHCP_TAG_PARA_LIST = 55, // Parameter Request List
|
||||
DHCP_TAG_MESSAGE = 56, // Message
|
||||
DHCP_TAG_MAXMSG = 57, // Maximum DHCP Message Size
|
||||
DHCP_TAG_T1 = 58, // Renewal (T1) Time Value
|
||||
DHCP_TAG_T2 = 59, // Rebinding (T2) Time Value
|
||||
DHCP_TAG_VENDOR_CLASS = 60, // Vendor class identifier
|
||||
DHCP_TAG_CLIENT_ID = 61, // Client-identifier
|
||||
};
|
||||
|
||||
enum {
|
||||
DHCP_OPTION_MAGIC = 0x63538263, // Network byte order
|
||||
DHCP_MAX_OPTIONS = 256,
|
||||
|
||||
//
|
||||
// DHCP option types, this is used to validate the DHCP options.
|
||||
//
|
||||
DHCP_OPTION_SWITCH = 1,
|
||||
DHCP_OPTION_INT8,
|
||||
DHCP_OPTION_INT16,
|
||||
DHCP_OPTION_INT32,
|
||||
DHCP_OPTION_IP,
|
||||
DHCP_OPTION_IPPAIR,
|
||||
|
||||
//
|
||||
// Value of DHCP overload option
|
||||
//
|
||||
DHCP_OVERLOAD_FILENAME = 1,
|
||||
DHCP_OVERLOAD_SVRNAME = 2,
|
||||
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; // DHCP_TAG_NETMASK
|
||||
IP4_ADDR Router; // DHCP_TAG_ROUTER, only the first router is used
|
||||
|
||||
//
|
||||
// DHCP specific options
|
||||
//
|
||||
UINT8 DhcpType; // DHCP_TAG_TYPE
|
||||
UINT8 Overload; // DHCP_TAG_OVERLOAD
|
||||
IP4_ADDR ServerId; // DHCP_TAG_SERVER_ID
|
||||
UINT32 Lease; // DHCP_TAG_LEASE
|
||||
UINT32 T1; // DHCP_TAG_T1
|
||||
UINT32 T2; // DHCP_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
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
DhcpIterateOptions (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
IN DHCP_CHECK_OPTION Check, OPTIONAL
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
DhcpValidateOptions (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
OUT DHCP_PARAMETER **Para OPTIONAL
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
DhcpParseOption (
|
||||
IN EFI_DHCP4_PACKET *Packet,
|
||||
OUT INTN *Count,
|
||||
OUT DHCP_OPTION **OptionPoint
|
||||
);
|
||||
|
||||
UINT8 *
|
||||
DhcpAppendOption (
|
||||
IN UINT8 *Buf,
|
||||
IN UINT8 Tag,
|
||||
IN UINT16 DataLen,
|
||||
IN UINT8 *Data
|
||||
);
|
||||
|
||||
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
|
Reference in New Issue
Block a user