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:
169
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/ComponentName.c
Normal file
169
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/ComponentName.c
Normal 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 */
|
355
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4.c
Normal file
355
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4.c
Normal 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 */
|
353
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4.h
Normal file
353
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4.h
Normal 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 */
|
64
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Dxe.inf
Normal file
64
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Dxe.inf
Normal 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
|
||||
|
78
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Dxe.msa
Normal file
78
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Dxe.msa
Normal 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>
|
784
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4InitSelect.c
Normal file
784
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4InitSelect.c
Normal 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 */
|
247
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Release.c
Normal file
247
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Release.c
Normal 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 */
|
408
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4RenewRebind.c
Normal file
408
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4RenewRebind.c
Normal 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 */
|
191
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Run.c
Normal file
191
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Run.c
Normal 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 */
|
258
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Setup.c
Normal file
258
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/PxeDhcp4Setup.c
Normal 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 */
|
1086
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/Support.c
Normal file
1086
MdeModulePkg/Universal/Network/PxeDhcp4Dxe/Support.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user