Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
169
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/ComponentName.c
Normal file
169
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/ComponentName.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
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",
|
||||
(CHAR16 *) 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 */
|
41
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.mbd
Normal file
41
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.mbd
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
-->
|
||||
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
|
||||
<MbdHeader>
|
||||
<BaseName>Dhcp4</BaseName>
|
||||
<Guid>a46c3330-be36-4977-9d24-a7cf92eef0fe</Guid>
|
||||
<Version>0</Version>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2004-2006, Intel Corporation</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>
|
||||
<Created>2006-03-12 17:09</Created>
|
||||
<Modified>2006-03-19 15:19</Modified>
|
||||
</MbdHeader>
|
||||
<Libraries>
|
||||
<Library>UefiBootServicesTableLib</Library>
|
||||
<Library>UefiMemoryLib</Library>
|
||||
<Library>UefiLib</Library>
|
||||
<Library>UefiDriverEntryPoint</Library>
|
||||
<Library>UefiDriverModelLib</Library>
|
||||
<Library>DxeReportStatusCodeLib</Library>
|
||||
<Library>BaseDebugLibReportStatusCode</Library>
|
||||
<Library>BaseLib</Library>
|
||||
<Library>DxeMemoryAllocationLib</Library>
|
||||
</Libraries>
|
||||
</ModuleBuildDescription>
|
74
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.msa
Normal file
74
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/Dhcp4.msa
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
-->
|
||||
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
|
||||
<MsaHeader>
|
||||
<BaseName>Dhcp4</BaseName>
|
||||
<ModuleType>UEFI_DRIVER</ModuleType>
|
||||
<ComponentType>BS_DRIVER</ComponentType>
|
||||
<Guid>a46c3330-be36-4977-9d24-a7cf92eef0fe</Guid>
|
||||
<Version>0</Version>
|
||||
<Abstract>Component description file for DiskIo module.</Abstract>
|
||||
<Description>FIX ME!</Description>
|
||||
<Copyright>Copyright (c) 2004-2006, Intel Corporation</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>0</Specification>
|
||||
<Created>2006-03-12 17:09</Created>
|
||||
<Updated>2006-03-19 15:19</Updated>
|
||||
</MsaHeader>
|
||||
<LibraryClassDefinitions>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
<Filename>PxeDhcp4.c</Filename>
|
||||
<Filename>PxeDhcp4.h</Filename>
|
||||
<Filename>PxeDhcp4InitSelect.c</Filename>
|
||||
<Filename>PxeDhcp4Release.c</Filename>
|
||||
<Filename>PxeDhcp4RenewRebind.c</Filename>
|
||||
<Filename>PxeDhcp4Run.c</Filename>
|
||||
<Filename>PxeDhcp4Setup.c</Filename>
|
||||
<Filename>support.c</Filename>
|
||||
</SourceFiles>
|
||||
<Includes>
|
||||
<PackageName>MdePkg</PackageName>
|
||||
<PackageName>EdkModulePkg</PackageName>
|
||||
</Includes>
|
||||
<Protocols>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">PxeDhcp4Callback</Protocol>
|
||||
<Protocol Usage="BY_START">PxeDhcp4</Protocol>
|
||||
<Protocol Usage="ALWAYS_CONSUMED">SimpleNetwork</Protocol>
|
||||
<Protocol Usage="TO_START">PxeBaseCode</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Extern>
|
||||
<ModuleEntryPoint></ModuleEntryPoint>
|
||||
<ModuleUnloadImage></ModuleUnloadImage>
|
||||
</Extern>
|
||||
<Extern>
|
||||
<DriverBinding>gPxeDhcp4DriverBinding</DriverBinding>
|
||||
<ComponentName>gPxeDhcp4ComponentName</ComponentName>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
342
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.c
Normal file
342
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
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,
|
||||
0x10,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PxeDhcp4DriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Test to see if this driver supports ControllerHandle. Any
|
||||
ControllerHandle that contains a PxeBaseCode protocol can be
|
||||
supported.
|
||||
|
||||
Arguments:
|
||||
This - Protocol instance pointer.
|
||||
ControllerHandle - Handle of device to test.
|
||||
RemainingDevicePath - Not used.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - This driver supports this device.
|
||||
EFI_ALREADY_STARTED - This driver is already running on this
|
||||
device.
|
||||
other - This driver does not support this device.
|
||||
|
||||
--*/
|
||||
{
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PxeDhcp4DriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL * This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Start this driver on ControllerHandle by opening a PxeBaseCode
|
||||
protocol and installing a PxeDhcp4 protocol on ControllerHandle.
|
||||
|
||||
Arguments:
|
||||
This - Protocol instance pointer.
|
||||
ControllerHandle - Handle of device to bind driver to.
|
||||
RemainingDevicePath - Not used, always produce all possible
|
||||
children.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - This driver is added to ControllerHandle.
|
||||
EFI_ALREADY_STARTED - This driver is already running on
|
||||
ControllerHandle.
|
||||
other - This driver does not support this device.
|
||||
|
||||
--*/
|
||||
{
|
||||
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.
|
||||
//
|
||||
Status = gBS->AllocatePool (
|
||||
EfiBootServicesData,
|
||||
sizeof (PXE_DHCP4_PRIVATE_DATA),
|
||||
(VOID **) &Private
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto error_exit;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
ZeroMem (Private, sizeof (PXE_DHCP4_PRIVATE_DATA));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PxeDhcp4DriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Stop this driver on ControllerHandle by removing PXE DHCP
|
||||
protocol and closing the PXE Base Code protocol on
|
||||
ControllerHandle.
|
||||
|
||||
Arguments:
|
||||
This - Protocol instance pointer.
|
||||
ControllerHandle - Handle of device to stop driver on.
|
||||
NumberOfChildren - Not used.
|
||||
ChildHandleBuffer - Not used.
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - This driver is removed ControllerHandle.
|
||||
other - This driver was not removed from this
|
||||
device.
|
||||
|
||||
--*/
|
||||
{
|
||||
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) {
|
||||
gBS->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
|
||||
//
|
||||
gBS->FreePool (Private);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF - PxeDhcp4.c */
|
307
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.h
Normal file
307
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4.h
Normal file
@@ -0,0 +1,307 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
PxeDhcp4.h
|
||||
|
||||
Abstract:
|
||||
Common header for PxeDhcp4 protocol driver
|
||||
|
||||
--*/
|
||||
#ifndef _PXEDHCP4_H
|
||||
#define _PXEDHCP4_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_DRIVER_BINDING_PROTOCOL gPxeDhcp4DriverBinding;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gPxeDhcp4ComponentName;
|
||||
|
||||
#endif /* _PXEDHCP4_H */
|
||||
|
||||
/* EOF - PxeDhcp4.h */
|
786
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4InitSelect.c
Normal file
786
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4InitSelect.c
Normal file
@@ -0,0 +1,786 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
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
|
||||
)
|
||||
/*++
|
||||
-2 = ignore, stop waiting
|
||||
-1 = ignore, keep waiting
|
||||
0 = accept, keep waiting
|
||||
1 = accept, stop waiting
|
||||
--*/
|
||||
{
|
||||
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
|
||||
)
|
||||
/*++
|
||||
-2 = ignore, stop waiting
|
||||
-1 = ignore, keep waiting
|
||||
0 = accept, keep waiting
|
||||
1 = accept, stop waiting
|
||||
--*/
|
||||
{
|
||||
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 */
|
246
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Release.c
Normal file
246
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Release.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
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 */
|
@@ -0,0 +1,408 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
PxeDhcp4RenewRebind.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "PxeDhcp4.h"
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
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
|
||||
)
|
||||
/*++
|
||||
Routine Description:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
-2 = ignore, stop waiting
|
||||
-1 = ignore, keep waiting
|
||||
0 = accept, keep waiting
|
||||
1 = accept, stop waiting
|
||||
--*/
|
||||
{
|
||||
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 */
|
196
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Run.c
Normal file
196
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Run.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
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);
|
||||
|
||||
switch (efi_status) {
|
||||
case EFI_NO_RESPONSE:
|
||||
case EFI_TIMEOUT:
|
||||
case EFI_SUCCESS:
|
||||
break;
|
||||
|
||||
case EFI_ABORTED:
|
||||
default:
|
||||
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 */
|
268
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Setup.c
Normal file
268
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/PxeDhcp4Setup.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
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.
|
||||
//
|
||||
EfiStatus = gBS->AllocatePool (
|
||||
EfiBootServicesData,
|
||||
sizeof (EFI_PXE_DHCP4_DATA),
|
||||
(VOID **) &This->Data
|
||||
);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
This->Data = NULL;
|
||||
return EfiStatus;
|
||||
}
|
||||
|
||||
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) {
|
||||
gBS->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 */
|
47
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/build.xml
Normal file
47
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/build.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
|
||||
<project basedir="." default="Dhcp4"><!--Apply external ANT tasks-->
|
||||
<taskdef resource="GenBuild.tasks"/>
|
||||
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
|
||||
<property environment="env"/>
|
||||
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
|
||||
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
|
||||
<property name="MODULE_RELATIVE_PATH" value="Universal\Network\PxeDhcp4\Dxe"/>
|
||||
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
|
||||
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
|
||||
<target name="Dhcp4">
|
||||
<GenBuild baseName="Dhcp4" mbdFilename="${MODULE_DIR}\Dhcp4.mbd" msaFilename="${MODULE_DIR}\Dhcp4.msa"/>
|
||||
</target>
|
||||
<target depends="Dhcp4_clean" name="clean"/>
|
||||
<target depends="Dhcp4_cleanall" name="cleanall"/>
|
||||
<target name="Dhcp4_clean">
|
||||
<OutputDirSetup baseName="Dhcp4" mbdFilename="${MODULE_DIR}\Dhcp4.mbd" msaFilename="${MODULE_DIR}\Dhcp4.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\Dhcp4_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\Dhcp4_build.xml" target="clean"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
|
||||
</target>
|
||||
<target name="Dhcp4_cleanall">
|
||||
<OutputDirSetup baseName="Dhcp4" mbdFilename="${MODULE_DIR}\Dhcp4.mbd" msaFilename="${MODULE_DIR}\Dhcp4.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\Dhcp4_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\Dhcp4_build.xml" target="cleanall"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}"/>
|
||||
<delete dir="${DEST_DIR_DEBUG}"/>
|
||||
<delete>
|
||||
<fileset dir="${BIN_DIR}" includes="**Dhcp4*"/>
|
||||
</delete>
|
||||
</target>
|
||||
</project>
|
1126
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c
Normal file
1126
EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user