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:
vanjeff
2007-07-30 02:37:10 +00:00
parent eca7eaf49b
commit 772db4bb33
113 changed files with 42735 additions and 302 deletions

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

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

View 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

View 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

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

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

View 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

File diff suppressed because it is too large Load Diff

View 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

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

View 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