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,169 @@
/** @file
Copyright (c) 2004 - 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:
PxeDhcp4 component name protocol declarations
**/
#include "PxeDhcp4.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
PxeDhcp4ComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
PxeDhcp4ComponentNameGetControllerName (
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 gPxeDhcp4ComponentName = {
PxeDhcp4ComponentNameGetDriverName,
PxeDhcp4ComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mPxeDhcp4DriverNameTable[] = {
{
"eng",
L"PXE DHCPv4 Driver"
},
{
NULL,
NULL
}
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4ComponentNameGetDriverName (
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_SUCCESS - 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,
gPxeDhcp4ComponentName.SupportedLanguages,
mPxeDhcp4DriverNameTable,
DriverName
);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4ComponentNameGetControllerName (
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 is not NULL and it is not 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;
}
/* EOF - ComponentName.c */

View File

@@ -0,0 +1,355 @@
/** @file
Copyright (c) 2004 - 2005, 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:
PxeDhcp4.c
Abstract:
**/
#include "PxeDhcp4.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// Prototypes
// Driver model protocol interface
//
EFI_STATUS
EFIAPI
PxeDhcp4DriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
EFIAPI
PxeDhcp4DriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PxeDhcp4DriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
EFIAPI
PxeDhcp4DriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// PXE DHCP Protocol Interface
//
EFI_DRIVER_BINDING_PROTOCOL gPxeDhcp4DriverBinding = {
PxeDhcp4DriverBindingSupported,
PxeDhcp4DriverBindingStart,
PxeDhcp4DriverBindingStop,
0xa,
NULL,
NULL
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// PxeDhcp4 Driver Entry point funtion
//
/**
Register Driver Binding protocol for this driver.
@param entry EFI_IMAGE_ENTRY_POINT)
@retval EFI_SUCCESS Driver loaded.
@retval other Driver not loaded.
**/
EFI_STATUS
EFIAPI
PxeDhcp4DriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EfiLibInstallAllDriverProtocols (
ImageHandle,
SystemTable,
&gPxeDhcp4DriverBinding,
NULL,
COMPONENT_NAME,
NULL,
NULL
);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
Test to see if this driver supports ControllerHandle. Any
ControllerHandle that contains a PxeBaseCode protocol can be
supported.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to test.
@param RemainingDevicePath Not used.
@retval EFI_SUCCESS This driver supports this device.
@retval EFI_ALREADY_STARTED This driver is already running on this device.
@retval other This driver does not support this device.
**/
EFI_STATUS
EFIAPI
PxeDhcp4DriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL * This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Status;
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
//
// Open the IO Abstraction(s) needed to perform the supported test.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid,
(VOID **) &PxeBc,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the I/O Abstraction(s) used to perform the supported test.
//
return gBS->CloseProtocol (
ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
Start this driver on ControllerHandle by opening a PxeBaseCode
protocol and installing a PxeDhcp4 protocol on ControllerHandle.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to bind driver to.
@param RemainingDevicePath Not used, always produce all possible children.
@retval EFI_SUCCESS This driver is added to ControllerHandle.
@retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
@retval other This driver does not support this device.
**/
EFI_STATUS
EFIAPI
PxeDhcp4DriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL * This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
)
{
EFI_STATUS Status;
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
PXE_DHCP4_PRIVATE_DATA *Private;
//
// Connect to the PxeBaseCode interface on ControllerHandle.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid,
(VOID **) &PxeBc,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// BaseCode has already grabbed the SimpleNetwork interface
// so just do a HandleProtocol() to get it.
//
Status = gBS->HandleProtocol (
ControllerHandle,
&gEfiSimpleNetworkProtocolGuid,
(VOID **) &Snp
);
if (EFI_ERROR (Status)) {
goto error_exit;
}
ASSERT (Snp);
//
// Initialize the PXE DHCP device instance.
//
Private = AllocateZeroPool (sizeof (PXE_DHCP4_PRIVATE_DATA));
if (Private == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto error_exit;
}
Private->Signature = PXE_DHCP4_PRIVATE_DATA_SIGNATURE;
Private->PxeBc = PxeBc;
Private->Snp = Snp;
Private->Handle = ControllerHandle;
Private->PxeDhcp4.Revision = EFI_PXE_DHCP4_PROTOCOL_REVISION;
Private->PxeDhcp4.Run = PxeDhcp4Run;
Private->PxeDhcp4.Setup = PxeDhcp4Setup;
Private->PxeDhcp4.Init = PxeDhcp4Init;
Private->PxeDhcp4.Select = PxeDhcp4Select;
Private->PxeDhcp4.Renew = PxeDhcp4Renew;
Private->PxeDhcp4.Rebind = PxeDhcp4Rebind;
Private->PxeDhcp4.Release = PxeDhcp4Release;
Private->PxeDhcp4.Data = NULL;
//
// Install protocol interfaces for the PXE DHCP device.
//
Status = gBS->InstallProtocolInterface (
&ControllerHandle,
&gEfiPxeDhcp4ProtocolGuid,
EFI_NATIVE_INTERFACE,
&Private->PxeDhcp4
);
if (!EFI_ERROR (Status)) {
return Status;
}
error_exit: ;
gBS->CloseProtocol (
ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
return Status;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
Stop this driver on ControllerHandle by removing PXE DHCP
protocol and closing the PXE Base Code protocol on
ControllerHandle.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to stop driver on.
@param NumberOfChildren Not used.
@param ChildHandleBuffer Not used.
@retval EFI_SUCCESS This driver is removed ControllerHandle.
@retval other This driver was not removed from this device.
**/
EFI_STATUS
EFIAPI
PxeDhcp4DriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
EFI_PXE_DHCP4_PROTOCOL *PxeDhcp4;
PXE_DHCP4_PRIVATE_DATA *Private;
//
// Get our context back.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiPxeDhcp4ProtocolGuid,
(VOID **) &PxeDhcp4,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (PxeDhcp4);
//
// Release allocated resources
//
if (Private->PxeDhcp4.Data) {
FreePool (Private->PxeDhcp4.Data);
Private->PxeDhcp4.Data = NULL;
}
//
// Uninstall our protocol
//
Status = gBS->UninstallProtocolInterface (
ControllerHandle,
&gEfiPxeDhcp4ProtocolGuid,
&Private->PxeDhcp4
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close any consumed protocols
//
Status = gBS->CloseProtocol (
ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid,
This->DriverBindingHandle,
ControllerHandle
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Release our private data
//
FreePool (Private);
return Status;
}
/* EOF - PxeDhcp4.c */

View File

@@ -0,0 +1,353 @@
/** @file
Copyright (c) 2004 - 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:
PxeDhcp4.h
Abstract:
Common header for PxeDhcp4 protocol driver
**/
#ifndef _PXEDHCP4_H
#define _PXEDHCP4_H
#include <PiDxe.h>
#include <Protocol/PxeBaseCode.h>
#include <Protocol/SimpleNetwork.h>
#include <Protocol/PxeDhcp4.h>
#include <Protocol/PxeDhcp4Callback.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// PxeDhcp4 protocol instance data
//
typedef struct {
//
// Signature field used to locate beginning of containment record.
//
UINTN Signature;
#define PXE_DHCP4_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('p', 'x', 'D', '4')
//
// Device handle the protocol is bound to.
//
EFI_HANDLE Handle;
//
// Public PxeDhcp4 protocol interface.
//
EFI_PXE_DHCP4_PROTOCOL PxeDhcp4;
//
// Consumed PxeBc, Snp and PxeDhcp4Callback protocol interfaces.
//
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
EFI_PXE_DHCP4_CALLBACK_PROTOCOL *callback;
//
// PxeDhcp4 called function for PxeDhcp4Callback.
//
EFI_PXE_DHCP4_FUNCTION function;
//
// Timeout event and flag for PxeDhcp4Callback.
//
EFI_EVENT TimeoutEvent;
BOOLEAN TimeoutOccurred;
//
// Periodic event and flag for PxeDhcp4Callback.
//
EFI_EVENT PeriodicEvent;
BOOLEAN PeriodicOccurred;
//
// DHCP server IP address.
//
UINT32 ServerIp;
//
// DHCP renewal and rebinding times, in seconds.
//
UINT32 RenewTime;
UINT32 RebindTime;
UINT32 LeaseTime;
//
// Number of offers received & allocated offer list.
//
UINTN offers;
DHCP4_PACKET *offer_list;
//
//
//
BOOLEAN StopPxeBc;
} PXE_DHCP4_PRIVATE_DATA;
#define PXE_DHCP4_PRIVATE_DATA_FROM_THIS(a) CR (a, PXE_DHCP4_PRIVATE_DATA, PxeDhcp4, PXE_DHCP4_PRIVATE_DATA_SIGNATURE)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// Protocol function prototypes.
//
extern
EFI_STATUS
EFIAPI
PxeDhcp4Run (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN OPTIONAL UINTN OpLen,
IN OPTIONAL VOID *OpList
)
;
extern
EFI_STATUS
EFIAPI
PxeDhcp4Setup (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN EFI_PXE_DHCP4_DATA *Data
)
;
extern
EFI_STATUS
EFIAPI
PxeDhcp4Init (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN UINTN seconds_timeout,
OUT UINTN *offer_list_entries,
OUT DHCP4_PACKET **offer_list
)
;
extern
EFI_STATUS
EFIAPI
PxeDhcp4Select (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN UINTN seconds_timeout,
IN DHCP4_PACKET *offer_list
)
;
extern
EFI_STATUS
EFIAPI
PxeDhcp4Renew (
IN EFI_PXE_DHCP4_PROTOCOL *This,
UINTN seconds_timeout
)
;
extern
EFI_STATUS
EFIAPI
PxeDhcp4Rebind (
IN EFI_PXE_DHCP4_PROTOCOL *This,
UINTN seconds_timeout
)
;
extern
EFI_STATUS
EFIAPI
PxeDhcp4Release (
IN EFI_PXE_DHCP4_PROTOCOL *This
)
;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// Support function prototypes.
//
extern
UINT16
htons (
UINTN n
)
;
extern
UINT32
htonl (
UINTN n
)
;
extern
VOID
EFIAPI
timeout_notify (
IN EFI_EVENT Event,
IN VOID *Context
)
;
extern
VOID
EFIAPI
periodic_notify (
IN EFI_EVENT Event,
IN VOID *Context
)
;
extern
EFI_STATUS
find_opt (
IN DHCP4_PACKET *Packet,
IN UINT8 OpCode,
IN UINTN Skip,
OUT DHCP4_OP **OpPtr
)
;
extern
EFI_STATUS
add_opt (
IN DHCP4_PACKET *Packet,
IN DHCP4_OP *OpPtr
)
;
extern
EFI_STATUS
start_udp (
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN OPTIONAL EFI_IP_ADDRESS *station_ip,
IN OPTIONAL EFI_IP_ADDRESS *subnet_mask
)
;
extern
VOID
stop_udp (
IN PXE_DHCP4_PRIVATE_DATA *Private
)
;
extern
EFI_STATUS
start_receive_events (
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN UINTN seconds_timeout
)
;
extern
VOID
stop_receive_events (
IN PXE_DHCP4_PRIVATE_DATA *Private
)
;
extern
EFI_STATUS
tx_udp (
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN EFI_IP_ADDRESS *dest_ip,
IN OPTIONAL EFI_IP_ADDRESS *gateway_ip,
IN EFI_IP_ADDRESS *src_ip,
IN VOID *buffer,
IN UINTN BufferSize
)
;
extern
EFI_STATUS
rx_udp (
IN PXE_DHCP4_PRIVATE_DATA *Private,
OUT VOID *buffer,
OUT UINTN *BufferSize,
IN OUT EFI_IP_ADDRESS *dest_ip,
IN OUT EFI_IP_ADDRESS *src_ip,
IN UINT16 op_flags
)
;
extern
EFI_STATUS
tx_rx_udp (
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN OUT EFI_IP_ADDRESS *ServerIp,
IN OPTIONAL EFI_IP_ADDRESS *gateway_ip,
IN OPTIONAL EFI_IP_ADDRESS *client_ip,
IN OPTIONAL EFI_IP_ADDRESS *subnet_mask,
IN DHCP4_PACKET *tx_pkt,
OUT DHCP4_PACKET *rx_pkt,
IN INTN
(
*rx_vfy)
(
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN DHCP4_PACKET *tx_pkt,
IN DHCP4_PACKET *rx_pkt,
IN UINTN rx_pkt_size
),
IN UINTN seconds_timeout
)
;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// Global variable definitions.
//
extern EFI_COMPONENT_NAME_PROTOCOL gPxeDhcp4ComponentName;
EFI_STATUS
EFIAPI
PxeDhcp4DriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Register Driver Binding protocol for this driver.
Arguments:
(Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
Returns:
EFI_SUCCESS - Driver loaded.
other - Driver not loaded.
--*/
;
#ifdef EFI_SIZE_REDUCTION_APPLIED
#define COMPONENT_NAME_CODE(code)
#define COMPONENT_NAME NULL
#else
#define COMPONENT_NAME_CODE(code) code
#define COMPONENT_NAME &gPxeDhcp4ComponentName
#endif
#endif /* _PXEDHCP4_H */
/* EOF - PxeDhcp4.h */

View File

@@ -0,0 +1,64 @@
#/** @file
# Component name for module PxeDhcp4
#
# 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 = PxeDhcp4Dxe
FILE_GUID = a46c3330-be36-4977-9d24-a7cf92eef0fe
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
EDK_RELEASE_VERSION = 0x00020000
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = PxeDhcp4DriverEntryPoint
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
support.c
PxeDhcp4Release.c
PxeDhcp4Setup.c
ComponentName.c
PxeDhcp4RenewRebind.c
PxeDhcp4.h
PxeDhcp4.c
PxeDhcp4InitSelect.c
PxeDhcp4Run.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
DebugLib
[Protocols]
gEfiPxeBaseCodeProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiPxeDhcp4CallbackProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiPxeDhcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED

View File

@@ -0,0 +1,78 @@
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MsaHeader>
<ModuleName>PxeDhcp4</ModuleName>
<ModuleType>DXE_DRIVER</ModuleType>
<GuidValue>a46c3330-be36-4977-9d24-a7cf92eef0fe</GuidValue>
<Version>1.0</Version>
<Abstract>Component name for module PxeDhcp4</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>PxeDhcp4</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</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>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>PxeDhcp4Run.c</Filename>
<Filename>PxeDhcp4InitSelect.c</Filename>
<Filename>PxeDhcp4Entry.c</Filename>
<Filename>PxeDhcp4.c</Filename>
<Filename>PxeDhcp4.h</Filename>
<Filename>PxeDhcp4RenewRebind.c</Filename>
<Filename>ComponentName.c</Filename>
<Filename>PxeDhcp4Setup.c</Filename>
<Filename>PxeDhcp4Release.c</Filename>
<Filename>support.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>gEfiPxeDhcp4ProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiPxeDhcp4CallbackProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiSimpleNetworkProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiPxeBaseCodeProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<ModuleEntryPoint>PxeDhcp4DriverEntryPoint</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,784 @@
/** @file
Copyright (c) 2004, 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:
PxeDhcp4InitSelect.c
Abstract:
**/
#include "PxeDhcp4.h"
#define DebugPrint(x)
//
// #define DebugPrint(x) Aprint x
//
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
**/
STATIC
INTN
offer_verify (
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN DHCP4_PACKET *tx_pkt,
IN DHCP4_PACKET *rx_pkt,
IN UINTN rx_pkt_size
)
{
EFI_STATUS EfiStatus;
DHCP4_PACKET *tmp;
DHCP4_OP *msg_type_op;
DHCP4_OP *srvid_op;
UINT32 magik;
//
// Verify parameters. Touch unused parameters to keep
// compiler happy.
//
ASSERT (Private);
ASSERT (rx_pkt);
if (Private == NULL || rx_pkt == NULL) {
return -2;
}
tx_pkt = tx_pkt;
rx_pkt_size = rx_pkt_size;
//
// This may be a BOOTP Reply or DHCP Offer packet.
// If there is no DHCP magik number, assume that
// this is a BOOTP Reply packet.
//
magik = htonl (DHCP4_MAGIK_NUMBER);
while (!CompareMem (&rx_pkt->dhcp4.magik, &magik, 4)) {
//
// If there is no DHCP message type option, assume
// this is a BOOTP reply packet and cache it.
//
EfiStatus = find_opt (rx_pkt, DHCP4_MESSAGE_TYPE, 0, &msg_type_op);
if (EFI_ERROR (EfiStatus)) {
break;
}
//
// If there is a DHCP message type option, it must be a
// DHCP offer packet
//
if (msg_type_op->len != 1) {
return -1;
}
if (msg_type_op->data[0] != DHCP4_MESSAGE_TYPE_OFFER) {
return -1;
}
//
// There must be a server identifier option.
//
EfiStatus = find_opt (
rx_pkt,
DHCP4_SERVER_IDENTIFIER,
0,
&srvid_op
);
if (EFI_ERROR (EfiStatus)) {
return -1;
}
if (srvid_op->len != 4) {
return -1;
}
//
// Good DHCP offer packet.
//
break;
}
//
// Good DHCP (or BOOTP) packet. Cache it!
//
EfiStatus = gBS->AllocatePool (
EfiBootServicesData,
(Private->offers + 1) * sizeof (DHCP4_PACKET),
(VOID **) &tmp
);
if (EFI_ERROR (EfiStatus)) {
return -2;
}
ASSERT (tmp);
if (Private->offers != 0) {
CopyMem (
tmp,
Private->offer_list,
Private->offers * sizeof (DHCP4_PACKET)
);
gBS->FreePool (Private->offer_list);
}
CopyMem (&tmp[Private->offers++], rx_pkt, sizeof (DHCP4_PACKET));
Private->offer_list = tmp;
return 0;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
**/
STATIC
INTN
acknak_verify (
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN DHCP4_PACKET *tx_pkt,
IN DHCP4_PACKET *rx_pkt,
IN UINTN rx_pkt_size
)
{
EFI_STATUS EfiStatus;
DHCP4_OP *msg_type_op;
DHCP4_OP *srvid_op;
DHCP4_OP *renew_op;
DHCP4_OP *rebind_op;
DHCP4_OP *lease_time_op;
UINT32 magik;
//
// Verify parameters. Touch unused parameters to
// keep compiler happy.
//
ASSERT (Private);
ASSERT (rx_pkt);
if (Private == NULL || rx_pkt == NULL) {
return -2;
}
tx_pkt = tx_pkt;
rx_pkt_size = rx_pkt_size;
//
// This must be a DHCP Ack message.
//
magik = htonl (DHCP4_MAGIK_NUMBER);
if (CompareMem (&rx_pkt->dhcp4.magik, &magik, 4)) {
return -1;
}
EfiStatus = find_opt (rx_pkt, DHCP4_MESSAGE_TYPE, 0, &msg_type_op);
if (EFI_ERROR (EfiStatus)) {
return -1;
}
if (msg_type_op->len != 1) {
return -1;
}
if (msg_type_op->data[0] != DHCP4_MESSAGE_TYPE_ACK) {
return -1;
}
//
// There must be a server identifier.
//
EfiStatus = find_opt (rx_pkt, DHCP4_SERVER_IDENTIFIER, 0, &srvid_op);
if (EFI_ERROR (EfiStatus)) {
return -1;
}
if (srvid_op->len != 4) {
return -1;
}
//
// There should be a renewal time.
// If there is not, we will default to the 7/8 of the rebinding time.
//
EfiStatus = find_opt (rx_pkt, DHCP4_RENEWAL_TIME, 0, &renew_op);
if (EFI_ERROR (EfiStatus)) {
renew_op = NULL;
} else if (renew_op->len != 4) {
renew_op = NULL;
}
//
// There should be a rebinding time.
// If there is not, we will default to 7/8 of the lease time.
//
EfiStatus = find_opt (rx_pkt, DHCP4_REBINDING_TIME, 0, &rebind_op);
if (EFI_ERROR (EfiStatus)) {
rebind_op = NULL;
} else if (rebind_op->len != 4) {
rebind_op = NULL;
}
//
// There should be a lease time.
// If there is not, we will default to one week.
//
EfiStatus = find_opt (rx_pkt, DHCP4_LEASE_TIME, 0, &lease_time_op);
if (EFI_ERROR (EfiStatus)) {
lease_time_op = NULL;
} else if (lease_time_op->len != 4) {
lease_time_op = NULL;
}
//
// Packet looks good. Double check the renew, rebind and lease times.
//
CopyMem (&Private->ServerIp, srvid_op->data, 4);
if (renew_op != NULL) {
CopyMem (&Private->RenewTime, renew_op->data, 4);
Private->RenewTime = htonl (Private->RenewTime);
} else {
Private->RenewTime = 0;
}
if (rebind_op != NULL) {
CopyMem (&Private->RebindTime, rebind_op->data, 4);
Private->RebindTime = htonl (Private->RebindTime);
} else {
Private->RebindTime = 0;
}
if (lease_time_op != NULL) {
CopyMem (&Private->LeaseTime, lease_time_op->data, 4);
Private->LeaseTime = htonl (Private->LeaseTime);
} else {
Private->LeaseTime = 0;
}
if (Private->LeaseTime < 60) {
Private->LeaseTime = 7 * 86400;
}
if (Private->RebindTime < 52 || Private->RebindTime >= Private->LeaseTime) {
Private->RebindTime = Private->LeaseTime / 2 + Private->LeaseTime / 4 + Private->LeaseTime / 8;
}
if (Private->RenewTime < 45 || Private->RenewTime >= Private->RebindTime) {
Private->RenewTime = Private->RebindTime / 2 + Private->RebindTime / 4 + Private->RebindTime / 8;
}
return 1;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4Init (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN UINTN seconds_timeout,
OUT UINTN *Offers,
OUT DHCP4_PACKET **OfferList
)
{
PXE_DHCP4_PRIVATE_DATA *Private;
DHCP4_PACKET offer;
EFI_IP_ADDRESS bcast_ip;
EFI_STATUS EfiStatus;
//
// Verify parameters and protocol state.
//
if (This == NULL ||
seconds_timeout < DHCP4_MIN_SECONDS ||
seconds_timeout > DHCP4_MAX_SECONDS ||
Offers == NULL ||
OfferList == NULL
) {
//
// Return parameters are not initialized when
// parameters are invalid!
//
return EFI_INVALID_PARAMETER;
}
*Offers = 0;
*OfferList = NULL;
//
// Check protocol state.
//
if (This->Data == NULL) {
return EFI_NOT_STARTED;
}
if (!This->Data->SetupCompleted) {
return EFI_NOT_READY;
}
#if 0
if (!is_good_discover (&This->Data->Discover)) {
//
// %%TBD - check discover packet fields
//
}
#endif
//
// Get pointer to our instance data.
//
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Private->PxeBc == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Setup variables...
//
Private->offers = 0;
Private->offer_list = NULL;
EfiStatus = gBS->HandleProtocol (
Private->Handle,
&gEfiPxeDhcp4CallbackProtocolGuid,
(VOID *) &Private->callback
);
if (EFI_ERROR (EfiStatus)) {
Private->callback = NULL;
}
Private->function = EFI_PXE_DHCP4_FUNCTION_INIT;
//
// Increment the transaction ID.
//
{
UINT32 xid;
CopyMem (&xid, &This->Data->Discover.dhcp4.xid, sizeof (UINT32));
xid = htonl (htonl (xid) + 1);
CopyMem (&This->Data->Discover.dhcp4.xid, &xid, sizeof (UINT32));
}
//
// Transmit discover and wait for offers...
//
SetMem (&bcast_ip, sizeof (EFI_IP_ADDRESS), 0xFF);
EfiStatus = tx_rx_udp (
Private,
&bcast_ip,
NULL,
NULL,
NULL,
&This->Data->Discover,
&offer,
&offer_verify,
seconds_timeout
);
if (EFI_ERROR (EfiStatus)) {
if (Private->offer_list) {
gBS->FreePool (Private->offer_list);
}
Private->offers = 0;
Private->offer_list = NULL;
Private->callback = NULL;
DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));
return EfiStatus;
}
*Offers = Private->offers;
*OfferList = Private->offer_list;
Private->offers = 0;
Private->offer_list = NULL;
Private->callback = NULL;
This->Data->InitCompleted = TRUE;
This->Data->SelectCompleted = FALSE;
This->Data->IsBootp = FALSE;
This->Data->IsAck = FALSE;
return EFI_SUCCESS;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4Select (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN UINTN seconds_timeout,
IN DHCP4_PACKET *Offer
)
{
PXE_DHCP4_PRIVATE_DATA *Private;
EFI_STATUS EfiStatus;
DHCP4_PACKET request;
DHCP4_PACKET acknak;
EFI_IP_ADDRESS bcast_ip;
EFI_IP_ADDRESS zero_ip;
EFI_IP_ADDRESS local_ip;
DHCP4_OP *srvid;
DHCP4_OP *op;
UINT32 dhcp4_magik;
UINT8 buf[16];
BOOLEAN is_bootp;
//
// Verify parameters.
//
if (This == NULL || seconds_timeout < DHCP4_MIN_SECONDS || seconds_timeout > DHCP4_MAX_SECONDS || Offer == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Check protocol state.
//
if (This->Data == NULL) {
return EFI_NOT_STARTED;
}
if (!This->Data->SetupCompleted) {
return EFI_NOT_READY;
}
//
// Get pointer to instance data.
//
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Private->PxeBc == NULL) {
return EFI_DEVICE_ERROR;
}
#if 0
if (!is_good_discover (&This->Data->Discover)) {
//
// %%TBD - check discover packet fields
//
}
#endif
//
// Setup useful variables...
//
SetMem (&bcast_ip, sizeof (EFI_IP_ADDRESS), 0xFF);
ZeroMem (&zero_ip, sizeof (EFI_IP_ADDRESS));
ZeroMem (&local_ip, sizeof (EFI_IP_ADDRESS));
local_ip.v4.Addr[0] = 127;
local_ip.v4.Addr[3] = 1;
This->Data->SelectCompleted = FALSE;
This->Data->IsBootp = FALSE;
This->Data->IsAck = FALSE;
EfiStatus = gBS->HandleProtocol (
Private->Handle,
&gEfiPxeDhcp4CallbackProtocolGuid,
(VOID *) &Private->callback
);
if (EFI_ERROR (EfiStatus)) {
Private->callback = NULL;
}
Private->function = EFI_PXE_DHCP4_FUNCTION_SELECT;
//
// Verify offer packet fields.
//
if (Offer->dhcp4.op != BOOTP_REPLY) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (Offer->dhcp4.htype != This->Data->Discover.dhcp4.htype) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (Offer->dhcp4.hlen != This->Data->Discover.dhcp4.hlen) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (CompareMem (&Offer->dhcp4.xid, &This->Data->Discover.dhcp4.xid, 4)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (!CompareMem (&Offer->dhcp4.yiaddr, &bcast_ip, 4)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (!CompareMem (&Offer->dhcp4.yiaddr, &zero_ip, 4)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (!CompareMem (&Offer->dhcp4.yiaddr, &local_ip, 4)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (CompareMem (
&Offer->dhcp4.chaddr,
&This->Data->Discover.dhcp4.chaddr,
16
)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
//
// DHCP option checks
//
dhcp4_magik = htonl (DHCP4_MAGIK_NUMBER);
is_bootp = TRUE;
if (!CompareMem (&Offer->dhcp4.magik, &dhcp4_magik, 4)) {
//
// If present, DHCP message type must be offer.
//
EfiStatus = find_opt (Offer, DHCP4_MESSAGE_TYPE, 0, &op);
if (!EFI_ERROR (EfiStatus)) {
if (op->len != 1 || op->data[0] != DHCP4_MESSAGE_TYPE_OFFER) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
is_bootp = FALSE;
}
//
// If present, DHCP max message size must be valid.
//
EfiStatus = find_opt (Offer, DHCP4_MAX_MESSAGE_SIZE, 0, &op);
if (!EFI_ERROR (EfiStatus)) {
if (op->len != 2 || ((op->data[0] << 8) | op->data[1]) < DHCP4_DEFAULT_MAX_MESSAGE_SIZE) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
}
//
// If present, DHCP server identifier must be valid.
//
EfiStatus = find_opt (Offer, DHCP4_SERVER_IDENTIFIER, 0, &op);
if (!EFI_ERROR (EfiStatus)) {
if (op->len != 4 || !CompareMem (op->data, &bcast_ip, 4) || !CompareMem (op->data, &zero_ip, 4)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
}
//
// If present, DHCP subnet mask must be valid.
//
EfiStatus = find_opt (
Offer,
DHCP4_SUBNET_MASK,
0,
&op
);
if (!EFI_ERROR (EfiStatus)) {
if (op->len != 4) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
}
}
//
// Early out for BOOTP.
//
This->Data->IsBootp = is_bootp;
if (is_bootp) {
//
// Copy offer packet to instance data.
//
CopyMem (&This->Data->Offer, Offer, sizeof (DHCP4_PACKET));
//
// Copy discover to request and offer to acknak.
//
CopyMem (
&This->Data->Request,
&This->Data->Discover,
sizeof (DHCP4_PACKET)
);
CopyMem (
&This->Data->AckNak,
&This->Data->Offer,
sizeof (DHCP4_PACKET)
);
//
// Set state flags.
//
This->Data->SelectCompleted = TRUE;
This->Data->IsAck = TRUE;
Private->callback = NULL;
return EFI_SUCCESS;
}
//
// Copy discover packet contents to request packet.
//
CopyMem (&request, &This->Data->Discover, sizeof (DHCP4_PACKET));
This->Data->IsAck = FALSE;
//
// Change DHCP message type from discover to request.
//
EfiStatus = find_opt (&request, DHCP4_MESSAGE_TYPE, 0, &op);
if (EFI_ERROR (EfiStatus) && EfiStatus != EFI_NOT_FOUND) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (EfiStatus == EFI_NOT_FOUND) {
EfiStatus = find_opt (&request, DHCP4_END, 0, &op);
if (EFI_ERROR (EfiStatus)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
op->op = DHCP4_MESSAGE_TYPE;
op->len = 1;
op->data[1] = DHCP4_END;
}
op->data[0] = DHCP4_MESSAGE_TYPE_REQUEST;
//
// Copy server identifier option from offer to request.
//
EfiStatus = find_opt (Offer, DHCP4_SERVER_IDENTIFIER, 0, &srvid);
if (EFI_ERROR (EfiStatus)) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
if (srvid->len != 4) {
Private->callback = NULL;
return EFI_INVALID_PARAMETER;
}
EfiStatus = add_opt (&request, srvid);
if (EFI_ERROR (EfiStatus)) {
DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));
Private->callback = NULL;
return EfiStatus;
}
//
// Add requested IP address option to request packet.
//
op = (DHCP4_OP *) buf;
op->op = DHCP4_REQUESTED_IP_ADDRESS;
op->len = 4;
CopyMem (op->data, &Offer->dhcp4.yiaddr, 4);
EfiStatus = add_opt (&request, op);
if (EFI_ERROR (EfiStatus)) {
DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));
Private->callback = NULL;
return EfiStatus;
}
//
// Transimit DHCP request and wait for DHCP ack...
//
SetMem (&bcast_ip, sizeof (EFI_IP_ADDRESS), 0xFF);
EfiStatus = tx_rx_udp (
Private,
&bcast_ip,
NULL,
NULL,
NULL,
&request,
&acknak,
&acknak_verify,
seconds_timeout
);
if (EFI_ERROR (EfiStatus)) {
DebugPrint (("%a:%d:%r\n", __FILE__, __LINE__, EfiStatus));
Private->callback = NULL;
return EfiStatus;
}
//
// Set Data->IsAck and return.
//
EfiStatus = find_opt (&acknak, DHCP4_MESSAGE_TYPE, 0, &op);
if (EFI_ERROR (EfiStatus)) {
Private->callback = NULL;
return EFI_DEVICE_ERROR;
}
if (op->len != 1) {
Private->callback = NULL;
return EFI_DEVICE_ERROR;
}
switch (op->data[0]) {
case DHCP4_MESSAGE_TYPE_ACK:
This->Data->IsAck = TRUE;
break;
case DHCP4_MESSAGE_TYPE_NAK:
This->Data->IsAck = FALSE;
break;
default:
Private->callback = NULL;
return EFI_DEVICE_ERROR;
}
//
// Copy packets into instance data...
//
CopyMem (&This->Data->Offer, Offer, sizeof (DHCP4_PACKET));
CopyMem (&This->Data->Request, &request, sizeof (DHCP4_PACKET));
CopyMem (&This->Data->AckNak, &acknak, sizeof (DHCP4_PACKET));
This->Data->SelectCompleted = TRUE;
Private->callback = NULL;
return EFI_SUCCESS;
}
/* eof - PxeDhcp4InitSelect.c */

View File

@@ -0,0 +1,247 @@
/** @file
Copyright (c) 2004, 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:
PxeDhcp4Release.c
Abstract:
Transmit release packet, free allocations and shutdown PxeDhcp4.
**/
#include "PxeDhcp4.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4Release (
IN EFI_PXE_DHCP4_PROTOCOL *This
)
{
PXE_DHCP4_PRIVATE_DATA *Private;
EFI_IP_ADDRESS ServerIp;
EFI_IP_ADDRESS client_ip;
EFI_IP_ADDRESS gateway_ip;
EFI_IP_ADDRESS subnet_mask;
EFI_STATUS efi_status;
DHCP4_OP *op;
UINT8 op_list[20];
//
// Check for invalid parameters.
//
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Release does nothing if the protocol has never been setup.
//
if (This->Data == NULL) {
return EFI_NOT_STARTED;
}
//
// Fail if we do not have valid instance data.
//
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Private->PxeBc == NULL) {
return EFI_DEVICE_ERROR;
}
//
// If this is a BOOTP session and there is not a DHCP Ack
// packet, just release storage and return.
//
if (This->Data->IsBootp || !This->Data->IsAck) {
gBS->FreePool (This->Data);
This->Data = NULL;
if (Private->StopPxeBc) {
Private->PxeBc->Stop (Private->PxeBc);
}
return EFI_SUCCESS;
}
//
// Build option list for DHCP Release packet.
// If any errors occur, just release storage and return.
//
//
// Message type is first.
//
op_list[0] = DHCP4_MESSAGE_TYPE;
op_list[1] = 1;
op_list[2] = DHCP4_MESSAGE_TYPE_RELEASE;
//
// Followed by server identifier.
//
efi_status = find_opt (
&This->Data->Request,
DHCP4_SERVER_IDENTIFIER,
0,
&op
);
if (EFI_ERROR (efi_status)) {
gBS->FreePool (This->Data);
This->Data = NULL;
if (Private->StopPxeBc) {
Private->PxeBc->Stop (Private->PxeBc);
}
return EFI_SUCCESS;
}
if (op->len != 4) {
gBS->FreePool (This->Data);
This->Data = NULL;
if (Private->StopPxeBc) {
Private->PxeBc->Stop (Private->PxeBc);
}
return EFI_SUCCESS;
}
CopyMem (&ServerIp, op->data, 4);
op_list[3] = DHCP4_SERVER_IDENTIFIER;
op_list[4] = 4;
CopyMem (&op_list[5], &ServerIp, 4);
//
// Followed by end.
//
op_list[9] = DHCP4_END;
//
// We need a subnet mask for IP stack operation.
//
efi_status = find_opt (
&This->Data->AckNak,
DHCP4_SUBNET_MASK,
0,
&op
);
if (EFI_ERROR (efi_status)) {
gBS->FreePool (This->Data);
This->Data = NULL;
if (Private->StopPxeBc) {
Private->PxeBc->Stop (Private->PxeBc);
}
return EFI_SUCCESS;
}
if (op->len != 4) {
gBS->FreePool (This->Data);
This->Data = NULL;
if (Private->StopPxeBc) {
Private->PxeBc->Stop (Private->PxeBc);
}
return EFI_SUCCESS;
}
ZeroMem (&subnet_mask, sizeof (EFI_IP_ADDRESS));
CopyMem (&subnet_mask, op->data, 4);
//
// Gateway IP address may be needed.
//
ZeroMem (&gateway_ip, sizeof (EFI_IP_ADDRESS));
CopyMem (&gateway_ip, &This->Data->AckNak.dhcp4.giaddr, 4);
//
// Client IP address needed for IP stack operation.
//
ZeroMem (&client_ip, sizeof (EFI_IP_ADDRESS));
CopyMem (&client_ip, &This->Data->AckNak.dhcp4.yiaddr, 4);
//
// Enable UDP...
//
efi_status = start_udp (Private, &client_ip, &subnet_mask);
if (EFI_ERROR (efi_status)) {
gBS->FreePool (This->Data);
This->Data = NULL;
if (Private->StopPxeBc) {
Private->PxeBc->Stop (Private->PxeBc);
}
return efi_status;
}
//
// Gather information out of DHCP request packet needed for
// DHCP release packet.
//
//
// Setup DHCP Release packet.
//
CopyMem (&This->Data->Request.dhcp4.ciaddr, &client_ip, 4);
ZeroMem (&This->Data->Request.dhcp4.yiaddr, 12);
ZeroMem (&This->Data->Request.dhcp4.sname, 64 + 128);
This->Data->Request.dhcp4.hops = 0;
This->Data->Request.dhcp4.secs = 0;
This->Data->Request.dhcp4.flags = 0;
ZeroMem (
&This->Data->Request.dhcp4.options,
sizeof This->Data->Request.dhcp4.options
);
CopyMem (&This->Data->Request.dhcp4.options, op_list, 10);
//
// Transmit DHCP Release packet.
//
tx_udp (
Private,
&ServerIp,
&gateway_ip,
&client_ip,
&This->Data->Request,
DHCP4_MAX_PACKET_SIZE - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE)
);
gBS->Stall (1000000); /* 1/10th second */
//
// Shutdown PXE BaseCode and release local storage.
//
stop_udp (Private);
gBS->FreePool (This->Data);
This->Data = NULL;
if (Private->StopPxeBc) {
Private->PxeBc->Stop (Private->PxeBc);
}
return EFI_SUCCESS;
}
/* eof - PxeDhcp4Release.c */

View File

@@ -0,0 +1,408 @@
/** @file
Copyright (c) 2004, 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:
PxeDhcp4RenewRebind.c
Abstract:
**/
#include "PxeDhcp4.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
Parameters:
@return -2 = ignore, stop waiting
@return -1 = ignore, keep waiting
@return 0 = accept, keep waiting
@return 1 = accept, stop waiting
**/
STATIC
INTN
acknak_verify (
IN PXE_DHCP4_PRIVATE_DATA *Private,
IN DHCP4_PACKET *tx_pkt,
IN DHCP4_PACKET *rx_pkt,
IN UINTN rx_pkt_size
)
{
EFI_STATUS efi_status;
DHCP4_OP *msg_type_op;
DHCP4_OP *srvid_op;
DHCP4_OP *renew_op;
DHCP4_OP *rebind_op;
DHCP4_OP *lease_time_op;
UINT32 magik;
//
// Verify parameters. Unused parameters are also touched
// to make the compiler happy.
//
ASSERT (Private);
ASSERT (rx_pkt);
if (Private == NULL || rx_pkt == NULL) {
return -2;
}
tx_pkt = tx_pkt;
rx_pkt_size = rx_pkt_size;
//
// This must be a DHCP Ack message.
//
magik = htonl (DHCP4_MAGIK_NUMBER);
if (CompareMem (&rx_pkt->dhcp4.magik, &magik, 4)) {
return -1;
}
efi_status = find_opt (rx_pkt, DHCP4_MESSAGE_TYPE, 0, &msg_type_op);
if (EFI_ERROR (efi_status)) {
return -1;
}
if (msg_type_op->len != 1) {
return -1;
}
if (msg_type_op->data[0] != DHCP4_MESSAGE_TYPE_ACK) {
return -1;
}
//
// There must be a server identifier.
//
efi_status = find_opt (rx_pkt, DHCP4_SERVER_IDENTIFIER, 0, &srvid_op);
if (EFI_ERROR (efi_status)) {
return -1;
}
if (srvid_op->len != 4) {
return -1;
}
//
// There should be a renewal time.
// If there is not, we will default to the 7/8 of the rebinding time.
//
efi_status = find_opt (rx_pkt, DHCP4_RENEWAL_TIME, 0, &renew_op);
if (EFI_ERROR (efi_status)) {
renew_op = NULL;
} else if (renew_op->len != 4) {
renew_op = NULL;
}
//
// There should be a rebinding time.
// If there is not, we will default to 7/8 of the lease time.
//
efi_status = find_opt (rx_pkt, DHCP4_REBINDING_TIME, 0, &rebind_op);
if (EFI_ERROR (efi_status)) {
rebind_op = NULL;
} else if (rebind_op->len != 4) {
rebind_op = NULL;
}
//
// There should be a lease time.
// If there is not, we will default to one week.
//
efi_status = find_opt (rx_pkt, DHCP4_LEASE_TIME, 0, &lease_time_op);
if (EFI_ERROR (efi_status)) {
lease_time_op = NULL;
} else if (lease_time_op->len != 4) {
lease_time_op = NULL;
}
//
// Packet looks good. Double check the renew, rebind and lease times.
//
CopyMem (&Private->ServerIp, srvid_op->data, 4);
if (renew_op != NULL) {
CopyMem (&Private->RenewTime, renew_op->data, 4);
Private->RenewTime = htonl (Private->RenewTime);
} else {
Private->RenewTime = 0;
}
if (rebind_op != NULL) {
CopyMem (&Private->RebindTime, rebind_op->data, 4);
Private->RebindTime = htonl (Private->RebindTime);
} else {
Private->RebindTime = 0;
}
if (lease_time_op != NULL) {
CopyMem (&Private->LeaseTime, lease_time_op->data, 4);
Private->LeaseTime = htonl (Private->LeaseTime);
} else {
Private->LeaseTime = 0;
}
if (Private->LeaseTime < 60) {
Private->LeaseTime = 7 * 86400;
}
if (Private->RebindTime < 52 || Private->RebindTime >= Private->LeaseTime) {
Private->RebindTime = Private->LeaseTime / 2 + Private->LeaseTime / 4 + Private->LeaseTime / 8;
}
if (Private->RenewTime < 45 || Private->RenewTime >= Private->RebindTime) {
Private->RenewTime = Private->RebindTime / 2 + Private->RebindTime / 4 + Private->RebindTime / 8;
}
return 1;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
STATIC
EFI_STATUS
EFIAPI
renew_rebind (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN UINTN seconds_timeout,
IN BOOLEAN renew
)
{
PXE_DHCP4_PRIVATE_DATA *Private;
EFI_IP_ADDRESS ServerIp;
EFI_IP_ADDRESS client_ip;
EFI_IP_ADDRESS subnet_mask;
EFI_IP_ADDRESS gateway_ip;
DHCP4_PACKET Request;
DHCP4_PACKET AckNak;
DHCP4_OP *op;
EFI_STATUS efi_status;
//
// Check for invalid parameters.
//
if (This == NULL || seconds_timeout < DHCP4_MIN_SECONDS || seconds_timeout > DHCP4_MAX_SECONDS) {
return EFI_INVALID_PARAMETER;
}
//
// Check for proper protocol state.
//
if (This->Data == NULL) {
return EFI_NOT_STARTED;
}
if (!This->Data->SelectCompleted) {
return EFI_NOT_READY;
}
if (This->Data->IsBootp) {
return EFI_SUCCESS;
}
if (!This->Data->IsAck) {
return EFI_INVALID_PARAMETER;
}
//
// Get pointer to instance data.
//
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Private->PxeBc == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Copy Discover packet to temporary request packet
// to be used for Renew/Rebind operation.
//
CopyMem (&Request, &This->Data->Discover, sizeof (DHCP4_PACKET));
CopyMem (&Request.dhcp4.ciaddr, &This->Data->AckNak.dhcp4.yiaddr, 4);
Request.dhcp4.flags = 0; /* Reply does not need to be broadcast. */
//
// Change message type from discover to request.
//
efi_status = find_opt (&Request, DHCP4_MESSAGE_TYPE, 0, &op);
if (EFI_ERROR (efi_status)) {
return EFI_INVALID_PARAMETER;
}
if (op->len != 1) {
return EFI_INVALID_PARAMETER;
}
op->data[0] = DHCP4_MESSAGE_TYPE_REQUEST;
//
// Need a subnet mask.
//
efi_status = find_opt (
&This->Data->AckNak,
DHCP4_SUBNET_MASK,
0,
&op
);
if (EFI_ERROR (efi_status)) {
return EFI_INVALID_PARAMETER;
}
if (op->len != 4) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&subnet_mask, sizeof (EFI_IP_ADDRESS));
CopyMem (&subnet_mask, op->data, 4);
//
// Need a server IP address (renew) or a broadcast
// IP address (rebind).
//
ZeroMem (&gateway_ip, sizeof (EFI_IP_ADDRESS));
if (renew) {
efi_status = find_opt (
&This->Data->AckNak,
DHCP4_SERVER_IDENTIFIER,
0,
&op
);
if (EFI_ERROR (efi_status)) {
return EFI_INVALID_PARAMETER;
}
if (op->len != 4) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&ServerIp, sizeof (EFI_IP_ADDRESS));
CopyMem (&ServerIp, op->data, 4);
//
//
//
if (CompareMem (&This->Data->AckNak.dhcp4.giaddr, &gateway_ip, 4)) {
CopyMem (&gateway_ip, &This->Data->AckNak.dhcp4.giaddr, 4);
}
} else {
SetMem (&ServerIp, sizeof (EFI_IP_ADDRESS), 0xFF);
}
//
// Need a client IP address.
//
ZeroMem (&client_ip, sizeof (EFI_IP_ADDRESS));
CopyMem (&client_ip, &Request.dhcp4.ciaddr, 4);
//
//
//
efi_status = gBS->HandleProtocol (
Private->Handle,
&gEfiPxeDhcp4CallbackProtocolGuid,
(VOID *) &Private->callback
);
if (EFI_ERROR (efi_status)) {
Private->callback = NULL;
}
Private->function = renew ? EFI_PXE_DHCP4_FUNCTION_RENEW : EFI_PXE_DHCP4_FUNCTION_REBIND;
//
// Transimit DHCP request and wait for DHCP ack...
//
efi_status = tx_rx_udp (
Private,
&ServerIp,
&gateway_ip,
&client_ip,
&subnet_mask,
&Request,
&AckNak,
&acknak_verify,
seconds_timeout
);
if (EFI_ERROR (efi_status)) {
Private->callback = NULL;
return efi_status;
}
//
// Copy server identifier, renewal time and rebinding time
// from temporary ack/nak packet into cached ack/nak packet.
//
efi_status = find_opt (
&This->Data->AckNak,
DHCP4_SERVER_IDENTIFIER,
0,
&op
);
if (!EFI_ERROR (efi_status)) {
if (op->len == 4) {
CopyMem (op->data, &Private->ServerIp, 4);
}
}
efi_status = find_opt (&This->Data->AckNak, DHCP4_RENEWAL_TIME, 0, &op);
if (!EFI_ERROR (efi_status)) {
if (op->len == 4) {
CopyMem (op->data, &Private->RenewTime, 4);
}
}
efi_status = find_opt (&This->Data->AckNak, DHCP4_REBINDING_TIME, 0, &op);
if (!EFI_ERROR (efi_status)) {
if (op->len == 4) {
CopyMem (op->data, &Private->RebindTime, 4);
}
}
Private->callback = NULL;
return efi_status;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4Renew (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN UINTN seconds_timeout
)
{
return renew_rebind (This, seconds_timeout, TRUE);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4Rebind (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN UINTN seconds_timeout
)
{
return renew_rebind (This, seconds_timeout, FALSE);
}
/* eof - PxeDhcp4RenewRebind.c */

View File

@@ -0,0 +1,191 @@
/** @file
Copyright (c) 2004 - 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:
PxeDhcp4Run.c
Abstract:
Simplified entry point for starting basic PxeDhcp4 client operation.
**/
#include "PxeDhcp4.h"
EFI_STATUS
EFIAPI
PxeDhcp4Run (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN OPTIONAL UINTN OpLen,
IN OPTIONAL VOID *OpList
)
{
PXE_DHCP4_PRIVATE_DATA *Private;
DHCP4_PACKET *offer_list;
EFI_STATUS efi_status;
EFI_IP_ADDRESS zero_ip;
UINTN offers;
UINTN timeout;
UINTN n;
UINT16 seconds;
//
// Validate parameters.
//
if (This == NULL || (OpLen != 0 && OpList == NULL) || (OpLen == 0 && OpList != NULL)) {
return EFI_INVALID_PARAMETER;
}
for (n = 0; n < OpLen;) {
switch (((UINT8 *) OpList)[n]) {
case DHCP4_PAD:
++n;
continue;
case DHCP4_END:
++n;
break;
default:
n += 2 + ((UINT8 *) OpList)[n + 1];
continue;
}
break;
}
if (n != OpLen) {
return EFI_INVALID_PARAMETER;
}
//
// Get pointer to instance data.
//
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Private->PxeBc == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Initialize DHCP discover packet.
//
efi_status = PxeDhcp4Setup (This, NULL);
if (EFI_ERROR (efi_status)) {
return efi_status;
}
for (n = 0; n < OpLen;) {
switch (((UINT8 *) OpList)[n]) {
case DHCP4_PAD:
++n;
continue;
case DHCP4_END:
++n;
break;
default:
efi_status = add_opt (
&This->Data->Discover,
(DHCP4_OP *) &(((UINT8 *) OpList)[n])
);
if (EFI_ERROR (efi_status)) {
return efi_status;
}
n += 2 + ((UINT8 *) OpList)[n + 1];
continue;
}
break;
}
//
// Basic DHCP D.O.R.A.
// 1, 2, 4, 8, 16 & 32 second timeouts.
// Callback routine can be used to break out earlier.
//
ZeroMem (&zero_ip, sizeof (EFI_IP_ADDRESS));
for (timeout = 1;;) {
//
// Broadcast DHCP discover and wait for DHCP offers.
//
efi_status = PxeDhcp4Init (This, timeout, &offers, &offer_list);
if ((efi_status != EFI_SUCCESS) &&
(efi_status != EFI_TIMEOUT) &&
(efi_status != EFI_NO_RESPONSE)) {
return efi_status;
}
//
// Try to select from each DHCP or BOOTP offer.
//
for (n = 0; n < offers; ++n) {
//
// Ignore proxyDHCP offers.
//
if (!CompareMem (&offer_list[n].dhcp4.yiaddr, &zero_ip, 4)) {
continue;
}
//
// Issue DHCP Request and wait for DHCP Ack/Nak.
//
efi_status = PxeDhcp4Select (
This,
timeout,
&offer_list[n]
);
if (EFI_ERROR (efi_status)) {
continue;
}
//
// Exit when we have got our DHCP Ack.
//
if (This->Data->IsAck) {
return EFI_SUCCESS;
}
}
//
// No DHCP Acks. Release DHCP Offer list storage.
//
if (offer_list != NULL) {
gBS->FreePool (offer_list);
offer_list = NULL;
}
//
// Try again until we have used up >= DHCP4_MAX_SECONDS.
//
if ((timeout <<= 1) > DHCP4_MAX_SECONDS) {
if (!EFI_ERROR (efi_status)) {
efi_status = EFI_TIMEOUT;
}
return efi_status;
}
//
// Next timeout value.
//
CopyMem (&seconds, &This->Data->Discover.dhcp4.secs, 2);
seconds = htons (htons (seconds) + timeout);
CopyMem (&This->Data->Discover.dhcp4.secs, &seconds, 2);
}
}
/* eof - PxeDhcp4Run.c */

View File

@@ -0,0 +1,258 @@
/** @file
Copyright (c) 2004, 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:
PxeDhcp4Setup.c
Abstract:
**/
#include "PxeDhcp4.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
EFIAPI
PxeDhcp4Setup (
IN EFI_PXE_DHCP4_PROTOCOL *This,
IN EFI_PXE_DHCP4_DATA *Data
)
{
PXE_DHCP4_PRIVATE_DATA *Private;
DHCP4_HEADER *Packet;
EFI_STATUS EfiStatus;
UINT8 *OpLen;
UINT8 *OpPtr;
//
// Return error if parameters are invalid.
//
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Private = PXE_DHCP4_PRIVATE_DATA_FROM_THIS (This);
if (Private == NULL) {
return EFI_INVALID_PARAMETER;
}
if (This->Data != NULL) {
return EFI_ALREADY_STARTED;
}
if (Private->PxeBc == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Check contents of provided Data structure.
//
if (Data != NULL) {
//
// Do protocol state checks first.
//
if (Data->SelectCompleted) {
if (!Data->InitCompleted || !Data->SetupCompleted) {
return EFI_INVALID_PARAMETER;
}
if (Data->IsBootp && !Data->IsAck) {
return EFI_INVALID_PARAMETER;
}
} else if (Data->InitCompleted) {
if (!Data->SetupCompleted || Data->IsBootp || Data->IsAck) {
return EFI_INVALID_PARAMETER;
}
} else if (Data->SetupCompleted) {
if (Data->IsBootp || Data->IsAck) {
return EFI_INVALID_PARAMETER;
}
}
//
// Do packet content checks.
//
if (Data->SetupCompleted) {
//
// %%TBD - check discover packet
//
}
if (Data->SelectCompleted) {
if (Data->IsBootp) {
//
// %%TBD - check offer packet
//
if (CompareMem (
&Data->Discover,
&Data->Request,
sizeof (DHCP4_PACKET)
)) {
return EFI_INVALID_PARAMETER;
}
if (CompareMem (
&Data->Offer,
&Data->AckNak,
sizeof (DHCP4_PACKET)
)) {
return EFI_INVALID_PARAMETER;
}
} else {
//
// %%TBD - check offer, request & acknak packets
//
}
}
}
//
// Allocate data structure. Return error
// if there is not enough available memory.
//
This->Data = AllocatePool (sizeof (EFI_PXE_DHCP4_DATA));
if (This->Data == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Start PxeBc because we want to use its UdpWrite, UdpRead and
// SetFilter calls.
//
EfiStatus = Private->PxeBc->Start (Private->PxeBc, FALSE);
if (EFI_ERROR (EfiStatus)) {
if (EfiStatus != EFI_ALREADY_STARTED) {
FreePool (This->Data);
This->Data = NULL;
Private->PxeBc->Stop (Private->PxeBc);
return EfiStatus;
}
Private->StopPxeBc = FALSE;
} else {
Private->StopPxeBc = TRUE;
}
//
// Use new data.
//
if (Data != NULL) {
CopyMem (This->Data, Data, sizeof (EFI_PXE_DHCP4_DATA));
return EFI_SUCCESS;
}
//
// Initialize new public data structure.
//
ZeroMem (This->Data, sizeof (EFI_PXE_DHCP4_DATA));
//
// Fill in default DHCP discover packet.
// Check for MAC addresses of strange lengths, just in case.
//
Packet = &This->Data->Discover.dhcp4;
Packet->op = BOOTP_REQUEST;
Packet->htype = Private->Snp->Mode->IfType;
if (Private->Snp->Mode->HwAddressSize > 16) {
Packet->hlen = 16;
} else {
Packet->hlen = (UINT8) Private->Snp->Mode->HwAddressSize;
}
Packet->hops = 0; /* Set to zero per RFC 2131. */
if (Packet->hlen < sizeof Packet->xid) {
if (Packet->hlen != 0) {
CopyMem (
&Packet->xid,
&Private->Snp->Mode->CurrentAddress,
Packet->hlen
);
}
} else {
CopyMem (
&Packet->xid,
&Private->Snp->Mode->CurrentAddress.Addr[Packet->hlen - sizeof Packet->xid],
sizeof Packet->xid
);
}
//
// %%TBD - xid should be randomized
//
Packet->secs = htons (DHCP4_INITIAL_SECONDS);
Packet->flags = htons (DHCP4_BROADCAST_FLAG);
if (Packet->hlen != 0) {
CopyMem (Packet->chaddr, &Private->Snp->Mode->CurrentAddress, Packet->hlen);
}
Packet->magik = htonl (DHCP4_MAGIK_NUMBER);
OpPtr = Packet->options;
*OpPtr++ = DHCP4_MESSAGE_TYPE;
*OpPtr++ = 1;
*OpPtr++ = DHCP4_MESSAGE_TYPE_DISCOVER;
*OpPtr++ = DHCP4_MAX_MESSAGE_SIZE;
*OpPtr++ = 2;
*OpPtr++ = (UINT8) ((DHCP4_DEFAULT_MAX_MESSAGE_SIZE >> 8) & 0xFF);
*OpPtr++ = (UINT8) (DHCP4_DEFAULT_MAX_MESSAGE_SIZE & 0xFF);
*OpPtr++ = DHCP4_PARAMETER_REQUEST_LIST;
OpLen = OpPtr;
*OpPtr++ = 0;
*OpPtr++ = DHCP4_SUBNET_MASK;
*OpPtr++ = DHCP4_TIME_OFFSET;
*OpPtr++ = DHCP4_ROUTER_LIST;
*OpPtr++ = DHCP4_TIME_SERVERS;
*OpPtr++ = DHCP4_NAME_SERVERS;
*OpPtr++ = DHCP4_DNS_SERVERS;
*OpPtr++ = DHCP4_HOST_NAME;
*OpPtr++ = DHCP4_BOOT_FILE_SIZE;
*OpPtr++ = DHCP4_MESSAGE_TYPE;
*OpPtr++ = DHCP4_DOMAIN_NAME;
*OpPtr++ = DHCP4_ROOT_PATH;
*OpPtr++ = DHCP4_EXTENSION_PATH;
*OpPtr++ = DHCP4_MAX_DATAGRAM_SIZE;
*OpPtr++ = DHCP4_DEFAULT_TTL;
*OpPtr++ = DHCP4_BROADCAST_ADDRESS;
*OpPtr++ = DHCP4_NIS_DOMAIN_NAME;
*OpPtr++ = DHCP4_NIS_SERVERS;
*OpPtr++ = DHCP4_NTP_SERVERS;
*OpPtr++ = DHCP4_VENDOR_SPECIFIC;
*OpPtr++ = DHCP4_REQUESTED_IP_ADDRESS;
*OpPtr++ = DHCP4_LEASE_TIME;
*OpPtr++ = DHCP4_SERVER_IDENTIFIER;
*OpPtr++ = DHCP4_RENEWAL_TIME;
*OpPtr++ = DHCP4_REBINDING_TIME;
*OpPtr++ = DHCP4_CLASS_IDENTIFIER;
*OpPtr++ = DHCP4_TFTP_SERVER_NAME;
*OpPtr++ = DHCP4_BOOTFILE;
*OpPtr++ = 128;
*OpPtr++ = 129;
*OpPtr++ = 130;
*OpPtr++ = 131;
*OpPtr++ = 132;
*OpPtr++ = 133;
*OpPtr++ = 134;
*OpPtr++ = 135;
*OpLen = (UINT8) ((OpPtr - OpLen) - 1);
*OpPtr++ = DHCP4_END;
This->Data->SetupCompleted = TRUE;
return EFI_SUCCESS;
}
/* eof - PxeDhcp4Setup.c */

File diff suppressed because it is too large Load Diff