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:
42
EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.mbd
Normal file
42
EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.mbd
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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>BC</BaseName>
|
||||
<Guid>A3f436EA-A127-4EF8-957C-8048606FF670</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>EdkDxePrintLib</Library>
|
||||
<Library>BaseLib</Library>
|
||||
<Library>DxeMemoryAllocationLib</Library>
|
||||
</Libraries>
|
||||
</ModuleBuildDescription>
|
94
EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.msa
Normal file
94
EdkModulePkg/Universal/Network/PxeBc/Dxe/BC.msa
Normal file
@@ -0,0 +1,94 @@
|
||||
<?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>BC</BaseName>
|
||||
<ModuleType>UEFI_DRIVER</ModuleType>
|
||||
<ComponentType>BS_DRIVER</ComponentType>
|
||||
<Guid>A3f436EA-A127-4EF8-957C-8048606FF670</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">BaseLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">PrintLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>bc.c</Filename>
|
||||
<Filename>pxe_bc_arp.c</Filename>
|
||||
<Filename>pxe_bc_dhcp.c</Filename>
|
||||
<Filename>pxe_bc_igmp.c</Filename>
|
||||
<Filename>pxe_bc_ip.c</Filename>
|
||||
<Filename>pxe_bc_mtftp.c</Filename>
|
||||
<Filename>pxe_bc_udp.c</Filename>
|
||||
<Filename>pxe_loadfile.c</Filename>
|
||||
<Filename>dhcp.h</Filename>
|
||||
<Filename>bc.h</Filename>
|
||||
<Filename>ip.h</Filename>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
<Filename>Print.c</Filename>
|
||||
</SourceFiles>
|
||||
<Includes>
|
||||
<PackageName>MdePkg</PackageName>
|
||||
<PackageName>EdkModulePkg</PackageName>
|
||||
</Includes>
|
||||
<Protocols>
|
||||
<Protocol Usage="TO_START">Bis</Protocol>
|
||||
<Protocol Usage="BY_START">LoadFile</Protocol>
|
||||
<Protocol Usage="SOMETIMES_PRODUCED">PxeBaseCodeCallBack</Protocol>
|
||||
<Protocol Usage="TO_START">SimpleNetwork</Protocol>
|
||||
<Protocol Usage="TO_START">DevicePath</Protocol>
|
||||
<Protocol Usage="SOMETIMES_CONSUMED">NetworkInterfaceIdentifier</Protocol>
|
||||
<Protocol Usage="SOMETIMES_CONSUMED">NetworkInterfaceIdentifier2</Protocol>
|
||||
<Protocol Usage="BY_START">PxeBaseCode</Protocol>
|
||||
</Protocols>
|
||||
<SystemTables>
|
||||
<SystemTable Usage="SOMETIMES_CONSUMED">
|
||||
<Entry>gEfiSmbiosTableGuid</Entry>
|
||||
</SystemTable>
|
||||
</SystemTables>
|
||||
<Guids>
|
||||
<GuidEntry Usage="ALWAYS_CONSUMED">
|
||||
<C_Name>SmbiosTable</C_Name>
|
||||
</GuidEntry>
|
||||
</Guids>
|
||||
<Externs>
|
||||
<Extern>
|
||||
<ModuleEntryPoint>InitializeBCDriver</ModuleEntryPoint>
|
||||
<ModuleUnloadImage></ModuleUnloadImage>
|
||||
</Extern>
|
||||
<Extern>
|
||||
<DriverBinding>gPxeBcDriverBinding</DriverBinding>
|
||||
<ComponentName>gPxeBcComponentName</ComponentName>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
160
EdkModulePkg/Universal/Network/PxeBc/Dxe/ComponentName.c
Normal file
160
EdkModulePkg/Universal/Network/PxeBc/Dxe/ComponentName.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "Bc.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PxeBcComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PxeBcComponentNameGetControllerName (
|
||||
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 gPxeBcComponentName = {
|
||||
PxeBcComponentNameGetDriverName,
|
||||
PxeBcComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
static EFI_UNICODE_STRING_TABLE mPxeBcDriverNameTable[] = {
|
||||
{
|
||||
"eng",
|
||||
(CHAR16 *) L"PXE Base Code Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PxeBcComponentNameGetDriverName (
|
||||
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,
|
||||
gPxeBcComponentName.SupportedLanguages,
|
||||
mPxeBcDriverNameTable,
|
||||
DriverName
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PxeBcComponentNameGetControllerName (
|
||||
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;
|
||||
}
|
81
EdkModulePkg/Universal/Network/PxeBc/Dxe/Print.c
Normal file
81
EdkModulePkg/Universal/Network/PxeBc/Dxe/Print.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*++
|
||||
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:
|
||||
Print.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include <Bc.h>
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
AsciiPrint (
|
||||
IN CONST CHAR8 *Format,
|
||||
...
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Print function for a maximum of PXE_MAX_PRINT_BUFFER ascii
|
||||
characters.
|
||||
|
||||
Arguments:
|
||||
|
||||
Format - Ascii format string see file header for more details.
|
||||
|
||||
... - Vararg list consumed by processing Format.
|
||||
|
||||
Returns:
|
||||
|
||||
Number of characters printed.
|
||||
|
||||
--*/
|
||||
{
|
||||
UINTN Return;
|
||||
VA_LIST Marker;
|
||||
UINTN Index;
|
||||
UINTN MaxIndex;
|
||||
CHAR16 Buffer[PXE_MAX_PRINT_BUFFER];
|
||||
CHAR16 UnicodeFormat[PXE_MAX_PRINT_BUFFER];
|
||||
|
||||
MaxIndex = AsciiStrLen ((CHAR8 *) Format);
|
||||
if (MaxIndex > PXE_MAX_PRINT_BUFFER) {
|
||||
//
|
||||
// Format string was too long for use to process.
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PXE_MAX_PRINT_BUFFER; Index++) {
|
||||
UnicodeFormat[Index] = (CHAR16) Format[Index];
|
||||
}
|
||||
|
||||
VA_START (Marker, Format);
|
||||
Return = UnicodeVSPrint (Buffer, sizeof (Buffer), UnicodeFormat, Marker);
|
||||
VA_END (Marker);
|
||||
|
||||
//
|
||||
// Need to convert to Unicode to do an OutputString
|
||||
//
|
||||
|
||||
if (gST->ConOut != NULL) {
|
||||
//
|
||||
// To be extra safe make sure ConOut has been initialized
|
||||
//
|
||||
gST->ConOut->OutputString (gST->ConOut, Buffer);
|
||||
}
|
||||
|
||||
return Return;
|
||||
}
|
2510
EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c
Normal file
2510
EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c
Normal file
File diff suppressed because it is too large
Load Diff
499
EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.h
Normal file
499
EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.h
Normal file
@@ -0,0 +1,499 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
bc.h
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _BC_H
|
||||
#define _BC_H
|
||||
|
||||
#ifndef EFI_MIN
|
||||
#define EFI_MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
|
||||
#endif
|
||||
|
||||
#define CALLBACK_INTERVAL 100 // ten times a second
|
||||
#define FILTER_BITS (EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP | \
|
||||
EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST | \
|
||||
EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS | \
|
||||
EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST \
|
||||
)
|
||||
|
||||
#define WAIT_TX_TIMEOUT 1000
|
||||
|
||||
#define SUPPORT_IPV6 0
|
||||
|
||||
#define PXE_BASECODE_DEVICE_SIGNATURE EFI_SIGNATURE_32('p','x','e','d')
|
||||
|
||||
//
|
||||
// Determine the classes of IPv4 address
|
||||
//
|
||||
#define IS_CLASSA_IPADDR(x) ((((EFI_IP_ADDRESS*)x)->v4.Addr[0] & 0x80) == 0x00)
|
||||
#define IS_CLASSB_IPADDR(x) ((((EFI_IP_ADDRESS*)x)->v4.Addr[0] & 0xc0) == 0x80)
|
||||
#define IS_CLASSC_IPADDR(x) ((((EFI_IP_ADDRESS*)x)->v4.Addr[0] & 0xe0) == 0xc0)
|
||||
#define IS_INADDR_UNICAST(x) ((IS_CLASSA_IPADDR(x) || IS_CLASSB_IPADDR(x) || IS_CLASSC_IPADDR(x)) && (((EFI_IP_ADDRESS*)x)->Addr[0] != 0) )
|
||||
|
||||
//
|
||||
// Definitions for internet group management protocol version 2 message
|
||||
// structure
|
||||
// Per RFC 2236, November 1997
|
||||
//
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
UINT8 Type;
|
||||
UINT8 MaxRespTime; // in tenths of a second
|
||||
UINT16 Checksum; // ones complement of ones complement sum of
|
||||
// 16 bit words of message
|
||||
UINT32 GroupAddress; // for general query, all systems group,
|
||||
// for group specific, the group
|
||||
} IGMPV2_MESSAGE;
|
||||
|
||||
#define IGMP_TYPE_QUERY 0x11
|
||||
#define IGMP_TYPE_REPORT 0x16
|
||||
#define IGMP_TYPE_V1REPORT 0x12
|
||||
#define IGMP_TYPE_LEAVE_GROUP 0x17
|
||||
|
||||
#define IGMP_DEFAULT_MAX_RESPONSE_TIME 10 // 10 second default
|
||||
#pragma pack()
|
||||
|
||||
#define MAX_MCAST_GROUPS 8 // most we allow ourselves to join at once
|
||||
#define MAX_OFFERS 16
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_LOCK Lock;
|
||||
BOOLEAN ShowErrorMessages;
|
||||
EFI_PXE_BASE_CODE_PROTOCOL EfiBc;
|
||||
EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *CallbackProtocolPtr;
|
||||
EFI_HANDLE Handle;
|
||||
|
||||
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NiiPtr;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork;
|
||||
UINT8 *TransmitBufferPtr;
|
||||
UINT8 *ReceiveBufferPtr;
|
||||
EFI_PXE_BASE_CODE_FUNCTION Function;
|
||||
|
||||
UINTN OldestArpEntry;
|
||||
UINTN MCastGroupCount;
|
||||
EFI_EVENT Igmpv1TimeoutEvent;
|
||||
BOOLEAN UseIgmpv1Reporting;
|
||||
EFI_EVENT IgmpGroupEvent[MAX_MCAST_GROUPS];
|
||||
UINT16 RandomPort;
|
||||
|
||||
#if SUPPORT_IPV6
|
||||
//
|
||||
// TBD
|
||||
//
|
||||
#else
|
||||
UINT32 MCastGroup[MAX_MCAST_GROUPS];
|
||||
#endif
|
||||
|
||||
BOOLEAN GoodStationIp;
|
||||
BOOLEAN DidTransmit;
|
||||
UINTN IpLength;
|
||||
VOID *DhcpPacketBuffer;
|
||||
UINTN FileSize;
|
||||
VOID *BootServerReceiveBuffer;
|
||||
EFI_IP_ADDRESS ServerIp;
|
||||
|
||||
//
|
||||
// work area
|
||||
// for dhcp
|
||||
//
|
||||
VOID *ReceiveBuffers;
|
||||
VOID *TransmitBuffer;
|
||||
UINTN NumOffersReceived;
|
||||
UINT16 TotalSeconds;
|
||||
|
||||
//
|
||||
// arrays for different types of offers
|
||||
//
|
||||
UINT8 ServerCount[4];
|
||||
UINT8 OfferCount[4][MAX_OFFERS];
|
||||
UINT8 GotBootp;
|
||||
UINT8 GotProxy[4];
|
||||
UINT8 BinlProxies[MAX_OFFERS];
|
||||
|
||||
UINT8 *ArpBuffer;
|
||||
UINT8 *TftpAckBuffer;
|
||||
UINT8 *TftpErrorBuffer;
|
||||
IGMPV2_MESSAGE IgmpMessage;
|
||||
BOOLEAN BigBlkNumFlag;
|
||||
UINT8 Timeout;
|
||||
UINT16 RandomSeed;
|
||||
} PXE_BASECODE_DEVICE;
|
||||
|
||||
//
|
||||
// type index
|
||||
//
|
||||
#define DHCP_ONLY_IX 0
|
||||
#define PXE10_IX 1
|
||||
#define WfM11a_IX 2
|
||||
#define BINL_IX 3
|
||||
|
||||
#define PXE_RND_PORT_LOW 2070
|
||||
|
||||
#define PXE_MAX_PRINT_BUFFER 128
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
#define LOADFILE_DEVICE_SIGNATURE EFI_SIGNATURE_32('p','x','e','l')
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_LOCK Lock;
|
||||
EFI_LOAD_FILE_PROTOCOL LoadFile;
|
||||
PXE_BASECODE_DEVICE *Private;
|
||||
} LOADFILE_DEVICE;
|
||||
|
||||
#define EFI_BASE_CODE_DEV_FROM_THIS(a) CR (a, PXE_BASECODE_DEVICE, efi_bc, PXE_BASECODE_DEVICE_SIGNATURE);
|
||||
|
||||
#define EFI_LOAD_FILE_DEV_FROM_THIS(a) CR (a, LOADFILE_DEVICE, LoadFile, LOADFILE_DEVICE_SIGNATURE)
|
||||
|
||||
EFI_BIS_PROTOCOL *
|
||||
PxebcBisStart (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
BIS_APPLICATION_HANDLE *BisAppHandle,
|
||||
EFI_BIS_DATA **BisDataSigInfo
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
PxebcBisStop (
|
||||
EFI_BIS_PROTOCOL *Bis,
|
||||
BIS_APPLICATION_HANDLE BisAppHandle,
|
||||
EFI_BIS_DATA *BisDataSigInfo
|
||||
)
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
PxebcBisVerify (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
VOID *FileBuffer,
|
||||
UINTN FileBufferLength,
|
||||
VOID *CredentialBuffer,
|
||||
UINTN CredentialBufferLength
|
||||
)
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
PxebcBisDetect (
|
||||
PXE_BASECODE_DEVICE *Private
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gPxeBcComponentName;
|
||||
|
||||
//
|
||||
// //////////////////////////////////////////////////////////
|
||||
//
|
||||
// prototypes
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeBCDriver (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcStart (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
|
||||
IN BOOLEAN UseIpv6
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcStop (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcDhcp (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
|
||||
IN BOOLEAN SortOffers
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcDiscover (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
|
||||
IN UINT16 Type,
|
||||
IN UINT16 *Layer,
|
||||
IN BOOLEAN UseBis,
|
||||
IN EFI_PXE_BASE_CODE_DISCOVER_INFO * Info OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcMtftp (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
|
||||
IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
|
||||
IN OUT VOID *BufferPtr,
|
||||
IN BOOLEAN Overwrite,
|
||||
IN OUT UINT64 *BufferSize,
|
||||
IN UINTN *BlockSize OPTIONAL,
|
||||
IN EFI_IP_ADDRESS * ServerIp,
|
||||
IN UINT8 *Filename,
|
||||
IN EFI_PXE_BASE_CODE_MTFTP_INFO * Info OPTIONAL,
|
||||
IN BOOLEAN DontUseBuffer
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcUdpWrite (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
|
||||
IN UINT16 OpFlags,
|
||||
IN EFI_IP_ADDRESS *DestIp,
|
||||
IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort,
|
||||
IN EFI_IP_ADDRESS *GatewayIp, OPTIONAL
|
||||
IN EFI_IP_ADDRESS *SrcIp, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL
|
||||
IN UINTN *HeaderSize, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN UINTN *BufferSize,
|
||||
IN VOID *BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcUdpRead (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
|
||||
IN UINT16 OpFlags,
|
||||
IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL
|
||||
IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL
|
||||
IN UINTN *HeaderSize, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcArp (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
|
||||
IN EFI_IP_ADDRESS * IpAddr,
|
||||
IN EFI_MAC_ADDRESS * MacAddr OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcIpFilter (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
|
||||
IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcSetParameters (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
|
||||
IN BOOLEAN *NewAutoArp, OPTIONAL
|
||||
IN BOOLEAN *NewSendGUID, OPTIONAL
|
||||
IN UINT8 *NewTTL, OPTIONAL
|
||||
IN UINT8 *NewToS, OPTIONAL
|
||||
IN BOOLEAN *NewMakeCallback OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcSetStationIP (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
|
||||
IN EFI_IP_ADDRESS * NewStationIp, OPTIONAL
|
||||
IN EFI_IP_ADDRESS * NewSubnetMask OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcSetPackets (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
|
||||
BOOLEAN *NewDhcpDiscoverValid, OPTIONAL
|
||||
BOOLEAN *NewDhcpAckReceived, OPTIONAL
|
||||
BOOLEAN *NewProxyOfferReceived, OPTIONAL
|
||||
BOOLEAN *NewPxeDiscoverValid, OPTIONAL
|
||||
BOOLEAN *NewPxeReplyReceived, OPTIONAL
|
||||
BOOLEAN *NewPxeBisReplyReceived, OPTIONAL
|
||||
IN EFI_PXE_BASE_CODE_PACKET * NewDhcpDiscover, OPTIONAL
|
||||
IN EFI_PXE_BASE_CODE_PACKET * NewDhcpAck, OPTIONAL
|
||||
IN EFI_PXE_BASE_CODE_PACKET * NewProxyOffer, OPTIONAL
|
||||
IN EFI_PXE_BASE_CODE_PACKET * NewPxeDiscover, OPTIONAL
|
||||
IN EFI_PXE_BASE_CODE_PACKET * NewPxeReply, OPTIONAL
|
||||
IN EFI_PXE_BASE_CODE_PACKET * NewPxeBisReply OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
LoadFile (
|
||||
IN EFI_LOAD_FILE_PROTOCOL *This,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||
IN BOOLEAN BootPolicy,
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
PxeBcLibGetSmbiosSystemGuidAndSerialNumber (
|
||||
IN EFI_GUID *SystemGuid,
|
||||
OUT CHAR8 **SystemSerialNumber
|
||||
)
|
||||
;
|
||||
|
||||
UINTN
|
||||
EFIAPI
|
||||
AsciiPrint (
|
||||
IN CONST CHAR8 *Format,
|
||||
...
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// Define SMBIOS tables.
|
||||
//
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT8 AnchorString[4];
|
||||
UINT8 EntryPointStructureChecksum;
|
||||
UINT8 EntryPointLength;
|
||||
UINT8 MajorVersion;
|
||||
UINT8 MinorVersion;
|
||||
UINT16 MaxStructureSize;
|
||||
UINT8 EntryPointRevision;
|
||||
UINT8 FormattedArea[5];
|
||||
UINT8 IntermediateAnchorString[5];
|
||||
UINT8 IntermediateChecksum;
|
||||
UINT16 TableLength;
|
||||
UINT32 TableAddress;
|
||||
UINT16 NumberOfSmbiosStructures;
|
||||
UINT8 SmbiosBcdRevision;
|
||||
} SMBIOS_STRUCTURE_TABLE;
|
||||
|
||||
//
|
||||
// Please note that SMBIOS structures can be odd byte aligned since the
|
||||
// unformated section of each record is a set of arbitrary size strings.
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 Type;
|
||||
UINT8 Length;
|
||||
UINT8 Handle[2];
|
||||
} SMBIOS_HEADER;
|
||||
|
||||
typedef UINT8 SMBIOS_STRING;
|
||||
|
||||
typedef struct {
|
||||
SMBIOS_HEADER Hdr;
|
||||
SMBIOS_STRING Vendor;
|
||||
SMBIOS_STRING BiosVersion;
|
||||
UINT8 BiosSegment[2];
|
||||
SMBIOS_STRING BiosReleaseDate;
|
||||
UINT8 BiosSize;
|
||||
UINT8 BiosCharacteristics[8];
|
||||
} SMBIOS_TYPE0;
|
||||
|
||||
typedef struct {
|
||||
SMBIOS_HEADER Hdr;
|
||||
SMBIOS_STRING Manufacturer;
|
||||
SMBIOS_STRING ProductName;
|
||||
SMBIOS_STRING Version;
|
||||
SMBIOS_STRING SerialNumber;
|
||||
|
||||
//
|
||||
// always byte copy this data to prevent alignment faults!
|
||||
//
|
||||
EFI_GUID Uuid;
|
||||
|
||||
UINT8 WakeUpType;
|
||||
} SMBIOS_TYPE1;
|
||||
|
||||
typedef struct {
|
||||
SMBIOS_HEADER Hdr;
|
||||
SMBIOS_STRING Manufacturer;
|
||||
SMBIOS_STRING ProductName;
|
||||
SMBIOS_STRING Version;
|
||||
SMBIOS_STRING SerialNumber;
|
||||
} SMBIOS_TYPE2;
|
||||
|
||||
typedef struct {
|
||||
SMBIOS_HEADER Hdr;
|
||||
SMBIOS_STRING Manufacturer;
|
||||
UINT8 Type;
|
||||
SMBIOS_STRING Version;
|
||||
SMBIOS_STRING SerialNumber;
|
||||
SMBIOS_STRING AssetTag;
|
||||
UINT8 BootupState;
|
||||
UINT8 PowerSupplyState;
|
||||
UINT8 ThermalState;
|
||||
UINT8 SecurityStatus;
|
||||
UINT8 OemDefined[4];
|
||||
} SMBIOS_TYPE3;
|
||||
|
||||
typedef struct {
|
||||
SMBIOS_HEADER Hdr;
|
||||
UINT8 Socket;
|
||||
UINT8 ProcessorType;
|
||||
UINT8 ProcessorFamily;
|
||||
SMBIOS_STRING ProcessorManufacture;
|
||||
UINT8 ProcessorId[8];
|
||||
SMBIOS_STRING ProcessorVersion;
|
||||
UINT8 Voltage;
|
||||
UINT8 ExternalClock[2];
|
||||
UINT8 MaxSpeed[2];
|
||||
UINT8 CurrentSpeed[2];
|
||||
UINT8 Status;
|
||||
UINT8 ProcessorUpgrade;
|
||||
UINT8 L1CacheHandle[2];
|
||||
UINT8 L2CacheHandle[2];
|
||||
UINT8 L3CacheHandle[2];
|
||||
} SMBIOS_TYPE4;
|
||||
|
||||
typedef union {
|
||||
SMBIOS_HEADER *Hdr;
|
||||
SMBIOS_TYPE0 *Type0;
|
||||
SMBIOS_TYPE1 *Type1;
|
||||
SMBIOS_TYPE2 *Type2;
|
||||
SMBIOS_TYPE3 *Type3;
|
||||
SMBIOS_TYPE4 *Type4;
|
||||
UINT8 *Raw;
|
||||
} SMBIOS_STRUCTURE_POINTER;
|
||||
#pragma pack()
|
||||
|
||||
#include "ip.h"
|
||||
#include "dhcp.h"
|
||||
#include "tftp.h"
|
||||
|
||||
#endif /* _BC_H */
|
||||
|
||||
/* EOF - bc.h */
|
47
EdkModulePkg/Universal/Network/PxeBc/Dxe/build.xml
Normal file
47
EdkModulePkg/Universal/Network/PxeBc/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="BC"><!--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\PxeBc\Dxe"/>
|
||||
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
|
||||
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
|
||||
<target name="BC">
|
||||
<GenBuild baseName="BC" mbdFilename="${MODULE_DIR}\BC.mbd" msaFilename="${MODULE_DIR}\BC.msa"/>
|
||||
</target>
|
||||
<target depends="BC_clean" name="clean"/>
|
||||
<target depends="BC_cleanall" name="cleanall"/>
|
||||
<target name="BC_clean">
|
||||
<OutputDirSetup baseName="BC" mbdFilename="${MODULE_DIR}\BC.mbd" msaFilename="${MODULE_DIR}\BC.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\BC_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\BC_build.xml" target="clean"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
|
||||
</target>
|
||||
<target name="BC_cleanall">
|
||||
<OutputDirSetup baseName="BC" mbdFilename="${MODULE_DIR}\BC.mbd" msaFilename="${MODULE_DIR}\BC.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\BC_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\BC_build.xml" target="cleanall"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}"/>
|
||||
<delete dir="${DEST_DIR_DEBUG}"/>
|
||||
<delete>
|
||||
<fileset dir="${BIN_DIR}" includes="**BC*"/>
|
||||
</delete>
|
||||
</target>
|
||||
</project>
|
627
EdkModulePkg/Universal/Network/PxeBc/Dxe/dhcp.h
Normal file
627
EdkModulePkg/Universal/Network/PxeBc/Dxe/dhcp.h
Normal file
@@ -0,0 +1,627 @@
|
||||
/*++
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _DHCP_H
|
||||
#define _DHCP_H
|
||||
|
||||
//
|
||||
// Definitions for DHCP version 4 UDP packet.
|
||||
// The field names in this structure are defined and described in RFC 2131.
|
||||
//
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
UINT8 op;
|
||||
#define BOOTP_REQUEST 1
|
||||
#define BOOTP_REPLY 2
|
||||
|
||||
UINT8 htype;
|
||||
UINT8 hlen;
|
||||
UINT8 hops;
|
||||
UINT32 xid;
|
||||
UINT16 secs;
|
||||
UINT16 flags;
|
||||
#define DHCP_BROADCAST_FLAG 0x8000
|
||||
|
||||
UINT32 ciaddr;
|
||||
UINT32 yiaddr;
|
||||
UINT32 siaddr;
|
||||
UINT32 giaddr;
|
||||
UINT8 chaddr[16];
|
||||
UINT8 sname[64];
|
||||
UINT8 file[128];
|
||||
UINT8 options[312];
|
||||
#define OP_PAD 0
|
||||
#define OP_END 255
|
||||
#define OP_SUBNET_MASK 1
|
||||
#define OP_TIME_OFFSET 2
|
||||
#define OP_ROUTER_LIST 3
|
||||
#define OP_TIME_SERVERS 4
|
||||
#define OP_NAME_SERVERS 5
|
||||
#define OP_DNS_SERVERS 6
|
||||
#define OP_LOG_SERVERS 7
|
||||
#define OP_COOKIE_SERVERS 8
|
||||
#define OP_LPR_SREVERS 9
|
||||
#define OP_IMPRESS_SERVERS 10
|
||||
#define OP_RES_LOC_SERVERS 11
|
||||
#define OP_HOST_NAME 12
|
||||
#define OP_BOOT_FILE_SZ 13
|
||||
#define OP_DUMP_FILE 14
|
||||
#define OP_DOMAIN_NAME 15
|
||||
#define OP_SWAP_SERVER 16
|
||||
#define OP_ROOT_PATH 17
|
||||
#define OP_EXTENSION_PATH 18
|
||||
#define OP_IP_FORWARDING 19
|
||||
#define OP_NON_LOCAL_SRC_RTE 20
|
||||
#define OP_POLICY_FILTER 21
|
||||
#define OP_MAX_DATAGRAM_SZ 22
|
||||
#define OP_DEFAULT_TTL 23
|
||||
#define OP_MTU_AGING_TIMEOUT 24
|
||||
#define OP_MTU_SIZES 25
|
||||
#define OP_MTU_TO_USE 26
|
||||
#define OP_ALL_SUBNETS_LOCAL 27
|
||||
#define OP_BROADCAST_ADD 28
|
||||
#define OP_PERFORM_MASK_DISCOVERY 29
|
||||
#define OP_RESPOND_TO_MASK_REQ 30
|
||||
#define OP_PERFORM_ROUTER_DISCOVERY 31
|
||||
#define OP_ROUTER_SOLICIT_ADDRESS 32
|
||||
#define OP_STATIC_ROUTER_LIST 33
|
||||
#define OP_USE_ARP_TRAILERS 34
|
||||
#define OP_ARP_CACHE_TIMEOUT 35
|
||||
#define OP_ETHERNET_ENCAPSULATION 36
|
||||
#define OP_TCP_DEFAULT_TTL 37
|
||||
#define OP_TCP_KEEP_ALIVE_INT 38
|
||||
#define OP_KEEP_ALIVE_GARBAGE 39
|
||||
#define OP_NIS_DOMAIN_NAME 40
|
||||
#define OP_NIS_SERVERS 41
|
||||
#define OP_NTP_SERVERS 42
|
||||
#define OP_VENDOR_SPECIFIC 43
|
||||
#define VEND_PXE_MTFTP_IP 1
|
||||
#define VEND_PXE_MTFTP_CPORT 2
|
||||
#define VEND_PXE_MTFTP_SPORT 3
|
||||
#define VEND_PXE_MTFTP_TMOUT 4
|
||||
#define VEND_PXE_MTFTP_DELAY 5
|
||||
#define VEND_PXE_DISCOVERY_CONTROL 6
|
||||
#define VEND_PXE_DISCOVERY_MCAST_ADDR 7
|
||||
#define VEND_PXE_BOOT_SERVERS 8
|
||||
#define VEND_PXE_BOOT_MENU 9
|
||||
#define VEND_PXE_BOOT_PROMPT 10
|
||||
#define VEND_PXE_MCAST_ADDRS_ALLOC 11
|
||||
#define VEND_PXE_CREDENTIAL_TYPES 12
|
||||
#define VEND_PXE_BOOT_ITEM 71
|
||||
#define OP_NBNS_SERVERS 44
|
||||
#define OP_NBDD_SERVERS 45
|
||||
#define OP_NETBIOS_NODE_TYPE 46
|
||||
#define OP_NETBIOS_SCOPE 47
|
||||
#define OP_XWINDOW_SYSTEM_FONT_SERVERS 48
|
||||
#define OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS 49
|
||||
#define OP_DHCP_REQ_IP_ADD 50
|
||||
#define OP_DHCP_LEASE_TIME 51
|
||||
#define OP_DHCP_OPTION_OVERLOAD 52
|
||||
#define OVLD_FILE 1
|
||||
#define OVLD_SRVR_NAME 2
|
||||
#define OP_DHCP_MESSAGE_TYPE 53
|
||||
#define DHCPDISCOVER 1
|
||||
#define DHCPOFFER 2
|
||||
#define DHCPREQUEST 3
|
||||
#define DHCPDECLINE 4
|
||||
#define DHCPACK 5
|
||||
#define DHCPNAK 6
|
||||
#define DHCPRELEASE 7
|
||||
#define DHCPINFORM 8
|
||||
#define OP_DHCP_SERVER_IP 54
|
||||
#define OP_DHCP_PARM_REQ_LIST 55
|
||||
#define OP_DHCP_ERROR_MESSAGE 56
|
||||
#define OP_DHCP_MAX_MESSAGE_SZ 57
|
||||
#define OP_DHCP_RENEWAL_TIME 58
|
||||
#define OP_DHCP_REBINDING_TIME 59
|
||||
#define OP_DHCP_CLASS_IDENTIFIER 60
|
||||
#define OP_DHCP_CLIENT_IDENTIFIER 61
|
||||
#define OP_NISPLUS_DOMAIN_NAME 64
|
||||
#define OP_NISPLUS_SERVERS 65
|
||||
#define OP_DHCP_TFTP_SERVER_NAME 66
|
||||
#define OP_DHCP_BOOTFILE 67
|
||||
#define OP_MOBILE_IP_HOME_AGENTS 68
|
||||
#define OP_SMPT_SERVERS 69
|
||||
#define OP_POP3_SERVERS 70
|
||||
#define OP_NNTP_SERVERS 71
|
||||
#define OP_WWW_SERVERS 72
|
||||
#define OP_FINGER_SERVERS 73
|
||||
#define OP_IRC_SERVERS 74
|
||||
#define OP_STREET_TALK_SERVERS 75
|
||||
#define OP_STREET_TALK_DIR_ASSIST_SERVERS 76
|
||||
#define OP_NDS_SERVERS 85
|
||||
#define OP_NDS_TREE_NAME 86
|
||||
#define OP_NDS_CONTEXT 87
|
||||
#define OP_DHCP_SYSTEM_ARCH 93
|
||||
#define OP_DHCP_NETWORK_ARCH 94
|
||||
#define OP_DHCP_PLATFORM_ID 97
|
||||
} DHCPV4_STRUCT;
|
||||
|
||||
//
|
||||
// DHCPv4 option header
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
UINT8 Length;
|
||||
//
|
||||
// followed by Data[]
|
||||
//
|
||||
} DHCPV4_OP_HEADER;
|
||||
|
||||
//
|
||||
// Generic DHCPv4 option (header followed by data)
|
||||
//
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 Data[1];
|
||||
} DHCPV4_OP_STRUCT;
|
||||
|
||||
//
|
||||
// Maximum DHCP packet size on ethernet
|
||||
//
|
||||
#define MAX_DHCP_MSG_SZ (MAX_ENET_DATA_SIZE - sizeof (IPV4_HEADER) - sizeof (UDPV4_HEADER))
|
||||
|
||||
//
|
||||
// Macros used in pxe_bc_dhcp.c and pxe_loadfile.c
|
||||
//
|
||||
#define DHCPV4_TRANSMIT_BUFFER (*(DHCPV4_STRUCT *) (Private->TransmitBuffer))
|
||||
#define DHCPV4_OPTIONS_BUFFER (*(struct optionsstr *) DHCPV4_TRANSMIT_BUFFER.options)
|
||||
|
||||
#define DHCPV4_ACK_INDEX 0
|
||||
#define PXE_BINL_INDEX 1
|
||||
#define PXE_OFFER_INDEX 1
|
||||
#define PXE_ACK_INDEX 2
|
||||
#define PXE_BIS_INDEX 3
|
||||
|
||||
#define DHCPV4_ACK_BUFFER ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[DHCPV4_ACK_INDEX]
|
||||
#define PXE_BINL_BUFFER ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_BINL_INDEX]
|
||||
#define PXE_OFFER_BUFFER ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_OFFER_INDEX]
|
||||
#define PXE_ACK_BUFFER ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_ACK_INDEX]
|
||||
#define PXE_BIS_BUFFER ((struct DhcpReceiveBufferStruct *) Private->DhcpPacketBuffer)[PXE_BIS_INDEX]
|
||||
|
||||
#define DHCPV4_ACK_PACKET DHCPV4_ACK_BUFFER.u.Dhcpv4
|
||||
#define PXE_BINL_PACKET PXE_BINL_BUFFER.u.Dhcpv4
|
||||
#define PXE_OFFER_PACKET PXE_OFFER_BUFFER.u.Dhcpv4
|
||||
#define PXE_ACK_PACKET PXE_ACK_BUFFER.u.Dhcpv4
|
||||
#define PXE_BIS_PACKET PXE_BIS_BUFFER.u.Dhcpv4
|
||||
|
||||
//
|
||||
// network structure definitions
|
||||
//
|
||||
//
|
||||
// some option definitions
|
||||
//
|
||||
#define DHCPV4_OPTION_LENGTH(type) (sizeof (type) - sizeof (DHCPV4_OP_HEADER))
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 Type;
|
||||
} DHCPV4_OP_MESSAGE_TYPE;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 Overload;
|
||||
} DHCPV4_OP_OVERLOAD;
|
||||
|
||||
//
|
||||
// boot server list structure
|
||||
// one or more contained in a pxe boot servers structure
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 IpCount;
|
||||
EFI_IPv4_ADDRESS IpList[1]; // IP count of IPs
|
||||
} PXEV4_SERVER_LIST;
|
||||
|
||||
typedef struct {
|
||||
UINT8 IpCount;
|
||||
EFI_IPv6_ADDRESS IpList[1]; // IP count of IPs
|
||||
} PXEV6_SERVER_LIST;
|
||||
|
||||
typedef union {
|
||||
PXEV4_SERVER_LIST Ipv4List;
|
||||
PXEV6_SERVER_LIST Ipv6List;
|
||||
} PXE_SERVER_LISTS;
|
||||
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
PXE_SERVER_LISTS u;
|
||||
} PXE_SERVER_LIST;
|
||||
|
||||
//
|
||||
// pxe boot servers structure
|
||||
//
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
PXE_SERVER_LIST ServerList[1]; // one or more
|
||||
} PXE_OP_SERVER_LIST;
|
||||
|
||||
//
|
||||
// pxe boot item structure
|
||||
//
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT16 Type;
|
||||
UINT16 Layer;
|
||||
} PXE_OP_BOOT_ITEM;
|
||||
|
||||
//
|
||||
// pxe boot menu item structure
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
UINT8 DataLen;
|
||||
UINT8 Data[1];
|
||||
} PXE_BOOT_MENU_ENTRY;
|
||||
|
||||
//
|
||||
// pxe boot menu structure
|
||||
//
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
PXE_BOOT_MENU_ENTRY MenuItem[1];
|
||||
} PXE_OP_BOOT_MENU;
|
||||
|
||||
//
|
||||
// pxe boot prompt structure
|
||||
//
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 Timeout;
|
||||
UINT8 Prompt[1];
|
||||
} PXE_OP_BOOT_PROMPT;
|
||||
|
||||
#define PXE_BOOT_PROMPT_AUTO_SELECT 0
|
||||
#define PXE_BOOT_PROMPT_NO_TIMEOUT 255
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 Class[1];
|
||||
} DHCPV4_OP_CLASS;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 File[1];
|
||||
} DHCPV4_OP_BOOTFILE;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 VendorOptions[1];
|
||||
} DHCPV4_OP_VENDOR_OPTIONS;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 MaxSize[2];
|
||||
} DHCPV4_OP_MAX_MESSAGE_SIZE;
|
||||
|
||||
typedef struct {
|
||||
UINT8 _OP_SUBNET_MASK; /* 1 */
|
||||
UINT8 _OP_TIME_OFFSET; /* 2 */
|
||||
UINT8 _OP_ROUTER_LIST; /* 3 */
|
||||
UINT8 _OP_TIME_SERVERS; /* 4 */
|
||||
UINT8 _OP_NAME_SERVERS; /* 5 */
|
||||
UINT8 _OP_DNS_SERVERS; /* 6 */
|
||||
UINT8 _OP_HOST_NAME; /* 12 */
|
||||
UINT8 _OP_BOOT_FILE_SZ; /* 13 */
|
||||
UINT8 _OP_DOMAIN_NAME; /* 15 */
|
||||
UINT8 _OP_ROOT_PATH; /* 17 */
|
||||
UINT8 _OP_EXTENSION_PATH; /* 18 */
|
||||
UINT8 _OP_MAX_DATAGRAM_SZ; /* 22 */
|
||||
UINT8 _OP_DEFAULT_TTL; /* 23 */
|
||||
UINT8 _OP_BROADCAST_ADD; /* 28 */
|
||||
UINT8 _OP_NIS_DOMAIN_NAME; /* 40 */
|
||||
UINT8 _OP_NIS_SERVERS; /* 41 */
|
||||
UINT8 _OP_NTP_SERVERS; /* 42 */
|
||||
UINT8 _OP_VENDOR_SPECIFIC; /* 43 */
|
||||
UINT8 _OP_DHCP_REQ_IP_ADD; /* 50 */
|
||||
UINT8 _OP_DHCP_LEASE_TIME; /* 51 */
|
||||
UINT8 _OP_DHCP_SERVER_IP; /* 54 */
|
||||
UINT8 _OP_DHCP_RENEWAL_TIME; /* 58 */
|
||||
UINT8 _OP_DHCP_REBINDING_TIME; /* 59 */
|
||||
UINT8 _OP_DHCP_CLASS_IDENTIFIER; /* 60 */
|
||||
UINT8 _OP_DHCP_TFTP_SERVER_NAME; /* 66 */
|
||||
UINT8 _OP_DHCP_BOOTFILE; /* 67 */
|
||||
UINT8 _OP_DHCP_PLATFORM_ID; /* 97 */
|
||||
UINT8 VendorOption128; // vendor option 128
|
||||
UINT8 VendorOption129; // vendor option 129
|
||||
UINT8 VendorOption130; // vendor option 130
|
||||
UINT8 VendorOption131; // vendor option 131
|
||||
UINT8 VendorOption132; // vendor option 132
|
||||
UINT8 VendorOption133; // vendor option 133
|
||||
UINT8 VendorOption134; // vendor option 134
|
||||
UINT8 VendorOption135; // vendor option 135
|
||||
} DHCPV4_REQUESTED_OPTIONS_DATA;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
DHCPV4_REQUESTED_OPTIONS_DATA Data;
|
||||
} DHCPV4_OP_REQUESTED_OPTIONS;
|
||||
|
||||
typedef struct opipstr {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
EFI_IPv4_ADDRESS Ip;
|
||||
} DHCPV4_OP_IP_ADDRESS;
|
||||
|
||||
//
|
||||
// ip list structure - e.g. router list
|
||||
//
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
EFI_IPv4_ADDRESS IpList[1];
|
||||
} DHCPV4_OP_IP_LIST;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 Type;
|
||||
UINT8 Guid[sizeof (EFI_GUID)];
|
||||
} DHCPV4_OP_CLIENT_ID;
|
||||
|
||||
//
|
||||
// special options start - someday obsolete ???
|
||||
//
|
||||
#define DHCPV4_OP_PLATFORM_ID DHCPV4_OP_CLIENT_ID
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 Type; // SNP = 2
|
||||
UINT8 MajorVersion;
|
||||
UINT8 MinorVersion;
|
||||
} DHCPV4_OP_NETWORK_INTERFACE;
|
||||
|
||||
#define UNDI_TYPE 1
|
||||
#define SNP_TYPE 2
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT16 Type;
|
||||
} DHCPV4_OP_ARCHITECTURE_TYPE;
|
||||
//
|
||||
// special options end - someday obsolete ???
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 ClassIdentifier[10]; // PXEClient:
|
||||
UINT8 Lit2[5]; // Arch:
|
||||
UINT8 ArchitectureType[5]; // 00000 - 65536
|
||||
UINT8 Lit3[1]; // :
|
||||
UINT8 InterfaceName[4]; // e.g. UNDI
|
||||
UINT8 Lit4[1]; // :
|
||||
UINT8 UndiMajor[3]; // 000 - 255
|
||||
UINT8 UndiMinor[3]; // 000 - 255
|
||||
} DHCPV4_CLASS_ID_DATA;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
DHCPV4_CLASS_ID_DATA Data;
|
||||
} DHCPV4_OP_CLASS_ID;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
EFI_IPv4_ADDRESS Ip;
|
||||
} DHCPV4_OP_REQUESTED_IP;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
EFI_IPv4_ADDRESS Ip;
|
||||
} DHCPV4_OP_SERVER_IP;
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
EFI_IPv4_ADDRESS Ip;
|
||||
} DHCPV4_OP_SUBNET_MASK;
|
||||
|
||||
typedef struct { // oppxedisctlstr {
|
||||
DHCPV4_OP_HEADER Header;
|
||||
UINT8 ControlBits;
|
||||
} PXE_OP_DISCOVERY_CONTROL;
|
||||
|
||||
#define DISABLE_BCAST (1 << 0)
|
||||
#define DISABLE_MCAST (1 << 1)
|
||||
#define USE_ACCEPT_LIST (1 << 2)
|
||||
#define USE_BOOTFILE (1 << 3)
|
||||
|
||||
#pragma pack()
|
||||
//
|
||||
// definitions of indices to populate option interest array
|
||||
//
|
||||
#define VEND_PXE_MTFTP_IP_IX 1 // multicast IP address of bootfile for MTFTP listen
|
||||
#define VEND_PXE_MTFTP_CPORT_IX 2 // UDP Port to monitor for MTFTP responses - Intel order
|
||||
#define VEND_PXE_MTFTP_SPORT_IX 3 // Server UDP Port for MTFTP open - Intel order
|
||||
#define VEND_PXE_MTFTP_TMOUT_IX 4 // Listen timeout - secs
|
||||
#define VEND_PXE_MTFTP_DELAY_IX 5 // Transmission timeout - secs
|
||||
#define VEND_PXE_DISCOVERY_CONTROL_IX 6 // bit field
|
||||
#define VEND_PXE_DISCOVERY_MCAST_ADDR_IX 7 // boot server discovery multicast address
|
||||
#define VEND_PXE_BOOT_SERVERS_IX 8 // list of boot servers of form tp(2) cnt(1) ips[cnt]
|
||||
#define VEND_PXE_BOOT_MENU_IX 9
|
||||
#define VEND_PXE_BOOT_PROMPT_IX 10
|
||||
#define VEND_PXE_MCAST_ADDRS_ALLOC_IX 0 // not used by PXE client
|
||||
#define VEND_PXE_CREDENTIAL_TYPES_IX 11
|
||||
#define VEND_13_IX 0 // not used by PXE client
|
||||
#define VEND_14_IX 0 // not used by PXE client
|
||||
#define VEND_15_IX 0 // not used by PXE client
|
||||
#define VEND_16_IX 0 // not used by PXE client
|
||||
#define VEND_17_IX 0 // not used by PXE client
|
||||
#define VEND_18_IX 0 // not used by PXE client
|
||||
#define VEND_19_IX 0 // not used by PXE client
|
||||
#define VEND_20_IX 0 // not used by PXE client
|
||||
#define VEND_21_IX 0 // not used by PXE client
|
||||
#define VEND_22_IX 0 // not used by PXE client
|
||||
#define VEND_23_IX 0 // not used by PXE client
|
||||
#define VEND_24_IX 0 // not used by PXE client
|
||||
#define VEND_25_IX 0 // not used by PXE client
|
||||
#define VEND_26_IX 0 // not used by PXE client
|
||||
#define VEND_27_IX 0 // not used by PXE client
|
||||
#define VEND_28_IX 0 // not used by PXE client
|
||||
#define VEND_29_IX 0 // not used by PXE client
|
||||
#define VEND_30_IX 0 // not used by PXE client
|
||||
#define VEND_31_IX 0 // not used by PXE client
|
||||
#define VEND_32_IX 0 // not used by PXE client
|
||||
#define VEND_33_IX 0 // not used by PXE client
|
||||
#define VEND_34_IX 0 // not used by PXE client
|
||||
#define VEND_35_IX 0 // not used by PXE client
|
||||
#define VEND_36_IX 0 // not used by PXE client
|
||||
#define VEND_37_IX 0 // not used by PXE client
|
||||
#define VEND_38_IX 0 // not used by PXE client
|
||||
#define VEND_39_IX 0 // not used by PXE client
|
||||
#define VEND_40_IX 0 // not used by PXE client
|
||||
#define VEND_41_IX 0 // not used by PXE client
|
||||
#define VEND_42_IX 0 // not used by PXE client
|
||||
#define VEND_43_IX 0 // not used by PXE client
|
||||
#define VEND_44_IX 0 // not used by PXE client
|
||||
#define VEND_45_IX 0 // not used by PXE client
|
||||
#define VEND_46_IX 0 // not used by PXE client
|
||||
#define VEND_47_IX 0 // not used by PXE client
|
||||
#define VEND_48_IX 0 // not used by PXE client
|
||||
#define VEND_49_IX 0 // not used by PXE client
|
||||
#define VEND_50_IX 0 // not used by PXE client
|
||||
#define VEND_51_IX 0 // not used by PXE client
|
||||
#define VEND_52_IX 0 // not used by PXE client
|
||||
#define VEND_53_IX 0 // not used by PXE client
|
||||
#define VEND_54_IX 0 // not used by PXE client
|
||||
#define VEND_55_IX 0 // not used by PXE client
|
||||
#define VEND_56_IX 0 // not used by PXE client
|
||||
#define VEND_57_IX 0 // not used by PXE client
|
||||
#define VEND_58_IX 0 // not used by PXE client
|
||||
#define VEND_59_IX 0 // not used by PXE client
|
||||
#define VEND_60_IX 0 // not used by PXE client
|
||||
#define VEND_61_IX 0 // not used by PXE client
|
||||
#define VEND_62_IX 0 // not used by PXE client
|
||||
#define VEND_63_IX 0 // not used by PXE client
|
||||
#define VEND_64_IX 0 // not used by PXE client
|
||||
#define VEND_65_IX 0 // not used by PXE client
|
||||
#define VEND_66_IX 0 // not used by PXE client
|
||||
#define VEND_67_IX 0 // not used by PXE client
|
||||
#define VEND_68_IX 0 // not used by PXE client
|
||||
#define VEND_69_IX 0 // not used by PXE client
|
||||
#define VEND_70_IX 0 // not used by PXE client
|
||||
#define VEND_PXE_BOOT_ITEM_IX 12
|
||||
|
||||
#define MAX_OUR_PXE_OPT VEND_PXE_BOOT_ITEM // largest PXE option in which we are interested
|
||||
#define MAX_OUR_PXE_IX VEND_PXE_BOOT_ITEM_IX // largest PXE option index
|
||||
//
|
||||
// define various types by options that are sent
|
||||
//
|
||||
#define WfM11a_OPTS ((1<<VEND_PXE_MTFTP_IP_IX) | \
|
||||
(1<<VEND_PXE_MTFTP_CPORT_IX) | \
|
||||
(1<<VEND_PXE_MTFTP_SPORT_IX) | \
|
||||
(1<<VEND_PXE_MTFTP_TMOUT_IX) | \
|
||||
(1<<VEND_PXE_MTFTP_DELAY_IX))
|
||||
|
||||
#define DISCOVER_OPTS ((1<<VEND_PXE_DISCOVERY_CONTROL_IX) | \
|
||||
(1<<VEND_PXE_DISCOVERY_MCAST_ADDR_IX) | \
|
||||
(1<<VEND_PXE_BOOT_SERVERS_IX) | \
|
||||
(1<<VEND_PXE_BOOT_MENU_IX) | \
|
||||
(1<<VEND_PXE_BOOT_PROMPT_IX) | \
|
||||
(1<<VEND_PXE_BOOT_ITEM_IX))
|
||||
|
||||
#define CREDENTIALS_OPT (1 << VEND_PXE_CREDENTIAL_TYPES_IX)
|
||||
|
||||
//
|
||||
// definitions of indices to populate option interest array
|
||||
//
|
||||
#define OP_SUBNET_MASK_IX 1
|
||||
#define OP_TIME_OFFSET_IX 0 // not used by PXE client
|
||||
#define OP_ROUTER_LIST_IX 2
|
||||
#define OP_TIME_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_NAME_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_DNS_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_LOG_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_COOKIE_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_LPR_SREVERS_IX 0 // not used by PXE client
|
||||
#define OP_IMPRESS_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_RES_LOC_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_HOST_NAME_IX 0 // not used by PXE client
|
||||
#define OP_BOOT_FILE_SZ_IX 9
|
||||
#define OP_DUMP_FILE_IX 0 // not used by PXE client
|
||||
#define OP_DOMAIN_NAME_IX 0 // not used by PXE client
|
||||
#define OP_SWAP_SERVER_IX 0 // not used by PXE client
|
||||
#define OP_ROOT_PATH_IX 0 // not used by PXE client
|
||||
#define OP_EXTENSION_PATH_IX 0 // not used by PXE client
|
||||
#define OP_IP_FORWARDING_IX 0 // not used by PXE client
|
||||
#define OP_NON_LOCAL_SRC_RTE_IX 0 // not used by PXE client
|
||||
#define OP_POLICY_FILTER_IX 0 // not used by PXE client
|
||||
#define OP_MAX_DATAGRAM_SZ_IX 0 // not used by PXE client
|
||||
#define OP_DEFAULT_TTL_IX 0 // not used by PXE client
|
||||
#define OP_MTU_AGING_TIMEOUT_IX 0 // not used by PXE client
|
||||
#define OP_MTU_SIZES_IX 0 // not used by PXE client
|
||||
#define OP_MTU_TO_USE_IX 0 // not used by PXE client
|
||||
#define OP_ALL_SUBNETS_LOCAL_IX 0 // not used by PXE client
|
||||
#define OP_BROADCAST_ADD_IX 0 // not used by PXE client
|
||||
#define OP_PERFORM_MASK_DISCOVERY_IX 0 // not used by PXE client
|
||||
#define OP_RESPOND_TO_MASK_REQ_IX 0 // not used by PXE client
|
||||
#define OP_PERFORM_ROUTER_DISCOVERY_IX 0 // not used by PXE client
|
||||
#define OP_ROUTER_SOLICIT_ADDRESS_IX 0 // not used by PXE client
|
||||
#define OP_STATIC_ROUTER_LIST_IX 0 // not used by PXE client
|
||||
#define OP_USE_ARP_TRAILERS_IX 0 // not used by PXE client
|
||||
#define OP_ARP_CACHE_TIMEOUT_IX 0 // not used by PXE client
|
||||
#define OP_ETHERNET_ENCAPSULATION_IX 0 // not used by PXE client
|
||||
#define OP_TCP_DEFAULT_TTL_IX 0 // not used by PXE client
|
||||
#define OP_TCP_KEEP_ALIVE_INT_IX 0 // not used by PXE client
|
||||
#define OP_KEEP_ALIVE_GARBAGE_IX 0 // not used by PXE client
|
||||
#define OP_NIS_DOMAIN_NAME_IX 0 // not used by PXE client
|
||||
#define OP_NIS_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_NTP_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_VENDOR_SPECIFIC_IX 3
|
||||
#define OP_NBNS_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_NBDD_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_NETBIOS_NODE_TYPE_IX 0 // not used by PXE client
|
||||
#define OP_NETBIOS_SCOPE_IX 0 // not used by PXE client
|
||||
#define OP_XWINDOW_SYSTEM_FONT_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_XWINDOW_SYSTEM_DISPLAY_MANAGERS_IX 0 // not used by PXE client
|
||||
// DHCP option indices
|
||||
//
|
||||
#define OP_DHCP_REQ_IP_ADD_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_LEASE_TIME_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_OPTION_OVERLOAD_IX 4
|
||||
#define OP_DHCP_MESSAGE_TYPE_IX 5
|
||||
#define OP_DHCP_SERVER_IP_IX 6
|
||||
#define OP_DHCP_PARM_REQ_LIST_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_ERROR_MESSAGE_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_MAX_MESSAGE_SZ_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_RENEWAL_TIME_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_REBINDING_TIME_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_CLASS_IDENTIFIER_IX 7
|
||||
#define OP_DHCP_CLIENT_IDENTIFIER_IX 0 // not used by PXE client
|
||||
#define OP_RESERVED62_IX 0 // not used by PXE client
|
||||
#define OP_RESERVED63_IX 0 // not used by PXE client
|
||||
#define OP_NISPLUS_DOMAIN_NAME_IX 0 // not used by PXE client
|
||||
#define OP_NISPLUS_SERVERS_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_TFTP_SERVER_NAME_IX 0 // not used by PXE client
|
||||
#define OP_DHCP_BOOTFILE_IX 8
|
||||
|
||||
#define MAX_OUR_OPT OP_DHCP_BOOTFILE // largest option in which we are interested
|
||||
#define MAX_OUR_IX OP_BOOT_FILE_SZ_IX
|
||||
|
||||
typedef struct {
|
||||
DHCPV4_OP_STRUCT *PktOptAdds[MAX_OUR_IX];
|
||||
DHCPV4_OP_STRUCT *PxeOptAdds[MAX_OUR_PXE_IX];
|
||||
UINT8 Status;
|
||||
} OPTION_POINTERS;
|
||||
|
||||
typedef struct DhcpReceiveBufferStruct {
|
||||
union {
|
||||
UINT8 ReceiveBuffer[MAX_DHCP_MSG_SZ];
|
||||
DHCPV4_STRUCT Dhcpv4;
|
||||
} u;
|
||||
|
||||
OPTION_POINTERS OpAdds;
|
||||
} DHCP_RECEIVE_BUFFER;
|
||||
|
||||
#define PXE_TYPE (1 << 0)
|
||||
#define WfM11a_TYPE (1 << 1)
|
||||
#define DISCOVER_TYPE (1 << 2)
|
||||
#define CREDENTIALS_TYPE (1 << 3)
|
||||
#define USE_THREE_BYTE (1 << 4)
|
||||
|
||||
#endif // _DHCP_H
|
||||
|
||||
/* EOF - dhcp.h */
|
42
EdkModulePkg/Universal/Network/PxeBc/Dxe/hton.h
Normal file
42
EdkModulePkg/Universal/Network/PxeBc/Dxe/hton.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
hton.h
|
||||
|
||||
Abstract:
|
||||
Byte swapping macros.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _HTON_H_
|
||||
#define _HTON_H_
|
||||
|
||||
//
|
||||
// Only Intel order functions are defined at this time.
|
||||
//
|
||||
#define HTONS(v) (UINT16) ((((v) << 8) & 0xff00) + (((v) >> 8) & 0x00ff))
|
||||
|
||||
#define HTONL(v) \
|
||||
(UINT32) ((((v) << 24) & 0xff000000) + (((v) << 8) & 0x00ff0000) + (((v) >> 8) & 0x0000ff00) + (((v) >> 24) & 0x000000ff))
|
||||
|
||||
#define HTONLL(v) swap64 (v)
|
||||
|
||||
#define U8PTR(na) ((UINT8 *) &(na))
|
||||
|
||||
#define NTOHS(ns) ((UINT16) (((*U8PTR (ns)) << 8) +*(U8PTR (ns) + 1)))
|
||||
|
||||
#define NTOHL(ns) \
|
||||
((UINT32) (((*U8PTR (ns)) << 24) + ((*(U8PTR (ns) + 1)) << 16) + ((*(U8PTR (ns) + 2)) << 8) +*(U8PTR (ns) + 3)))
|
||||
|
||||
#endif /* _HTON_H_ */
|
||||
|
||||
/* EOF - hton.h */
|
741
EdkModulePkg/Universal/Network/PxeBc/Dxe/ip.h
Normal file
741
EdkModulePkg/Universal/Network/PxeBc/Dxe/ip.h
Normal file
@@ -0,0 +1,741 @@
|
||||
/*++
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _IP_H_
|
||||
#define _IP_H_
|
||||
|
||||
#include "hton.h"
|
||||
|
||||
//
|
||||
// Client architecture types
|
||||
//
|
||||
#define IA64 2
|
||||
#define SYS_ARCH_EFI32 6
|
||||
|
||||
//
|
||||
// portability macros
|
||||
//
|
||||
#define UDP_FILTER_MASK (EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | \
|
||||
EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT | \
|
||||
EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP | \
|
||||
EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT | \
|
||||
EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER \
|
||||
)
|
||||
|
||||
#define PXE_BOOT_LAYER_MASK 0x7FFF
|
||||
#define PXE_BOOT_LAYER_INITIAL 0x0000
|
||||
#define PXE_BOOT_LAYER_CREDENTIAL_FLAG 0x8000
|
||||
#define MAX_BOOT_SERVERS 32
|
||||
|
||||
//
|
||||
// macro to evaluate IP address as TRUE if it is a multicast IP address
|
||||
//
|
||||
#define IS_MULTICAST(ptr) ((*((UINT8 *) ptr) & 0xf0) == 0xe0)
|
||||
|
||||
//
|
||||
// length macros
|
||||
//
|
||||
#define IP_ADDRESS_LENGTH(qp) (((qp)->UsingIpv6) ? sizeof (EFI_IPv6_ADDRESS) : sizeof (EFI_IPv4_ADDRESS))
|
||||
|
||||
#define MAX_FRAME_DATA_SIZE 1488
|
||||
#define ALLOCATE_SIZE(X) (((X) + 7) & 0xfff8)
|
||||
#define MODE_ALLOCATE_SIZE ALLOCATE_SIZE (sizeof (EFI_PXE_BASE_CODE_MODE))
|
||||
#define BUFFER_ALLOCATE_SIZE (8192 + 512)
|
||||
#define ROUTER_ALLOCATE_SIZE ALLOCATE_SIZE ((sizeof (EFI_PXE_BASE_CODE_ROUTE_ENTRY) * PXE_ROUTER_TABLE_SIZE))
|
||||
#define ARP_ALLOCATE_SIZE ALLOCATE_SIZE ((sizeof (EFI_PXE_BASE_CODE_ARP_ENTRY) * PXE_ARP_CACHE_SIZE))
|
||||
#define FILTER_ALLOCATE_SIZE ALLOCATE_SIZE ((sizeof (EFI_IP_ADDRESS) * PXE_IP_FILTER_SIZE))
|
||||
#define PXE_ARP_CACHE_SIZE 8
|
||||
#define PXE_ROUTER_TABLE_SIZE 8
|
||||
#define PXE_IP_FILTER_SIZE 8
|
||||
#define ICMP_ALLOCATE_SIZE ALLOCATE_SIZE (sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR))
|
||||
#define TFTP_ERR_ALLOCATE_SIZE ALLOCATE_SIZE (sizeof (EFI_PXE_BASE_CODE_TFTP_ERROR))
|
||||
|
||||
//
|
||||
// DHCP discover/request packets are sent to this UDP port. ProxyDHCP
|
||||
// servers listen on this port for DHCP discover packets that have a
|
||||
// class identifier (option 60) with 'PXEClient' in the first 9 bytes.
|
||||
// Bootservers also listen on this port for PXE broadcast discover
|
||||
// requests from PXE clients.
|
||||
//
|
||||
#define DHCP_SERVER_PORT 67
|
||||
|
||||
//
|
||||
// When DHCP, proxyDHCP and Bootservers respond to DHCP and PXE broadcast
|
||||
// discover requests by broadcasting the reply packet, the packet is
|
||||
// broadcast to this port.
|
||||
//
|
||||
#define DHCP_CLIENT_PORT 68
|
||||
|
||||
//
|
||||
// TFTP servers listen for TFTP open requests on this port.
|
||||
//
|
||||
#define TFTP_OPEN_PORT 69
|
||||
|
||||
//
|
||||
// proxyDHCP and Bootservers listen on this port for a PXE unicast and/or
|
||||
// multicast discover requests from PXE clients. A PXE discover request
|
||||
// looks like a DHCP discover or DHCP request packet.
|
||||
//
|
||||
#define PXE_DISCOVERY_PORT 4011
|
||||
|
||||
//
|
||||
// This port is used by the PXE client/server protocol tests.
|
||||
//
|
||||
#define PXE_PORT_PXETEST_PORT 0x8080
|
||||
|
||||
//
|
||||
// Definitions for Ethertype protocol numbers and interface types
|
||||
// Per RFC 1700,
|
||||
//
|
||||
#define PXE_PROTOCOL_ETHERNET_IP 0x0800
|
||||
#define PXE_PROTOCOL_ETHERNET_ARP 0x0806
|
||||
#define PXE_PROTOCOL_ETHERNET_RARP 0x8035
|
||||
|
||||
#define PXE_IFTYPE_ETHERNET 0x01
|
||||
#define PXE_IFTYPE_TOKENRING 0x04
|
||||
#define PXE_IFTYPE_FIBRE_CHANNEL 0x12
|
||||
|
||||
//
|
||||
// Definitions for internet protocol version 4 header
|
||||
// Per RFC 791, September 1981.
|
||||
//
|
||||
#define IPVER4 4
|
||||
|
||||
#pragma pack(1) // make network structures packed byte alignment
|
||||
typedef union {
|
||||
UINT8 B[4];
|
||||
UINT32 L;
|
||||
} IPV4_ADDR;
|
||||
|
||||
#define IPV4_HEADER_LENGTH(IpHeaderPtr) (((IpHeaderPtr)->VersionIhl & 0xf) << 2)
|
||||
|
||||
#define SET_IPV4_VER_HDL(IpHeaderPtr, IpHeaderLen) { \
|
||||
(IpHeaderPtr)->VersionIhl = (UINT8) ((IPVER4 << 4) | ((IpHeaderLen) >> 2)); \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
UINT8 VersionIhl;
|
||||
UINT8 TypeOfService;
|
||||
UINT16 TotalLength;
|
||||
UINT16 Id;
|
||||
UINT16 FragmentFields;
|
||||
UINT8 TimeToLive;
|
||||
UINT8 Protocol;
|
||||
UINT16 HeaderChecksum;
|
||||
IPV4_ADDR SrcAddr;
|
||||
IPV4_ADDR DestAddr;
|
||||
//
|
||||
// options are not implemented
|
||||
//
|
||||
} IPV4_HEADER;
|
||||
|
||||
#define IP_FRAG_RSVD 0x8000 // reserved bit - must be zero
|
||||
#define IP_NO_FRAG 0x4000 // do not fragment bit
|
||||
#define IP_MORE_FRAG 0x2000 // not last fragment
|
||||
#define IP_FRAG_OFF_MSK 0x1fff // fragment offset in 8 byte chunks
|
||||
#define DEFAULT_RFC_TTL 64
|
||||
|
||||
#define PROT_ICMP 1
|
||||
#define PROT_IGMP 2
|
||||
#define PROT_TCP 6
|
||||
#define PROT_UDP 17
|
||||
|
||||
/*
|
||||
* Definitions for internet control message protocol version 4 message
|
||||
* structure. Per RFC 792, September 1981.
|
||||
*/
|
||||
|
||||
//
|
||||
// icmp header for all icmp messages
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 Type; // message type
|
||||
UINT8 Code; // type specific - 0 for types we implement
|
||||
UINT16 Checksum; // ones complement of ones complement sum of 16 bit words of message
|
||||
} ICMPV4_HEADER;
|
||||
|
||||
#define ICMP_DEST_UNREACHABLE 3
|
||||
#define ICMP_SOURCE_QUENCH 4
|
||||
#define ICMP_REDIRECT 5
|
||||
#define ICMP_ECHO 8
|
||||
#define ICMP_ECHO_REPLY 0
|
||||
#define ICMP_ROUTER_ADV 9
|
||||
#define ICMP_ROUTER_SOLICIT 10
|
||||
#define ICMP_TIME_EXCEEDED 11
|
||||
#define ICMP_PARAMETER_PROBLEM 12
|
||||
#define ICMP_TIMESTAMP 13
|
||||
#define ICMP_TIMESTAMP_REPLY 14
|
||||
#define ICMP_INFO_REQ 15
|
||||
#define ICMP_INFO_REQ_REPLY 16
|
||||
#define ICMP_SUBNET_MASK_REQ 17
|
||||
#define ICMP_SUBNET_MASK_REPLY 18
|
||||
//
|
||||
// other ICMP message types ignored in this implementation
|
||||
//
|
||||
// icmp general messages
|
||||
//
|
||||
typedef struct {
|
||||
ICMPV4_HEADER Header;
|
||||
//
|
||||
// generally unused except byte [0] for
|
||||
// parameter problem message
|
||||
//
|
||||
UINT8 GenerallyUnused[4];
|
||||
//
|
||||
// original message ip header of plus 64
|
||||
// bits of data
|
||||
//
|
||||
IPV4_HEADER IpHeader;
|
||||
} ICMPV4_GENERAL_MESSAGE;
|
||||
|
||||
//
|
||||
// icmp req/rply message header
|
||||
//
|
||||
typedef struct {
|
||||
ICMPV4_HEADER Header;
|
||||
UINT16 Id;
|
||||
UINT16 SequenceNumber;
|
||||
} ICMPV4_REQUEST_REPLY_HEADER;
|
||||
|
||||
//
|
||||
// icmp echo message
|
||||
//
|
||||
typedef struct {
|
||||
ICMPV4_REQUEST_REPLY_HEADER Header;
|
||||
UINT8 EchoData[1]; // variable length data to be echoed
|
||||
} ICMPV4_ECHO_MESSAGE;
|
||||
|
||||
//
|
||||
// icmp timestamp message - times are milliseconds since midnight UT -
|
||||
// if non std, set high order bit
|
||||
//
|
||||
typedef struct {
|
||||
ICMPV4_REQUEST_REPLY_HEADER Header;
|
||||
UINT32 OriginalTime; // originating timestamp
|
||||
UINT32 ReceiveTime; // receiving timestamp
|
||||
UINT32 TransmitTime; // transmitting timestamp
|
||||
} ICMPV4_TIMESTAMP_MESSAGE;
|
||||
|
||||
//
|
||||
// icmp info request structure - fill in source and dest net ip address on reply
|
||||
//
|
||||
typedef struct {
|
||||
ICMPV4_REQUEST_REPLY_HEADER Header;
|
||||
} ICMPV4_INFO_MESSAGE;
|
||||
|
||||
//
|
||||
// Definitions for internet control message protocol version 4 message structure
|
||||
// Router discovery
|
||||
// Per RFC 1256, September 1991.
|
||||
//
|
||||
//
|
||||
// icmp router advertisement message
|
||||
//
|
||||
typedef struct {
|
||||
ICMPV4_HEADER Header;
|
||||
UINT8 NumberEntries; // number of address entries
|
||||
UINT8 EntrySize; // number of 32 bit words per address entry
|
||||
UINT16 Lifetime; // seconds to consider info valid
|
||||
UINT32 RouterIp;
|
||||
UINT32 Preferance;
|
||||
} ICMPV4_ROUTER_ADVERTISE_MESSAGE;
|
||||
|
||||
//
|
||||
// icmp router solicitation message
|
||||
//
|
||||
typedef struct {
|
||||
ICMPV4_HEADER Header;
|
||||
UINT32 Reserved;
|
||||
} ICMPV4_ROUTER_SOLICIT_MESSAGE;
|
||||
|
||||
#define MAX_SOLICITATION_DELAY 1 // 1 second
|
||||
#define SOLICITATION_INTERVAL 3 // 3 seconds
|
||||
#define MAX_SOLICITATIONS 3 // 3 transmissions
|
||||
#define V1ROUTER_PRESENT_TIMEOUT 400 // 400 second timeout until v2 reports can be sent
|
||||
#define UNSOLICITED_REPORT_INTERVAL 10 // 10 seconds between unsolicited reports
|
||||
#define BROADCAST_IPv4 0xffffffff
|
||||
|
||||
//
|
||||
// Definitions for address resolution protocol message structure
|
||||
// Per RFC 826, November 1982
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 HwType; // hardware type - e.g. ethernet (1)
|
||||
UINT16 ProtType; // protocol type - for ethernet, 0x800 for IP
|
||||
UINT8 HwAddLen; // byte length of a hardware address (e.g. 6 for ethernet)
|
||||
UINT8 ProtAddLen; // byte length of a protocol address (e.g. 4 for ipv4)
|
||||
UINT16 OpCode;
|
||||
//
|
||||
// source and dest hw and prot addresses follow - see example below
|
||||
//
|
||||
} ARP_HEADER;
|
||||
|
||||
#define ETHERNET_ADD_SPC 1
|
||||
|
||||
#define ETHER_TYPE_IP 0x800
|
||||
|
||||
#define ARP_REQUEST 1
|
||||
#define ARP_REPLY 2
|
||||
|
||||
//
|
||||
// generic ARP packet
|
||||
//
|
||||
typedef struct {
|
||||
ARP_HEADER ArpHeader;
|
||||
EFI_MAC_ADDRESS SrcHardwareAddr;
|
||||
EFI_IP_ADDRESS SrcProtocolAddr;
|
||||
EFI_MAC_ADDRESS DestHardwareAddr;
|
||||
EFI_IP_ADDRESS DestProtocolAddr;
|
||||
} ARP_PACKET;
|
||||
|
||||
#define ENET_HWADDLEN 6
|
||||
#define IPV4_PROTADDLEN 4
|
||||
|
||||
//
|
||||
// Definitions for user datagram protocol version 4 pseudo header & header
|
||||
// Per RFC 768, 28 August 1980
|
||||
//
|
||||
typedef struct {
|
||||
IPV4_ADDR SrcAddr; // source ip address
|
||||
IPV4_ADDR DestAddr; // dest ip address
|
||||
UINT8 Zero; // 0
|
||||
UINT8 Protocol; // protocol
|
||||
UINT16 TotalLength; // UDP length - sizeof udpv4hdr + data length
|
||||
} UDPV4_PSEUDO_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT16 SrcPort; // source port identifier
|
||||
UINT16 DestPort; // destination port identifier
|
||||
UINT16 TotalLength; // total length header plus data
|
||||
//
|
||||
// ones complement of ones complement sum of 16 bit
|
||||
// words of pseudo header, UDP header, and data
|
||||
// zero checksum is transmitted as -0 (ones comp)
|
||||
// zero transmitted means checksum not computed
|
||||
// data follows
|
||||
//
|
||||
UINT16 Checksum;
|
||||
} UDPV4_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UDPV4_PSEUDO_HEADER Udpv4PseudoHeader;
|
||||
UDPV4_HEADER Udpv4Header;
|
||||
} UDPV4_HEADERS;
|
||||
|
||||
//
|
||||
// Definitions for transmission control protocol header
|
||||
// Per RFC 793, September, 1981
|
||||
//
|
||||
typedef struct {
|
||||
IPV4_ADDR SrcAddr; // source ip address
|
||||
IPV4_ADDR DestAddr; // dest ip address
|
||||
UINT8 Zero; // 0
|
||||
UINT8 Protocol; // protocol
|
||||
UINT16 TotalLength; // TCP length - TCP header length + data length
|
||||
} TCPV4_PSEUDO_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT16 SrcPort; // source port identifier
|
||||
UINT16 DestPort; // destination port identifier
|
||||
UINT32 SeqNumber; // Sequence number
|
||||
UINT32 AckNumber; // Acknowledgement Number
|
||||
//
|
||||
// Nibble of HLEN (length of header in 32-bit multiples)
|
||||
// 6bits of RESERVED
|
||||
// Nibble of Code Bits
|
||||
//
|
||||
UINT16 HlenResCode;
|
||||
UINT16 Window; // Software buffer size (sliding window size) in network-standard byte order
|
||||
//
|
||||
// ones complement of ones complement sum of 16 bit words of
|
||||
// pseudo header, TCP header, and data
|
||||
// zero checksum is transmitted as -0 (ones comp)
|
||||
// zero transmitted means checksum not computed
|
||||
//
|
||||
UINT16 Checksum;
|
||||
UINT16 UrgentPointer; // pointer to urgent data (allows sender to specify urgent data)
|
||||
} TCPV4_HEADER;
|
||||
|
||||
typedef struct {
|
||||
TCPV4_PSEUDO_HEADER Tcpv4PseudoHeader;
|
||||
TCPV4_HEADER Tcpv4Header;
|
||||
} TCPV4_HEADERS;
|
||||
|
||||
typedef struct {
|
||||
UINT8 Kind; // one of the following:
|
||||
UINT8 Length; // total option length including Kind and Lth
|
||||
UINT8 Data[1]; // length = Lth - 2
|
||||
} TCPV4_OPTION;
|
||||
|
||||
#define TCP_OP_END 0 // only used to pad to end of TCP header
|
||||
#define TCP_NOP 1 // optional - may be used to pad between options to get alignment
|
||||
#define TCP_MAX_SEG 2 // maximum receive segment size - only send at initial connection request
|
||||
#define MAX_MEDIA_HDR_SIZE 64
|
||||
#define MIN_ENET_DATA_SIZE 64
|
||||
#define MAX_ENET_DATA_SIZE 1500 // temp def - make a network based var
|
||||
#define MAX_IPV4_PKT_SIZE 65535 // maximum IP packet size
|
||||
#define MAX_IPV4_DATA_SIZE (MAX_IPV4_PKT_SIZE - sizeof (IPV4_HEADER))
|
||||
#define MAX_IPV4_FRAME_DATA_SIZE (MAX_FRAME_DATA_SIZE - sizeof (IPV4_HEADER))
|
||||
#define REAS_IPV4_PKT_SIZE 576 // minimum IP packet size all IP host can handle
|
||||
#define REAS_IPV4_DATA_SIZE (REAS_IPV4_PKT_SIZE - sizeof (IPV4_HEADER))
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
typedef union {
|
||||
UINT8 Data[MAX_ENET_DATA_SIZE];
|
||||
ICMPV4_HEADER IcmpHeader;
|
||||
IGMPV2_MESSAGE IgmpMessage;
|
||||
struct {
|
||||
UDPV4_HEADER UdpHeader;
|
||||
UINT8 Data[1];
|
||||
} Udp;
|
||||
struct {
|
||||
TCPV4_HEADER TcpHeader;
|
||||
UINT8 Data[1];
|
||||
} Tcp;
|
||||
} PROTOCOL_UNION;
|
||||
|
||||
//
|
||||
// out buffer structure
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 MediaHeader[MAX_MEDIA_HDR_SIZE];
|
||||
IPV4_HEADER IpHeader;
|
||||
//
|
||||
// following union placement only valid if no option IP header
|
||||
//
|
||||
PROTOCOL_UNION u;
|
||||
} IPV4_BUFFER;
|
||||
|
||||
typedef struct {
|
||||
IPV4_HEADER IpHeader;
|
||||
//
|
||||
// following union placement only valid if no option IP header
|
||||
//
|
||||
PROTOCOL_UNION u;
|
||||
} IPV4_STRUCT;
|
||||
|
||||
#pragma pack() // reset to default
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BC IP Filter Routine
|
||||
//
|
||||
EFI_STATUS
|
||||
IpFilter (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
IN EFI_PXE_BASE_CODE_IP_FILTER *Filter
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Udp Write Routine - called by base code - e.g. TFTP - already locked
|
||||
//
|
||||
EFI_STATUS
|
||||
UdpWrite (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN UINT16 OpFlags,
|
||||
IN EFI_IP_ADDRESS *DestIpPtr,
|
||||
IN EFI_PXE_BASE_CODE_UDP_PORT *DestPortptr,
|
||||
IN EFI_IP_ADDRESS *GatewayIpPtr, OPTIONAL
|
||||
IN EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL
|
||||
IN UINTN *HeaderSizePtr, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN UINTN *BufferSizePtr,
|
||||
IN VOID *BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Udp Read Routine - called by base code - e.g. TFTP - already locked
|
||||
//
|
||||
EFI_STATUS
|
||||
UdpRead (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN UINT16 OpFlags,
|
||||
IN OUT EFI_IP_ADDRESS *DestIpPtr, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPorPtrt, OPTIONAL
|
||||
IN OUT EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL
|
||||
IN UINTN *HeaderSizePtr, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN OUT UINTN *BufferSizePtr,
|
||||
IN VOID *BufferPtr,
|
||||
IN EFI_EVENT TimeoutEvent
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
IgmpLeaveGroup (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
EFI_IP_ADDRESS *
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
IgmpJoinGroup (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
EFI_IP_ADDRESS *
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// convert number to zero filled ascii value of length lth
|
||||
//
|
||||
VOID
|
||||
CvtNum (
|
||||
UINTN Number,
|
||||
UINT8 *BufferPtr,
|
||||
INTN BufferLen
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// convert number to ascii string at ptr
|
||||
//
|
||||
VOID
|
||||
UtoA10 (
|
||||
UINTN Number,
|
||||
UINT8 *BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// convert ascii numeric string to UINTN
|
||||
//
|
||||
UINTN
|
||||
AtoU (
|
||||
UINT8 *BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
UINT64
|
||||
AtoU64 (
|
||||
UINT8 *BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// calculate the internet checksum (RFC 1071)
|
||||
// return 16 bit ones complement of ones complement sum of 16 bit words
|
||||
//
|
||||
UINT16
|
||||
IpChecksum (
|
||||
UINT16 *MessagePtr,
|
||||
UINTN ByteLength
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// do checksum on non contiguous header and data
|
||||
//
|
||||
UINT16
|
||||
IpChecksum2 (
|
||||
UINT16 *Header,
|
||||
UINTN HeaderLength,
|
||||
UINT16 *Message,
|
||||
UINTN MessageLength
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// update checksum when only a single word changes
|
||||
//
|
||||
UINT16
|
||||
UpdateChecksum (
|
||||
UINT16 OldChecksum,
|
||||
UINT16 OldWord,
|
||||
UINT16 NewWord
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
SeedRandom (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN UINT16 InitialSeed
|
||||
)
|
||||
;
|
||||
|
||||
UINT16
|
||||
Random (
|
||||
IN PXE_BASECODE_DEVICE *Private
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
SendPacket (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
VOID *HeaderPtr,
|
||||
VOID *PacketPtr,
|
||||
INTN PacketLength,
|
||||
VOID *HardwareAddress,
|
||||
UINT16 MediaProtocol,
|
||||
IN EFI_PXE_BASE_CODE_FUNCTION Function
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
HandleArpReceive (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
ARP_PACKET *ArpPacketPtr,
|
||||
VOID *HeaderPtr
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
HandleIgmp (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
IGMPV2_MESSAGE *IgmpMessageptr,
|
||||
UINTN IgmpMessageLen
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
IgmpCheckTimers (
|
||||
PXE_BASECODE_DEVICE *Private
|
||||
)
|
||||
; // poll when doing a receive
|
||||
// return hw add of IP and TRUE if available, otherwise FALSE
|
||||
//
|
||||
BOOLEAN
|
||||
GetHwAddr (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
EFI_IP_ADDRESS *ProtocolAddressPtr,
|
||||
EFI_MAC_ADDRESS *HardwareAddressPtr
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
DoArp (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN EFI_IP_ADDRESS *ProtocolAddressPtr,
|
||||
OUT EFI_MAC_ADDRESS *HardwareAddressptr
|
||||
)
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
OnSameSubnet (
|
||||
UINTN IpAddressLen,
|
||||
EFI_IP_ADDRESS *Ip1,
|
||||
EFI_IP_ADDRESS *Ip2,
|
||||
EFI_IP_ADDRESS *SubnetMask
|
||||
)
|
||||
;
|
||||
|
||||
VOID
|
||||
IpAddRouter (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
EFI_IP_ADDRESS *RouterIp
|
||||
)
|
||||
;
|
||||
|
||||
#define Ip4AddRouter(Private, Ipv4Ptr) IpAddRouter (Private, (EFI_IP_ADDRESS *) Ipv4Ptr)
|
||||
|
||||
//
|
||||
// routine to send ipv4 packet
|
||||
// ipv4 + upper protocol header for length TotHdrLth in xmtbuf, ipv4 header length IpHdrLth
|
||||
// routine fills in ipv4hdr Ver_Hdl, TotLth, and Checksum, moves in Data, and gets dest MAC address
|
||||
//
|
||||
EFI_STATUS
|
||||
Ipv4Xmt (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINT32 GatewayIP,
|
||||
UINTN IpHeaderLen,
|
||||
UINTN TotalHeaderLen,
|
||||
VOID *Data,
|
||||
UINTN DataLen,
|
||||
EFI_PXE_BASE_CODE_FUNCTION Function
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// send ipv4 packet with ipv4 option
|
||||
//
|
||||
EFI_STATUS
|
||||
Ipv4SendWOp (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINT32 GatewayIP,
|
||||
UINT8 *MessagePtr,
|
||||
UINTN MessageLth,
|
||||
UINT8 Protocol,
|
||||
UINT8 *Option,
|
||||
UINTN OptionLen,
|
||||
UINT32 DestIp,
|
||||
EFI_PXE_BASE_CODE_FUNCTION Function
|
||||
)
|
||||
;
|
||||
|
||||
//
|
||||
// send MsgLth message at MsgPtr - higher level protocol header already in xmtbuf, length HdrSize
|
||||
//
|
||||
EFI_STATUS
|
||||
Ip4Send (
|
||||
IN PXE_BASECODE_DEVICE *Private, // pointer to instance data
|
||||
IN UINTN MayFragment, //
|
||||
IN UINT8 Protocol, // protocol
|
||||
IN UINT32 SrcIp, // Source IP address
|
||||
IN UINT32 DestIp, // Destination IP address
|
||||
IN UINT32 GatewayIp, // used if not NULL and needed
|
||||
IN UINTN HeaderSize, // protocol header byte length
|
||||
IN UINT8 *MsgPtr, // pointer to data
|
||||
IN UINTN MsgLength
|
||||
)
|
||||
; // data byte length
|
||||
// receive up to MsgLth message into MsgPtr for protocol Prot
|
||||
// return message length, src/dest ips if select any, and pointer to protocol header
|
||||
//
|
||||
EFI_STATUS
|
||||
IpReceive (
|
||||
IN PXE_BASECODE_DEVICE *Private, // pointer to instance data
|
||||
UINT16 OpFlags, // Flags to determine if filtering on IP addresses
|
||||
EFI_IP_ADDRESS *SrcIpPtr, // if filtering, O if accept any
|
||||
EFI_IP_ADDRESS *DstIpPtr, // if filtering, O if accept any
|
||||
UINT8 Protocol, // protocol
|
||||
VOID *HeaderPtr, // address of where to put protocol header
|
||||
UINTN HeaderSize, // protocol header byte length
|
||||
UINT8 *MsgPtr, // pointer to data buffer
|
||||
UINTN *MsgLenPtr, // pointer to data buffer length/ O - returned data length
|
||||
IN EFI_EVENT TimeoutEvent
|
||||
)
|
||||
;
|
||||
|
||||
#if 0
|
||||
VOID
|
||||
WaitForTxComplete (
|
||||
IN PXE_BASECODE_DEVICE *Private
|
||||
)
|
||||
;
|
||||
#endif
|
||||
//
|
||||
// routine to cycle waiting for a receive or timeout
|
||||
//
|
||||
EFI_STATUS
|
||||
WaitForReceive (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN EFI_PXE_BASE_CODE_FUNCTION Function,
|
||||
IN EFI_EVENT TimeoutEvent,
|
||||
IN OUT UINTN *HeaderSizePtr,
|
||||
IN OUT UINTN *BufferSizePtr,
|
||||
IN OUT UINT16 *ProtocolPtr
|
||||
)
|
||||
;
|
||||
|
||||
#endif /* _IP_H_ */
|
||||
|
||||
/* EOF - ip.h */
|
617
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_arp.c
Normal file
617
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_arp.c
Normal file
@@ -0,0 +1,617 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
pxe_bc_arp.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "bc.h"
|
||||
|
||||
//
|
||||
// Definitions for ARP
|
||||
// Per RFC 826
|
||||
//
|
||||
STATIC ARP_HEADER ArpHeader;
|
||||
|
||||
#pragma pack(1)
|
||||
STATIC struct {
|
||||
UINT8 MediaHeader[14];
|
||||
ARP_HEADER ArpHeader;
|
||||
UINT8 ArpData[64];
|
||||
} ArpReplyPacket;
|
||||
#pragma pack()
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
VOID
|
||||
InitArpHeader (
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Initialize ARP packet header.
|
||||
|
||||
Parameters:
|
||||
none
|
||||
|
||||
Returns:
|
||||
none
|
||||
|
||||
--*/
|
||||
{
|
||||
ArpHeader.HwType = HTONS (ETHERNET_ADD_SPC);
|
||||
ArpHeader.ProtType = HTONS (ETHER_TYPE_IP);
|
||||
ArpHeader.HwAddLen = ENET_HWADDLEN;
|
||||
ArpHeader.ProtAddLen = IPV4_PROTADDLEN;
|
||||
ArpHeader.OpCode = HTONS (ARP_REQUEST);
|
||||
|
||||
CopyMem (&ArpReplyPacket.ArpHeader, &ArpHeader, sizeof (ARP_HEADER));
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
VOID
|
||||
HandleArpReceive (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN ARP_PACKET *ArpPacketPtr,
|
||||
IN VOID *MediaHeader
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Process ARP packet.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
ArpPacketPtr := Pointer to ARP packet
|
||||
MediaHeader := Pointer to media header.
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpMode;
|
||||
EFI_MAC_ADDRESS TmpMacAddr;
|
||||
UINTN Index;
|
||||
UINT8 *SrcHwAddr;
|
||||
UINT8 *SrcPrAddr;
|
||||
UINT8 *DstHwAddr;
|
||||
UINT8 *DstPrAddr;
|
||||
UINT8 *TmpPtr;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
SnpMode = Private->SimpleNetwork->Mode;
|
||||
|
||||
//
|
||||
// For now only ethernet addresses are supported.
|
||||
// This will need to be updated when other media
|
||||
// layers are supported by PxeBc, Snp and UNDI.
|
||||
//
|
||||
if (ArpPacketPtr->ArpHeader.HwType != HTONS (ETHERNET_ADD_SPC)) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// For now only IP protocol addresses are supported.
|
||||
// This will need to be updated when other protocol
|
||||
// types are supported by PxeBc, Snp and UNDI.
|
||||
//
|
||||
if (ArpPacketPtr->ArpHeader.ProtType != HTONS (ETHER_TYPE_IP)) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// For now only SNP hardware address sizes are supported.
|
||||
//
|
||||
if (ArpPacketPtr->ArpHeader.HwAddLen != SnpMode->HwAddressSize) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// For now only PxeBc protocol address sizes are supported.
|
||||
//
|
||||
if (ArpPacketPtr->ArpHeader.ProtAddLen != Private->IpLength) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Ignore out of range opcodes
|
||||
//
|
||||
switch (ArpPacketPtr->ArpHeader.OpCode) {
|
||||
case HTONS (ARP_REPLY):
|
||||
case HTONS (ARP_REQUEST):
|
||||
break;
|
||||
|
||||
default:
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// update entry in our ARP cache if we have it
|
||||
//
|
||||
SrcHwAddr = (UINT8 *) &ArpPacketPtr->SrcHardwareAddr;
|
||||
SrcPrAddr = SrcHwAddr + SnpMode->HwAddressSize;
|
||||
|
||||
for (Index = 0; Index < PxeBcMode->ArpCacheEntries; ++Index) {
|
||||
if (CompareMem (
|
||||
&PxeBcMode->ArpCache[Index].IpAddr,
|
||||
SrcPrAddr,
|
||||
Private->IpLength
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
&PxeBcMode->ArpCache[Index].MacAddr,
|
||||
SrcHwAddr,
|
||||
SnpMode->HwAddressSize
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Done if ARP packet was not for us.
|
||||
//
|
||||
DstHwAddr = SrcPrAddr + Private->IpLength;
|
||||
DstPrAddr = DstHwAddr + SnpMode->HwAddressSize;
|
||||
|
||||
if (CompareMem (DstPrAddr, &PxeBcMode->StationIp, Private->IpLength)) {
|
||||
return ;
|
||||
//
|
||||
// not for us
|
||||
//
|
||||
}
|
||||
//
|
||||
// for us - if we did not update entry, add it
|
||||
//
|
||||
if (Index == PxeBcMode->ArpCacheEntries) {
|
||||
//
|
||||
// if we have a full table, get rid of oldest
|
||||
//
|
||||
if (Index == PXE_ARP_CACHE_SIZE) {
|
||||
Index = Private->OldestArpEntry;
|
||||
|
||||
if (++Private->OldestArpEntry == PXE_ARP_CACHE_SIZE) {
|
||||
Private->OldestArpEntry = 0;
|
||||
}
|
||||
} else {
|
||||
++PxeBcMode->ArpCacheEntries;
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
&PxeBcMode->ArpCache[Index].MacAddr,
|
||||
SrcHwAddr,
|
||||
SnpMode->HwAddressSize
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&PxeBcMode->ArpCache[Index].IpAddr,
|
||||
SrcPrAddr,
|
||||
Private->IpLength
|
||||
);
|
||||
}
|
||||
//
|
||||
// if this is not a request or we don't yet have an IP, finished
|
||||
//
|
||||
if (ArpPacketPtr->ArpHeader.OpCode != HTONS (ARP_REQUEST) || !Private->GoodStationIp) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Assemble ARP reply.
|
||||
//
|
||||
//
|
||||
// Create media header. [ dest mac | src mac | prot ]
|
||||
//
|
||||
CopyMem (
|
||||
&ArpReplyPacket.MediaHeader[0],
|
||||
SrcHwAddr,
|
||||
SnpMode->HwAddressSize
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&ArpReplyPacket.MediaHeader[SnpMode->HwAddressSize],
|
||||
&SnpMode->CurrentAddress,
|
||||
SnpMode->HwAddressSize
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&ArpReplyPacket.MediaHeader[2 * SnpMode->HwAddressSize],
|
||||
&((UINT8 *) MediaHeader)[2 * SnpMode->HwAddressSize],
|
||||
sizeof (UINT16)
|
||||
);
|
||||
|
||||
//
|
||||
// ARP reply header is almost filled in,
|
||||
// just insert the correct opcode.
|
||||
//
|
||||
ArpReplyPacket.ArpHeader.OpCode = HTONS (ARP_REPLY);
|
||||
|
||||
//
|
||||
// Now fill in ARP data. [ src mac | src prot | dest mac | dest prot ]
|
||||
//
|
||||
TmpPtr = ArpReplyPacket.ArpData;
|
||||
CopyMem (TmpPtr, &SnpMode->CurrentAddress, SnpMode->HwAddressSize);
|
||||
|
||||
TmpPtr += SnpMode->HwAddressSize;
|
||||
CopyMem (TmpPtr, &PxeBcMode->StationIp, Private->IpLength);
|
||||
|
||||
TmpPtr += Private->IpLength;
|
||||
CopyMem (TmpPtr, SrcHwAddr, SnpMode->HwAddressSize);
|
||||
|
||||
TmpPtr += SnpMode->HwAddressSize;
|
||||
CopyMem (TmpPtr, SrcPrAddr, Private->IpLength);
|
||||
|
||||
//
|
||||
// Now send out the ARP reply.
|
||||
//
|
||||
CopyMem (&TmpMacAddr, SrcHwAddr, sizeof (EFI_MAC_ADDRESS));
|
||||
|
||||
SendPacket (
|
||||
Private,
|
||||
&ArpReplyPacket.MediaHeader,
|
||||
&ArpReplyPacket.ArpHeader,
|
||||
sizeof (ARP_HEADER) + 2 * (Private->IpLength + SnpMode->HwAddressSize),
|
||||
&TmpMacAddr,
|
||||
PXE_PROTOCOL_ETHERNET_ARP,
|
||||
EFI_PXE_BASE_CODE_FUNCTION_ARP
|
||||
);
|
||||
|
||||
//
|
||||
// Give time (100 microseconds) for ARP reply to get onto wire.
|
||||
//
|
||||
gBS->Stall (1000);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
BOOLEAN
|
||||
GetHwAddr (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN EFI_IP_ADDRESS *ProtocolAddrPtr,
|
||||
OUT EFI_MAC_ADDRESS *HardwareAddrPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Locate IP address in ARP cache and return MAC address.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
ProtocolAddrPtr := Pointer to IP address
|
||||
HardwareAddrPtr := Pointer to MAC address storage
|
||||
|
||||
Returns:
|
||||
TRUE := If IP address was found and MAC address was stored
|
||||
FALSE := If IP address was not found
|
||||
--*/
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
UINTN HardwareAddrLength;
|
||||
UINTN Index;
|
||||
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
HardwareAddrLength = Private->SimpleNetwork->Mode->HwAddressSize;
|
||||
|
||||
for (Index = 0; Index < PxeBcMode->ArpCacheEntries; ++Index) {
|
||||
if (!CompareMem (
|
||||
ProtocolAddrPtr,
|
||||
&PxeBcMode->ArpCache[Index].IpAddr,
|
||||
Private->IpLength
|
||||
)) {
|
||||
CopyMem (
|
||||
HardwareAddrPtr,
|
||||
&PxeBcMode->ArpCache[Index].MacAddr,
|
||||
HardwareAddrLength
|
||||
);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
SendRequest (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN EFI_IP_ADDRESS *ProtocolAddrPtr,
|
||||
IN EFI_MAC_ADDRESS *HardwareAddrPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Transmit ARP request packet
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
ProtocolAddrPtr := Pointer IP address to find
|
||||
HardwareAddrPtr := Pointer to MAC address to find
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS := ARP request sent
|
||||
other := ARP request could not be sent
|
||||
--*/
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpMode;
|
||||
ARP_PACKET *ArpPacket;
|
||||
EFI_STATUS Status;
|
||||
UINTN HardwareAddrLength;
|
||||
UINT8 *SrcProtocolAddrPtr;
|
||||
UINT8 *DestHardwareAddrptr;
|
||||
UINT8 *DestProtocolAddrPtr;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
SnpMode = Private->SimpleNetwork->Mode;
|
||||
HardwareAddrLength = SnpMode->HwAddressSize;
|
||||
|
||||
//
|
||||
// Allocate ARP buffer
|
||||
//
|
||||
if (Private->ArpBuffer == NULL) {
|
||||
Status = gBS->AllocatePool (
|
||||
EfiBootServicesData,
|
||||
SnpMode->MediaHeaderSize + sizeof (ARP_PACKET),
|
||||
(VOID **) &Private->ArpBuffer
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
ArpPacket = (VOID *) (Private->ArpBuffer + SnpMode->MediaHeaderSize);
|
||||
|
||||
//
|
||||
// for now, only handle one kind of hw and pr address
|
||||
//
|
||||
ArpPacket->ArpHeader = ArpHeader;
|
||||
ArpPacket->ArpHeader.HwAddLen = (UINT8) HardwareAddrLength;
|
||||
ArpPacket->ArpHeader.ProtAddLen = (UINT8) Private->IpLength;
|
||||
|
||||
//
|
||||
// rest more generic
|
||||
//
|
||||
SrcProtocolAddrPtr = (UINT8 *) (&ArpPacket->SrcHardwareAddr) + HardwareAddrLength;
|
||||
DestHardwareAddrptr = SrcProtocolAddrPtr + Private->IpLength;
|
||||
DestProtocolAddrPtr = DestHardwareAddrptr + HardwareAddrLength;
|
||||
|
||||
CopyMem (DestProtocolAddrPtr, ProtocolAddrPtr, Private->IpLength);
|
||||
CopyMem (DestHardwareAddrptr, HardwareAddrPtr, HardwareAddrLength);
|
||||
CopyMem (SrcProtocolAddrPtr, &PxeBcMode->StationIp, Private->IpLength);
|
||||
CopyMem (
|
||||
&ArpPacket->SrcHardwareAddr,
|
||||
&SnpMode->CurrentAddress,
|
||||
HardwareAddrLength
|
||||
);
|
||||
|
||||
return SendPacket (
|
||||
Private,
|
||||
Private->ArpBuffer,
|
||||
ArpPacket,
|
||||
sizeof (ARP_HEADER) + ((Private->IpLength + HardwareAddrLength) << 1),
|
||||
&SnpMode->BroadcastAddress,
|
||||
PXE_PROTOCOL_ETHERNET_ARP,
|
||||
EFI_PXE_BASE_CODE_FUNCTION_ARP
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//
|
||||
// check for address - if not there, send ARP request, wait and check again
|
||||
// not how it would be done in a full system
|
||||
//
|
||||
#define ARP_REQUEST_TIMEOUT_MS 500 // try for half a second
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BC Arp Routine
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcArp (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
|
||||
IN EFI_IP_ADDRESS * ProtocolAddrPtr,
|
||||
OUT EFI_MAC_ADDRESS * HardwareAddrPtr OPTIONAL
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
PxeBc ARP API.
|
||||
|
||||
Parameters:
|
||||
This := Pointer to PxeBc interface
|
||||
ProtocolAddrPtr := Pointer to IP address to find
|
||||
HardwareAddrPtr := Pointer to MAC address found.
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
EFI_MAC_ADDRESS Mac;
|
||||
EFI_STATUS StatCode;
|
||||
PXE_BASECODE_DEVICE *Private;
|
||||
|
||||
//
|
||||
// Lock the instance data and make sure started
|
||||
//
|
||||
StatCode = EFI_SUCCESS;
|
||||
|
||||
if (This == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
|
||||
|
||||
if (Private == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EfiAcquireLock (&Private->Lock);
|
||||
|
||||
if (This->Mode == NULL || !This->Mode->Started) {
|
||||
DEBUG ((EFI_D_ERROR, "BC was not started."));
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_INFO, "\nBcArp()"));
|
||||
|
||||
//
|
||||
// Issue BC command
|
||||
//
|
||||
if (ProtocolAddrPtr == NULL) {
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nBcArp() Exit #1 %Xh (%r)",
|
||||
EFI_INVALID_PARAMETER,
|
||||
EFI_INVALID_PARAMETER)
|
||||
);
|
||||
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (HardwareAddrPtr == NULL) {
|
||||
HardwareAddrPtr = &Mac;
|
||||
}
|
||||
|
||||
ZeroMem (HardwareAddrPtr, Private->SimpleNetwork->Mode->HwAddressSize);
|
||||
|
||||
if (GetHwAddr (Private, ProtocolAddrPtr, HardwareAddrPtr)) {
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nBcArp() Exit #2 %Xh (%r)",
|
||||
EFI_SUCCESS,
|
||||
EFI_SUCCESS)
|
||||
);
|
||||
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
StatCode = DoArp (Private, ProtocolAddrPtr, HardwareAddrPtr);
|
||||
|
||||
DEBUG ((EFI_D_INFO, "\nBcArp() Exit #3 %Xh (%r)", StatCode, StatCode));
|
||||
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return StatCode;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
EFI_STATUS
|
||||
DoArp (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN EFI_IP_ADDRESS *ProtocolAddrPtr,
|
||||
OUT EFI_MAC_ADDRESS *HardwareAddrPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Internal ARP implementation.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
ProtocolAddrPtr := Pointer to IP address to find
|
||||
HardwareAddrPtr := Pointer to MAC address found
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS := MAC address found
|
||||
other := MAC address could not be found
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS StatCode;
|
||||
EFI_EVENT TimeoutEvent;
|
||||
UINTN HeaderSize;
|
||||
UINTN BufferSize;
|
||||
UINT16 Protocol;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "\nDoArp()"));
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
StatCode = SendRequest (Private, ProtocolAddrPtr, HardwareAddrPtr);
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
DEBUG ((EFI_D_INFO, "\nDoArp() Exit #1 %Xh (%r)", StatCode, StatCode));
|
||||
return StatCode;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
StatCode = gBS->CreateEvent (
|
||||
EFI_EVENT_TIMER,
|
||||
EFI_TPL_CALLBACK,
|
||||
NULL,
|
||||
NULL,
|
||||
&TimeoutEvent
|
||||
);
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
return StatCode;
|
||||
}
|
||||
|
||||
StatCode = gBS->SetTimer (
|
||||
TimeoutEvent,
|
||||
TimerRelative,
|
||||
ARP_REQUEST_TIMEOUT_MS * 10000
|
||||
);
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
gBS->CloseEvent (TimeoutEvent);
|
||||
return StatCode;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
for (;;) {
|
||||
StatCode = WaitForReceive (
|
||||
Private,
|
||||
EFI_PXE_BASE_CODE_FUNCTION_ARP,
|
||||
TimeoutEvent,
|
||||
&HeaderSize,
|
||||
&BufferSize,
|
||||
&Protocol
|
||||
);
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (Protocol != PXE_PROTOCOL_ETHERNET_ARP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HandleArpReceive (
|
||||
Private,
|
||||
(ARP_PACKET *) (Private->ReceiveBufferPtr + HeaderSize),
|
||||
Private->ReceiveBufferPtr
|
||||
);
|
||||
|
||||
if (GetHwAddr (Private, ProtocolAddrPtr, HardwareAddrPtr)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nDoArp() Exit #2 %Xh, (%r)",
|
||||
StatCode,
|
||||
StatCode)
|
||||
);
|
||||
|
||||
gBS->CloseEvent (TimeoutEvent);
|
||||
|
||||
return StatCode;
|
||||
}
|
||||
|
||||
/* eof - pxe_bc_arp.c */
|
3332
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c
Normal file
3332
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_dhcp.c
Normal file
File diff suppressed because it is too large
Load Diff
476
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_igmp.c
Normal file
476
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_igmp.c
Normal file
@@ -0,0 +1,476 @@
|
||||
/*++
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
|
||||
|
||||
#define RAND_MAX 0x10000
|
||||
#include "bc.h"
|
||||
|
||||
//
|
||||
// Definitions for internet group management protocol version 2 message
|
||||
// structure Per RFC 2236, November 1997
|
||||
//
|
||||
STATIC UINT8 RouterAlertOption[4] = { 0x80 | 20, 4, 0, 0 };
|
||||
STATIC IPV4_ADDR AllRoutersGroup = { { 224, 0, 0, 2 } };
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
STATIC
|
||||
VOID
|
||||
ClearGroupTimer (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINTN TimerId
|
||||
)
|
||||
{
|
||||
if (Private == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (TimerId >= Private->MCastGroupCount) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (Private->IgmpGroupEvent[TimerId] == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
gBS->CloseEvent (Private->IgmpGroupEvent[TimerId]);
|
||||
Private->IgmpGroupEvent[TimerId] = NULL;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
STATIC
|
||||
VOID
|
||||
SetGroupTimer (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINTN TimerId,
|
||||
UINTN MaxRespTime
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Set IGMP response timeout value.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
TimerId := Timer ID#
|
||||
MaxRespTime := Base response timeout value in tenths of seconds
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
if (Private == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (TimerId >= Private->MCastGroupCount) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (Private->IgmpGroupEvent[TimerId] != NULL) {
|
||||
gBS->CloseEvent (Private->IgmpGroupEvent[TimerId]);
|
||||
}
|
||||
|
||||
EfiStatus = gBS->CreateEvent (
|
||||
EFI_EVENT_TIMER,
|
||||
EFI_TPL_CALLBACK,
|
||||
NULL,
|
||||
NULL,
|
||||
&Private->IgmpGroupEvent[TimerId]
|
||||
);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
Private->IgmpGroupEvent[TimerId] = NULL;
|
||||
return ;
|
||||
}
|
||||
|
||||
EfiStatus = gBS->SetTimer (
|
||||
Private->IgmpGroupEvent[TimerId],
|
||||
TimerRelative,
|
||||
MaxRespTime * 1000000 + Random (Private) % RAND_MAX
|
||||
);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
gBS->CloseEvent (Private->IgmpGroupEvent[TimerId]);
|
||||
Private->IgmpGroupEvent[TimerId] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
STATIC
|
||||
VOID
|
||||
SendIgmpMessage (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINT8 Type,
|
||||
INTN GroupId
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Send an IGMP message
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
Type := Message type opcode
|
||||
GroupId := Group ID#
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
Private->IgmpMessage.Type = Type;
|
||||
Private->IgmpMessage.MaxRespTime = 0;
|
||||
Private->IgmpMessage.Checksum = 0;
|
||||
Private->IgmpMessage.GroupAddress = Private->MCastGroup[GroupId];
|
||||
Private->IgmpMessage.Checksum = IpChecksum (
|
||||
(UINT16 *) &Private->IgmpMessage,
|
||||
sizeof Private->IgmpMessage
|
||||
);
|
||||
|
||||
Ipv4SendWOp (
|
||||
Private,
|
||||
0,
|
||||
(UINT8 *) &Private->IgmpMessage,
|
||||
sizeof Private->IgmpMessage,
|
||||
PROT_IGMP,
|
||||
RouterAlertOption,
|
||||
sizeof RouterAlertOption,
|
||||
((Type == IGMP_TYPE_LEAVE_GROUP) ? AllRoutersGroup.L : Private->IgmpMessage.GroupAddress),
|
||||
EFI_PXE_BASE_CODE_FUNCTION_IGMP
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
STATIC
|
||||
VOID
|
||||
ReportIgmp (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
INTN GroupId
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Send an IGMP report message.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
GroupId := Group ID#
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// if version 1 querier, send v1 report
|
||||
//
|
||||
UINT8 Type;
|
||||
|
||||
if (Private->Igmpv1TimeoutEvent != NULL) {
|
||||
if (!EFI_ERROR (gBS->CheckEvent (Private->Igmpv1TimeoutEvent))) {
|
||||
gBS->CloseEvent (Private->Igmpv1TimeoutEvent);
|
||||
Private->Igmpv1TimeoutEvent = NULL;
|
||||
Private->UseIgmpv1Reporting = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Type = (UINT8) (Private->UseIgmpv1Reporting ? IGMP_TYPE_V1REPORT : IGMP_TYPE_REPORT);
|
||||
|
||||
SendIgmpMessage (Private, Type, GroupId);
|
||||
ClearGroupTimer (Private, GroupId);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
VOID
|
||||
IgmpCheckTimers (
|
||||
PXE_BASECODE_DEVICE *Private
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Check IGMP timers and send reports for all groups that have expired.
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
UINTN GroupId;
|
||||
|
||||
if (Private == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
for (GroupId = 0; GroupId < Private->MCastGroupCount; ++GroupId) {
|
||||
if (Private->IgmpGroupEvent[GroupId] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (gBS->CheckEvent (Private->IgmpGroupEvent[GroupId]))) {
|
||||
//
|
||||
// send a report
|
||||
//
|
||||
ReportIgmp (Private, GroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
STATIC
|
||||
INTN
|
||||
FindMulticastGroup (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINT32 GroupAddress
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Fund group ID# (index).
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
GroupAddress := Group multicast address
|
||||
|
||||
Returns:
|
||||
0 := Group not found
|
||||
other := Group ID#
|
||||
--*/
|
||||
{
|
||||
UINTN GroupId;
|
||||
|
||||
for (GroupId = 0; GroupId < Private->MCastGroupCount; ++GroupId) {
|
||||
if (Private->MCastGroup[GroupId] == GroupAddress) {
|
||||
return GroupId + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
VOID
|
||||
IgmpJoinGroup (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
EFI_IP_ADDRESS *GroupPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Join multicast group.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
GroupPtr := Pointer to group mutlicast IP address.
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
UINT32 Grp;
|
||||
|
||||
Grp = *(UINT32 *) GroupPtr;
|
||||
|
||||
#if SUPPORT_IPV6
|
||||
if (Private->EfiBc.Mode->UsingIpv6) {
|
||||
//
|
||||
// TBD
|
||||
//
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// see if we already have it or if we can't take anymore
|
||||
//
|
||||
if (FindMulticastGroup (Private, Grp) || Private->MCastGroupCount == MAX_MCAST_GROUPS) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// add the group
|
||||
//
|
||||
Private->MCastGroup[Private->MCastGroupCount] = Grp;
|
||||
|
||||
ReportIgmp (Private, Private->MCastGroupCount);
|
||||
//
|
||||
// send a report
|
||||
// so it will get sent again per RFC 2236
|
||||
//
|
||||
SetGroupTimer (
|
||||
Private,
|
||||
Private->MCastGroupCount++,
|
||||
UNSOLICITED_REPORT_INTERVAL * 10
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
VOID
|
||||
IgmpLeaveGroup (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
EFI_IP_ADDRESS *GroupPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Leave multicast group.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
GroupPtr := Mutlicast group IP address.
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
UINT32 Grp;
|
||||
UINTN GroupId;
|
||||
|
||||
Grp = *(UINT32 *) GroupPtr;
|
||||
|
||||
#if SUPPORT_IPV6
|
||||
if (Private->EfiBc.Mode->UsingIpv6) {
|
||||
//
|
||||
// TBD
|
||||
//
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// if not in group, ignore
|
||||
//
|
||||
GroupId = FindMulticastGroup (Private, Grp);
|
||||
|
||||
if (GroupId == 0) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// if not v1 querrier, send leave group IGMP message
|
||||
//
|
||||
if (Private->Igmpv1TimeoutEvent != NULL) {
|
||||
if (!EFI_ERROR (gBS->CheckEvent (Private->Igmpv1TimeoutEvent))) {
|
||||
gBS->CloseEvent (Private->Igmpv1TimeoutEvent);
|
||||
Private->Igmpv1TimeoutEvent = NULL;
|
||||
Private->UseIgmpv1Reporting = TRUE;
|
||||
} else {
|
||||
SendIgmpMessage (Private, IGMP_TYPE_LEAVE_GROUP, GroupId - 1);
|
||||
}
|
||||
}
|
||||
|
||||
while (GroupId < Private->MCastGroupCount) {
|
||||
Private->MCastGroup[GroupId - 1] = Private->MCastGroup[GroupId];
|
||||
Private->IgmpGroupEvent[GroupId - 1] = Private->IgmpGroupEvent[GroupId];
|
||||
++GroupId;
|
||||
}
|
||||
|
||||
--Private->MCastGroupCount;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
VOID
|
||||
HandleIgmp (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
IGMPV2_MESSAGE *IgmpMessagePtr,
|
||||
UINTN IgmpLength
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
Handle received IGMP packet
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
IgmpMessagePtr := Pointer to IGMP packet
|
||||
IgmpLength := packet length in bytes
|
||||
|
||||
Returns:
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS EfiStatus;
|
||||
UINTN GroupId;
|
||||
INTN MaxRespTime;
|
||||
|
||||
if (Private == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (Private->MCastGroupCount == 0) {
|
||||
//
|
||||
// if we don't belong to any multicast groups, ignore
|
||||
//
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// verify checksum
|
||||
//
|
||||
if (IpChecksum ((UINT16 *) IgmpMessagePtr, IgmpLength)) {
|
||||
//
|
||||
// bad checksum - ignore packet
|
||||
//
|
||||
return ;
|
||||
}
|
||||
|
||||
switch (IgmpMessagePtr->Type) {
|
||||
case IGMP_TYPE_QUERY:
|
||||
//
|
||||
// if a version 1 querier, note the fact and set max resp time
|
||||
//
|
||||
MaxRespTime = IgmpMessagePtr->MaxRespTime;
|
||||
|
||||
if (MaxRespTime == 0) {
|
||||
Private->UseIgmpv1Reporting = TRUE;
|
||||
|
||||
if (Private->Igmpv1TimeoutEvent != NULL) {
|
||||
gBS->CloseEvent (Private->Igmpv1TimeoutEvent);
|
||||
}
|
||||
|
||||
EfiStatus = gBS->CreateEvent (
|
||||
EFI_EVENT_TIMER,
|
||||
EFI_TPL_CALLBACK,
|
||||
NULL,
|
||||
NULL,
|
||||
&Private->Igmpv1TimeoutEvent
|
||||
);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
Private->Igmpv1TimeoutEvent = NULL;
|
||||
} else {
|
||||
EfiStatus = gBS->SetTimer (
|
||||
Private->Igmpv1TimeoutEvent,
|
||||
TimerRelative,
|
||||
(UINT64) V1ROUTER_PRESENT_TIMEOUT * 10000000
|
||||
);
|
||||
}
|
||||
|
||||
MaxRespTime = IGMP_DEFAULT_MAX_RESPONSE_TIME * 10;
|
||||
}
|
||||
//
|
||||
// if a general query (!GroupAddress), set all our group timers
|
||||
//
|
||||
if (!IgmpMessagePtr->GroupAddress) {
|
||||
for (GroupId = 0; GroupId < Private->MCastGroupCount; ++GroupId) {
|
||||
SetGroupTimer (Private, GroupId, MaxRespTime);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// specific query - set only specific group
|
||||
//
|
||||
GroupId = FindMulticastGroup (Private, IgmpMessagePtr->GroupAddress);
|
||||
|
||||
if (GroupId != 0) {
|
||||
SetGroupTimer (Private, GroupId - 1, MaxRespTime);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//
|
||||
// if we have a timer running for this group, clear it
|
||||
//
|
||||
case IGMP_TYPE_V1REPORT:
|
||||
case IGMP_TYPE_REPORT:
|
||||
GroupId = FindMulticastGroup (Private, IgmpMessagePtr->GroupAddress);
|
||||
|
||||
if (GroupId != 0) {
|
||||
ClearGroupTimer (Private, GroupId - 1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF - pxe_bc_igmp.c */
|
861
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_ip.c
Normal file
861
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_ip.c
Normal file
@@ -0,0 +1,861 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
pxe_bc_ip.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "bc.h"
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
BOOLEAN
|
||||
OnSameSubnet (
|
||||
IN UINTN IpLength,
|
||||
IN EFI_IP_ADDRESS *Ip1,
|
||||
IN EFI_IP_ADDRESS *Ip2,
|
||||
IN EFI_IP_ADDRESS *SubnetMask
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Check if two IP addresses are on the same subnet.
|
||||
|
||||
Arguments:
|
||||
IpLength - Length of IP address in bytes.
|
||||
Ip1 - IP address to check.
|
||||
Ip2 - IP address to check.
|
||||
SubnetMask - Subnet mask to check with.
|
||||
|
||||
Returns:
|
||||
TRUE - IP addresses are on the same subnet.
|
||||
FALSE - IP addresses are on different subnets.
|
||||
|
||||
--*/
|
||||
{
|
||||
if (IpLength == 0 || Ip1 == NULL || Ip2 == NULL || SubnetMask == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (IpLength-- != 0) {
|
||||
if ((Ip1->v6.Addr[IpLength] ^ Ip2->v6.Addr[IpLength]) & SubnetMask->v6.Addr[IpLength]) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
VOID
|
||||
IpAddRouter (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN EFI_IP_ADDRESS *RouterIpPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Add router to router table.
|
||||
|
||||
Arguments:
|
||||
Private - Pointer PxeBc instance data.
|
||||
RouterIpPtr - Pointer to router IP address.
|
||||
|
||||
Returns:
|
||||
Nothing
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
UINTN Index;
|
||||
|
||||
if (Private == NULL || RouterIpPtr == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
|
||||
//
|
||||
// if we are filled up or this is not on the same subnet, forget it
|
||||
//
|
||||
if ((PxeBcMode->RouteTableEntries == PXE_ROUTER_TABLE_SIZE) ||
|
||||
!OnSameSubnet(Private->IpLength, &PxeBcMode->StationIp, RouterIpPtr, &PxeBcMode->SubnetMask)) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// make sure we don't already have it
|
||||
//
|
||||
for (Index = 0; Index < PxeBcMode->RouteTableEntries; ++Index) {
|
||||
if (!CompareMem (
|
||||
&PxeBcMode->RouteTable[Index].GwAddr,
|
||||
RouterIpPtr,
|
||||
Private->IpLength
|
||||
)) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
//
|
||||
// keep it
|
||||
//
|
||||
ZeroMem (
|
||||
&PxeBcMode->RouteTable[PxeBcMode->RouteTableEntries],
|
||||
sizeof (EFI_PXE_BASE_CODE_ROUTE_ENTRY)
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&PxeBcMode->RouteTable[PxeBcMode->RouteTableEntries++].GwAddr,
|
||||
RouterIpPtr,
|
||||
Private->IpLength
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//
|
||||
// return router ip to use for DestIp (0 if none)
|
||||
//
|
||||
STATIC
|
||||
EFI_IP_ADDRESS *
|
||||
GetRouterIp (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
EFI_IP_ADDRESS *DestIpPtr
|
||||
)
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
UINTN Index;
|
||||
|
||||
if (Private == NULL || DestIpPtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
|
||||
for (Index = 0; Index < PxeBcMode->RouteTableEntries; ++Index) {
|
||||
if (OnSameSubnet (
|
||||
Private->IpLength,
|
||||
&PxeBcMode->RouteTable[Index].IpAddr,
|
||||
DestIpPtr,
|
||||
&PxeBcMode->RouteTable[Index].SubnetMask
|
||||
)) {
|
||||
return &PxeBcMode->RouteTable[Index].GwAddr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//
|
||||
// routine to send ipv4 packet
|
||||
// ipv4 header of length HdrLth in TransmitBufferPtr
|
||||
// routine fills in ipv4hdr Ver_Hdl, TotalLength, and Checksum, moves in Data
|
||||
// and gets dest MAC address
|
||||
//
|
||||
#define IP_TX_BUFFER ((IPV4_BUFFER *) Private->TransmitBufferPtr)
|
||||
#define IP_TX_HEADER IP_TX_BUFFER->IpHeader
|
||||
|
||||
EFI_STATUS
|
||||
Ipv4Xmt (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINT32 GatewayIp,
|
||||
UINTN IpHeaderLength,
|
||||
UINTN TotalHeaderLength,
|
||||
VOID *Data,
|
||||
UINTN DataLength,
|
||||
EFI_PXE_BASE_CODE_FUNCTION Function
|
||||
)
|
||||
{
|
||||
EFI_MAC_ADDRESS DestMac;
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
EFI_STATUS StatCode;
|
||||
UINTN PacketLength;
|
||||
|
||||
Snp = Private->SimpleNetwork;
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
StatCode = EFI_SUCCESS;
|
||||
PacketLength = TotalHeaderLength + DataLength;
|
||||
|
||||
//
|
||||
// get dest MAC address
|
||||
// multicast - convert to hw equiv
|
||||
// unicast on same net, use arp
|
||||
// on different net, arp for router
|
||||
//
|
||||
if (IP_TX_HEADER.DestAddr.L == BROADCAST_IPv4) {
|
||||
CopyMem (&DestMac, &Snp->Mode->BroadcastAddress, sizeof (DestMac));
|
||||
} else if (IS_MULTICAST (&IP_TX_HEADER.DestAddr)) {
|
||||
StatCode = (*Snp->MCastIpToMac) (Snp, PxeBcMode->UsingIpv6, (EFI_IP_ADDRESS *) &IP_TX_HEADER.DestAddr, &DestMac);
|
||||
} else {
|
||||
UINT32 Ip;
|
||||
|
||||
if (OnSameSubnet (
|
||||
Private->IpLength,
|
||||
&PxeBcMode->StationIp,
|
||||
(EFI_IP_ADDRESS *) &IP_TX_HEADER.DestAddr,
|
||||
&PxeBcMode->SubnetMask
|
||||
)) {
|
||||
Ip = IP_TX_HEADER.DestAddr.L;
|
||||
} else if (GatewayIp != 0) {
|
||||
Ip = GatewayIp;
|
||||
} else {
|
||||
EFI_IP_ADDRESS *TmpIp;
|
||||
|
||||
TmpIp = GetRouterIp (Private, (EFI_IP_ADDRESS *) &IP_TX_HEADER.DestAddr);
|
||||
|
||||
if (TmpIp == NULL) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nIpv4Xmit() Exit #1 %xh (%r)",
|
||||
EFI_NO_RESPONSE,
|
||||
EFI_NO_RESPONSE)
|
||||
);
|
||||
|
||||
return EFI_NO_RESPONSE;
|
||||
//
|
||||
// no router
|
||||
//
|
||||
}
|
||||
|
||||
Ip = TmpIp->Addr[0];
|
||||
}
|
||||
|
||||
if (!GetHwAddr (
|
||||
Private,
|
||||
(EFI_IP_ADDRESS *) &Ip,
|
||||
(EFI_MAC_ADDRESS *) &DestMac
|
||||
)) {
|
||||
if (!PxeBcMode->AutoArp) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nIpv4Xmit() Exit #2 %xh (%r)",
|
||||
EFI_DEVICE_ERROR,
|
||||
EFI_DEVICE_ERROR)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
} else {
|
||||
StatCode = DoArp (
|
||||
Private,
|
||||
(EFI_IP_ADDRESS *) &Ip,
|
||||
(EFI_MAC_ADDRESS *) &DestMac
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
DEBUG ((EFI_D_WARN, "\nIpv4Xmit() Exit #3 %xh (%r)", StatCode, StatCode));
|
||||
return StatCode;
|
||||
}
|
||||
//
|
||||
// fill in packet info
|
||||
//
|
||||
SET_IPV4_VER_HDL (&IP_TX_HEADER, IpHeaderLength);
|
||||
IP_TX_HEADER.TotalLength = HTONS (PacketLength);
|
||||
IP_TX_HEADER.HeaderChecksum = IpChecksum ((UINT16 *) &IP_TX_HEADER, IpHeaderLength);
|
||||
CopyMem (((UINT8 *) &IP_TX_HEADER) + TotalHeaderLength, Data, DataLength);
|
||||
|
||||
//
|
||||
// send it
|
||||
//
|
||||
return SendPacket (
|
||||
Private,
|
||||
(UINT8 *) &IP_TX_HEADER - Snp->Mode->MediaHeaderSize,
|
||||
&IP_TX_HEADER,
|
||||
PacketLength,
|
||||
&DestMac,
|
||||
PXE_PROTOCOL_ETHERNET_IP,
|
||||
Function
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//
|
||||
// send ipv4 packet with option
|
||||
//
|
||||
EFI_STATUS
|
||||
Ipv4SendWOp (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
UINT32 GatewayIp,
|
||||
UINT8 *Msg,
|
||||
UINTN MessageLength,
|
||||
UINT8 Prot,
|
||||
UINT8 *Option,
|
||||
UINTN OptionLength,
|
||||
UINT32 DestIp,
|
||||
EFI_PXE_BASE_CODE_FUNCTION Function
|
||||
)
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
UINTN HdrLth;
|
||||
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
HdrLth = sizeof (IPV4_HEADER) + OptionLength;
|
||||
|
||||
ZeroMem ((VOID *) &IP_TX_HEADER, sizeof (IPV4_HEADER));
|
||||
IP_TX_HEADER.TimeToLive = PxeBcMode->TTL;
|
||||
IP_TX_HEADER.TypeOfService = PxeBcMode->ToS;
|
||||
IP_TX_HEADER.Protocol = Prot;
|
||||
IP_TX_HEADER.SrcAddr.L = *(UINT32 *) &PxeBcMode->StationIp;
|
||||
IP_TX_HEADER.DestAddr.L = DestIp;
|
||||
IP_TX_HEADER.Id = Random (Private);
|
||||
CopyMem (IP_TX_BUFFER->u.Data, Option, OptionLength);
|
||||
return Ipv4Xmt (
|
||||
Private,
|
||||
GatewayIp,
|
||||
HdrLth,
|
||||
HdrLth,
|
||||
Msg,
|
||||
MessageLength,
|
||||
Function
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//
|
||||
// send MessageLength message at MessagePtr - higher level protocol header already in TransmitBufferPtr, length HdrSize
|
||||
//
|
||||
EFI_STATUS
|
||||
Ip4Send (
|
||||
PXE_BASECODE_DEVICE *Private, // pointer to instance data
|
||||
UINTN MayFrag, //
|
||||
UINT8 Prot, // protocol
|
||||
UINT32 SrcIp, // Source IP address
|
||||
UINT32 DestIp, // Destination IP address
|
||||
UINT32 GatewayIp, // used if not NULL and needed
|
||||
UINTN HdrSize, // protocol header byte length
|
||||
UINT8 *MessagePtr, // pointer to data
|
||||
UINTN MessageLength // data byte length
|
||||
)
|
||||
{
|
||||
EFI_STATUS StatCode;
|
||||
UINTN TotDataLength;
|
||||
|
||||
TotDataLength = HdrSize + MessageLength;
|
||||
|
||||
if (TotDataLength > MAX_IPV4_DATA_SIZE) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nIp4Send() Exit #1 %xh (%r)",
|
||||
EFI_BAD_BUFFER_SIZE,
|
||||
EFI_BAD_BUFFER_SIZE)
|
||||
);
|
||||
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
ZeroMem ((VOID *) &IP_TX_HEADER, sizeof (IPV4_HEADER));
|
||||
IP_TX_HEADER.TimeToLive = DEFAULT_TTL;
|
||||
IP_TX_HEADER.Protocol = Prot;
|
||||
IP_TX_HEADER.SrcAddr.L = SrcIp;
|
||||
IP_TX_HEADER.DestAddr.L = DestIp;
|
||||
IP_TX_HEADER.Id = Random (Private);
|
||||
|
||||
if (!MayFrag) {
|
||||
*(UINT8 *) (&IP_TX_HEADER.FragmentFields) = IP_NO_FRAG >> 8;
|
||||
}
|
||||
//
|
||||
// check for need to fragment
|
||||
//
|
||||
if (TotDataLength > MAX_IPV4_FRAME_DATA_SIZE) {
|
||||
UINTN DataLengthSent;
|
||||
UINT16 FragmentOffset;
|
||||
|
||||
FragmentOffset = IP_MORE_FRAG;
|
||||
//
|
||||
// frag offset field
|
||||
//
|
||||
if (!MayFrag) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nIp4Send() Exit #2 %xh (%r)",
|
||||
EFI_BAD_BUFFER_SIZE,
|
||||
EFI_BAD_BUFFER_SIZE)
|
||||
);
|
||||
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
//
|
||||
// send out in fragments - first includes upper level header
|
||||
// all are max and include more frag bit except last
|
||||
//
|
||||
* (UINT8 *) (&IP_TX_HEADER.FragmentFields) = IP_MORE_FRAG >> 8;
|
||||
|
||||
#define IPV4_FRAG_SIZE (MAX_IPV4_FRAME_DATA_SIZE & 0xfff8)
|
||||
#define IPV4_FRAG_OFF_INC (IPV4_FRAG_SIZE >> 3)
|
||||
|
||||
DataLengthSent = IPV4_FRAG_SIZE - HdrSize;
|
||||
|
||||
StatCode = Ipv4Xmt (
|
||||
Private,
|
||||
GatewayIp,
|
||||
sizeof (IPV4_HEADER),
|
||||
sizeof (IPV4_HEADER) + HdrSize,
|
||||
MessagePtr,
|
||||
DataLengthSent,
|
||||
Private->Function
|
||||
);
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nIp4Send() Exit #3 %xh (%r)",
|
||||
StatCode,
|
||||
StatCode)
|
||||
);
|
||||
|
||||
return StatCode;
|
||||
}
|
||||
|
||||
MessagePtr += DataLengthSent;
|
||||
MessageLength -= DataLengthSent;
|
||||
FragmentOffset += IPV4_FRAG_OFF_INC;
|
||||
IP_TX_HEADER.FragmentFields = HTONS (FragmentOffset);
|
||||
|
||||
while (MessageLength > IPV4_FRAG_SIZE) {
|
||||
StatCode = Ipv4Xmt (
|
||||
Private,
|
||||
GatewayIp,
|
||||
sizeof (IPV4_HEADER),
|
||||
sizeof (IPV4_HEADER),
|
||||
MessagePtr,
|
||||
IPV4_FRAG_SIZE,
|
||||
Private->Function
|
||||
);
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nIp4Send() Exit #3 %xh (%r)",
|
||||
StatCode,
|
||||
StatCode)
|
||||
);
|
||||
|
||||
return StatCode;
|
||||
}
|
||||
|
||||
MessagePtr += IPV4_FRAG_SIZE;
|
||||
MessageLength -= IPV4_FRAG_SIZE;
|
||||
FragmentOffset += IPV4_FRAG_OFF_INC;
|
||||
IP_TX_HEADER.FragmentFields = HTONS (FragmentOffset);
|
||||
}
|
||||
|
||||
* (UINT8 *) (&IP_TX_HEADER.FragmentFields) &= ~(IP_MORE_FRAG >> 8);
|
||||
HdrSize = 0;
|
||||
}
|
||||
//
|
||||
// transmit
|
||||
//
|
||||
return Ipv4Xmt (
|
||||
Private,
|
||||
GatewayIp,
|
||||
sizeof (IPV4_HEADER),
|
||||
sizeof (IPV4_HEADER) + HdrSize,
|
||||
MessagePtr,
|
||||
MessageLength,
|
||||
Private->Function
|
||||
);
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//
|
||||
// return true if dst IP in receive header matched with what's enabled
|
||||
//
|
||||
STATIC
|
||||
BOOLEAN
|
||||
IPgood (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
IPV4_HEADER *IpHeader
|
||||
)
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
UINTN Index;
|
||||
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
|
||||
if (PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) &&
|
||||
IS_MULTICAST (&IpHeader->DestAddr)
|
||||
) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) &&
|
||||
PxeBcMode->StationIp.Addr[0] == IpHeader->DestAddr.L
|
||||
) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((PxeBcMode->IpFilter.Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) && IpHeader->DestAddr.L == BROADCAST_IPv4) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < PxeBcMode->IpFilter.IpCnt; ++Index) {
|
||||
if (IpHeader->DestAddr.L == PxeBcMode->IpFilter.IpList[Index].Addr[0]) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
//
|
||||
// receive up to MessageLength message into MessagePtr for protocol Prot
|
||||
// return message length, src/dest ips if select any, and pointer to protocol
|
||||
// header routine will filter based on source and/or dest ip if OpFlags set.
|
||||
//
|
||||
EFI_STATUS
|
||||
IpReceive (
|
||||
PXE_BASECODE_DEVICE *Private,
|
||||
PXE_OPFLAGS OpFlags,
|
||||
EFI_IP_ADDRESS *SrcIpPtr,
|
||||
EFI_IP_ADDRESS *DestIpPtr,
|
||||
UINT8 Prot,
|
||||
VOID *HeaderPtr,
|
||||
UINTN HdrSize,
|
||||
UINT8 *MessagePtr,
|
||||
UINTN *MessageLengthPtr,
|
||||
EFI_EVENT TimeoutEvent
|
||||
)
|
||||
{
|
||||
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
|
||||
EFI_STATUS StatCode;
|
||||
UINTN ByteCount;
|
||||
UINTN FragmentCount;
|
||||
UINTN ExpectedPacketLength;
|
||||
UINTN Id;
|
||||
BOOLEAN GotFirstFragment;
|
||||
BOOLEAN GotLastFragment;
|
||||
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nIpReceive() Hdr=%Xh HdrSz=%d Data=%Xh DataSz=%d",
|
||||
HeaderPtr,
|
||||
HdrSize,
|
||||
MessagePtr,
|
||||
*MessageLengthPtr)
|
||||
);
|
||||
|
||||
PxeBcMode = Private->EfiBc.Mode;
|
||||
PxeBcMode->IcmpErrorReceived = FALSE;
|
||||
|
||||
ExpectedPacketLength = 0;
|
||||
GotFirstFragment = FALSE;
|
||||
GotLastFragment = FALSE;
|
||||
FragmentCount = 0;
|
||||
ByteCount = 0;
|
||||
Id = 0;
|
||||
|
||||
for (;;) {
|
||||
IPV4_HEADER IpHdr;
|
||||
UINTN FFlds;
|
||||
UINTN TotalLength;
|
||||
UINTN FragmentOffset;
|
||||
UINTN HeaderSize;
|
||||
UINTN BufferSize;
|
||||
UINTN IpHeaderLength;
|
||||
UINTN DataLength;
|
||||
UINT16 Protocol;
|
||||
UINT8 *NextHdrPtr;
|
||||
UINT8 *PacketPtr;
|
||||
|
||||
StatCode = WaitForReceive (
|
||||
Private,
|
||||
Private->Function,
|
||||
TimeoutEvent,
|
||||
&HeaderSize,
|
||||
&BufferSize,
|
||||
&Protocol
|
||||
);
|
||||
|
||||
if (EFI_ERROR (StatCode)) {
|
||||
return StatCode;
|
||||
}
|
||||
|
||||
PacketPtr = Private->ReceiveBufferPtr + HeaderSize;
|
||||
|
||||
if (Protocol == PXE_PROTOCOL_ETHERNET_ARP) {
|
||||
HandleArpReceive (
|
||||
Private,
|
||||
(ARP_PACKET *) PacketPtr,
|
||||
Private->ReceiveBufferPtr
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Protocol != PXE_PROTOCOL_ETHERNET_IP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if SUPPORT_IPV6
|
||||
if (PxeBcMode->UsingIpv6) {
|
||||
//
|
||||
// TBD
|
||||
//
|
||||
}
|
||||
#endif
|
||||
|
||||
#define IpRxHeader ((IPV4_HEADER *) PacketPtr)
|
||||
|
||||
//
|
||||
// filter for version & check sum
|
||||
//
|
||||
IpHeaderLength = IPV4_HEADER_LENGTH (IpRxHeader);
|
||||
|
||||
if ((IpRxHeader->VersionIhl >> 4) != IPVER4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IpChecksum ((UINT16 *) IpRxHeader, IpHeaderLength)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CopyMem (&IpHdr, IpRxHeader, sizeof (IpHdr));
|
||||
//IpHdr = *IpRxHeader;
|
||||
TotalLength = NTOHS (IpHdr.TotalLength);
|
||||
|
||||
if (IpHdr.Protocol == PROT_TCP) {
|
||||
//
|
||||
// The NextHdrPtr is used to seed the header buffer we are passing back.
|
||||
// That being the case, we want to see everything in pPkt which contains
|
||||
// everything but the ethernet (or whatever) frame. IP + TCP in this case.
|
||||
//
|
||||
DataLength = TotalLength;
|
||||
NextHdrPtr = PacketPtr;
|
||||
} else {
|
||||
DataLength = TotalLength - IpHeaderLength;
|
||||
NextHdrPtr = PacketPtr + IpHeaderLength;
|
||||
}
|
||||
//
|
||||
// If this is an ICMP, it might not be for us.
|
||||
// Double check the state of the IP stack and the
|
||||
// packet fields before assuming it is an ICMP
|
||||
// error. ICMP requests are not supported by the
|
||||
// PxeBc IP stack and should be ignored.
|
||||
//
|
||||
if (IpHdr.Protocol == PROT_ICMP) {
|
||||
ICMPV4_HEADER *Icmpv4;
|
||||
|
||||
Icmpv4 = (ICMPV4_HEADER *) NextHdrPtr;
|
||||
|
||||
//
|
||||
// For now only obvious ICMP error replies will be accepted by
|
||||
// this stack. This still makes us vulnerable to DoS attacks.
|
||||
// But at least we will not be killed by DHCP daemons.
|
||||
//
|
||||
switch (Icmpv4->Type) {
|
||||
case ICMP_REDIRECT:
|
||||
case ICMP_ECHO:
|
||||
case ICMP_ROUTER_ADV:
|
||||
case ICMP_ROUTER_SOLICIT:
|
||||
case ICMP_TIMESTAMP:
|
||||
case ICMP_TIMESTAMP_REPLY:
|
||||
case ICMP_INFO_REQ:
|
||||
case ICMP_INFO_REQ_REPLY:
|
||||
case ICMP_SUBNET_MASK_REQ:
|
||||
case ICMP_SUBNET_MASK_REPLY:
|
||||
default:
|
||||
continue;
|
||||
|
||||
//
|
||||
// %%TBD - This should be implemented.
|
||||
//
|
||||
case ICMP_ECHO_REPLY:
|
||||
continue;
|
||||
|
||||
case ICMP_DEST_UNREACHABLE:
|
||||
case ICMP_TIME_EXCEEDED:
|
||||
case ICMP_PARAMETER_PROBLEM:
|
||||
case ICMP_SOURCE_QUENCH:
|
||||
PxeBcMode->IcmpErrorReceived = TRUE;
|
||||
|
||||
CopyMem (
|
||||
&PxeBcMode->IcmpError,
|
||||
NextHdrPtr,
|
||||
sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)
|
||||
);
|
||||
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nIpReceive() Exit #1 %Xh (%r)",
|
||||
EFI_ICMP_ERROR,
|
||||
EFI_ICMP_ERROR)
|
||||
);
|
||||
}
|
||||
|
||||
return EFI_ICMP_ERROR;
|
||||
}
|
||||
|
||||
if (IpHdr.Protocol == PROT_IGMP) {
|
||||
HandleIgmp (Private, (IGMPV2_MESSAGE *) NextHdrPtr, DataLength);
|
||||
|
||||
DEBUG ((EFI_D_NET, "\n IGMP"));
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// check for protocol
|
||||
//
|
||||
if (IpHdr.Protocol != Prot) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// do filtering
|
||||
//
|
||||
if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr && SrcIpPtr->Addr[0] != IpHdr.SrcAddr.L) {
|
||||
DEBUG ((EFI_D_NET, "\n Not expected source IP address."));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) {
|
||||
if (!IPgood (Private, &IpHdr)) {
|
||||
continue;
|
||||
}
|
||||
} else if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP)) {
|
||||
if (DestIpPtr == NULL) {
|
||||
if (PxeBcMode->StationIp.Addr[0] != IpHdr.DestAddr.L) {
|
||||
continue;
|
||||
}
|
||||
} else if (DestIpPtr->Addr[0] != IpHdr.DestAddr.L) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//
|
||||
// get some data we need
|
||||
//
|
||||
FFlds = NTOHS (IpHdr.FragmentFields);
|
||||
FragmentOffset = ((FFlds & IP_FRAG_OFF_MSK) << 3);
|
||||
|
||||
/* Keep count of fragments that belong to this session.
|
||||
* If we get packets with a different IP ID number,
|
||||
* ignore them. Ignored packets should be handled
|
||||
* by the upper level protocol.
|
||||
*/
|
||||
if (FragmentCount == 0) {
|
||||
Id = IpHdr.Id;
|
||||
|
||||
if (DestIpPtr != NULL) {
|
||||
DestIpPtr->Addr[0] = IpHdr.DestAddr.L;
|
||||
}
|
||||
|
||||
if (SrcIpPtr != NULL) {
|
||||
SrcIpPtr->Addr[0] = IpHdr.SrcAddr.L;
|
||||
}
|
||||
} else {
|
||||
if (IpHdr.Id != Id) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
++FragmentCount;
|
||||
|
||||
/* Fragment management.
|
||||
*/
|
||||
if (FragmentOffset == 0) {
|
||||
/* This is the first fragment (may also be the
|
||||
* only fragment).
|
||||
*/
|
||||
GotFirstFragment = TRUE;
|
||||
|
||||
/* If there is a separate protocol header buffer,
|
||||
* copy the header, adjust the data pointer and
|
||||
* the data length.
|
||||
*/
|
||||
if (HdrSize != 0) {
|
||||
CopyMem (HeaderPtr, NextHdrPtr, HdrSize);
|
||||
|
||||
NextHdrPtr += HdrSize;
|
||||
DataLength -= HdrSize;
|
||||
}
|
||||
} else {
|
||||
/* If there is a separate protocol header buffer,
|
||||
* adjust the fragment offset.
|
||||
*/
|
||||
FragmentOffset -= HdrSize;
|
||||
}
|
||||
|
||||
/* See if this is the last fragment.
|
||||
*/
|
||||
if (!(FFlds & IP_MORE_FRAG)) {
|
||||
//
|
||||
// This is the last fragment (may also be the only fragment).
|
||||
//
|
||||
GotLastFragment = TRUE;
|
||||
|
||||
/* Compute the expected length of the assembled
|
||||
* packet. This will be used to decide if we
|
||||
* have gotten all of the fragments.
|
||||
*/
|
||||
ExpectedPacketLength = FragmentOffset + DataLength;
|
||||
}
|
||||
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\n ID = %Xh Off = %d Len = %d",
|
||||
Id,
|
||||
FragmentOffset,
|
||||
DataLength)
|
||||
);
|
||||
|
||||
/* Check for receive buffer overflow.
|
||||
*/
|
||||
if (FragmentOffset + DataLength > *MessageLengthPtr) {
|
||||
/* There is not enough space in the receive
|
||||
* buffer for the fragment.
|
||||
*/
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nIpReceive() Exit #3 %Xh (%r)",
|
||||
EFI_BUFFER_TOO_SMALL,
|
||||
EFI_BUFFER_TOO_SMALL)
|
||||
);
|
||||
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Copy data into receive buffer.
|
||||
*/
|
||||
if (DataLength != 0) {
|
||||
DEBUG ((EFI_D_NET, " To = %Xh", MessagePtr + FragmentOffset));
|
||||
|
||||
CopyMem (MessagePtr + FragmentOffset, NextHdrPtr, DataLength);
|
||||
ByteCount += DataLength;
|
||||
}
|
||||
|
||||
/* If we have seen the first and last fragments and
|
||||
* the receive byte count is at least as large as the
|
||||
* expected byte count, return SUCCESS.
|
||||
*
|
||||
* We could be tricked by receiving a fragment twice
|
||||
* but the upper level protocol should figure this
|
||||
* out.
|
||||
*/
|
||||
if (GotFirstFragment && GotLastFragment && ByteCount >= ExpectedPacketLength) {
|
||||
*MessageLengthPtr = ExpectedPacketLength;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* eof - pxe_bc_ip.c */
|
2391
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_mtftp.c
Normal file
2391
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_mtftp.c
Normal file
File diff suppressed because it is too large
Load Diff
577
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_udp.c
Normal file
577
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_bc_udp.c
Normal file
@@ -0,0 +1,577 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
pxe_bc_udp.c
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "bc.h"
|
||||
|
||||
//
|
||||
// //////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Udp Write Routine - called by base code - e.g. TFTP - already locked
|
||||
//
|
||||
EFI_STATUS
|
||||
UdpWrite (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN UINT16 OpFlags,
|
||||
IN EFI_IP_ADDRESS *DestIpPtr,
|
||||
IN EFI_PXE_BASE_CODE_UDP_PORT *DestPortPtr,
|
||||
IN EFI_IP_ADDRESS *GatewayIpPtr, OPTIONAL
|
||||
IN EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL
|
||||
IN UINTN *HeaderSizePtr, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN UINTN *BufferSizeptr,
|
||||
IN VOID *BufferPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
UDP write packet.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
OpFlags :=
|
||||
DestIpPtr :=
|
||||
DestPortPtr :=
|
||||
GatewayIpPtr :=
|
||||
SrcIpPtr :=
|
||||
SrcPortPtr :=
|
||||
HeaderSizePtr :=
|
||||
HeaderPtr :=
|
||||
BufferSizeptr :=
|
||||
BufferPtr :=
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS :=
|
||||
EFI_INVALID_PARAMETER :=
|
||||
other :=
|
||||
--*/
|
||||
{
|
||||
UINTN TotalLength;
|
||||
UINTN HeaderSize;
|
||||
EFI_PXE_BASE_CODE_UDP_PORT DefaultSrcPort;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;
|
||||
DefaultSrcPort = 0;
|
||||
|
||||
//
|
||||
// check parameters
|
||||
//
|
||||
if (BufferSizeptr == NULL ||
|
||||
BufferPtr == NULL ||
|
||||
DestIpPtr == NULL ||
|
||||
DestPortPtr == NULL ||
|
||||
(HeaderSizePtr != NULL && *HeaderSizePtr == 0) ||
|
||||
(HeaderSize != 0 && HeaderPtr == NULL) ||
|
||||
(GatewayIpPtr != NULL && !IS_INADDR_UNICAST(GatewayIpPtr)) ||
|
||||
(OpFlags &~(EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT))
|
||||
) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nUdpWrite() Exit #1 %xh (%r)",
|
||||
EFI_INVALID_PARAMETER,
|
||||
EFI_INVALID_PARAMETER)
|
||||
);
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
TotalLength = *BufferSizeptr + HeaderSize + sizeof (UDPV4_HEADER);
|
||||
|
||||
if (TotalLength > 0x0000ffff) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nUdpWrite() Exit #2 %xh (%r)",
|
||||
EFI_BAD_BUFFER_SIZE,
|
||||
EFI_BAD_BUFFER_SIZE)
|
||||
);
|
||||
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (SrcIpPtr == NULL) {
|
||||
SrcIpPtr = &Private->EfiBc.Mode->StationIp;
|
||||
}
|
||||
|
||||
if (SrcPortPtr == NULL) {
|
||||
SrcPortPtr = &DefaultSrcPort;
|
||||
OpFlags |= EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT;
|
||||
}
|
||||
|
||||
if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) {
|
||||
*SrcPortPtr = Private->RandomPort;
|
||||
|
||||
if (++Private->RandomPort == 0) {
|
||||
Private->RandomPort = PXE_RND_PORT_LOW;
|
||||
}
|
||||
}
|
||||
|
||||
#define IpTxBuffer ((IPV4_BUFFER *) Private->TransmitBufferPtr)
|
||||
//
|
||||
// build pseudo header and udp header in transmit buffer
|
||||
//
|
||||
#define Udpv4Base ((UDPV4_HEADERS *) (IpTxBuffer->u.Data - sizeof (UDPV4_PSEUDO_HEADER)))
|
||||
|
||||
Udpv4Base->Udpv4PseudoHeader.SrcAddr.L = SrcIpPtr->Addr[0];
|
||||
Udpv4Base->Udpv4PseudoHeader.DestAddr.L = DestIpPtr->Addr[0];
|
||||
Udpv4Base->Udpv4PseudoHeader.Zero = 0;
|
||||
Udpv4Base->Udpv4PseudoHeader.Protocol = PROT_UDP;
|
||||
Udpv4Base->Udpv4PseudoHeader.TotalLength = HTONS (TotalLength);
|
||||
Udpv4Base->Udpv4Header.SrcPort = HTONS (*SrcPortPtr);
|
||||
Udpv4Base->Udpv4Header.DestPort = HTONS (*DestPortPtr);
|
||||
Udpv4Base->Udpv4Header.TotalLength = Udpv4Base->Udpv4PseudoHeader.TotalLength;
|
||||
Udpv4Base->Udpv4Header.Checksum = 0;
|
||||
|
||||
if (HeaderSize != 0) {
|
||||
CopyMem (IpTxBuffer->u.Udp.Data, HeaderPtr, HeaderSize);
|
||||
}
|
||||
|
||||
HeaderSize += sizeof (UDPV4_HEADER);
|
||||
|
||||
Udpv4Base->Udpv4Header.Checksum = IpChecksum2 (
|
||||
(UINT16 *) Udpv4Base,
|
||||
HeaderSize + sizeof (UDPV4_PSEUDO_HEADER),
|
||||
(UINT16 *) BufferPtr,
|
||||
(UINT16) *BufferSizeptr
|
||||
);
|
||||
|
||||
if (Udpv4Base->Udpv4Header.Checksum == 0) {
|
||||
Udpv4Base->Udpv4Header.Checksum = 0xffff;
|
||||
//
|
||||
// transmit zero checksum as ones complement
|
||||
//
|
||||
}
|
||||
|
||||
return Ip4Send (
|
||||
Private,
|
||||
OpFlags,
|
||||
PROT_UDP,
|
||||
Udpv4Base->Udpv4PseudoHeader.SrcAddr.L,
|
||||
Udpv4Base->Udpv4PseudoHeader.DestAddr.L,
|
||||
(GatewayIpPtr) ? GatewayIpPtr->Addr[0] : 0,
|
||||
HeaderSize,
|
||||
BufferPtr,
|
||||
*BufferSizeptr
|
||||
);
|
||||
}
|
||||
//
|
||||
// //////////////////////////////////////////////////////////
|
||||
//
|
||||
// BC Udp Write Routine
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcUdpWrite (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
|
||||
IN UINT16 OpFlags,
|
||||
IN EFI_IP_ADDRESS *DestIpPtr,
|
||||
IN EFI_PXE_BASE_CODE_UDP_PORT *DestPortPtr,
|
||||
IN EFI_IP_ADDRESS *GatewayIpPtr, OPTIONAL
|
||||
IN EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL
|
||||
IN UINTN *HeaderSizePtr, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN UINTN *BufferSizeptr,
|
||||
IN VOID *BufferPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
UDP write API entry point.
|
||||
|
||||
Parameters:
|
||||
This := Pointer to PxeBc interface.
|
||||
OpFlags :=
|
||||
DestIpPtr :=
|
||||
DestPortPtr :=
|
||||
GatewayIpPtr :=
|
||||
SrcIpPtr :=
|
||||
SrcPortPtr :=
|
||||
HeaderSizePtr :=
|
||||
HeaderPtr :=
|
||||
BufferSizeptr :=
|
||||
BufferPtr :=
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS :=
|
||||
other :=
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS StatCode;
|
||||
PXE_BASECODE_DEVICE *Private;
|
||||
|
||||
//
|
||||
// Lock the instance data and make sure started
|
||||
//
|
||||
StatCode = EFI_SUCCESS;
|
||||
|
||||
if (This == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
|
||||
|
||||
if (Private == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EfiAcquireLock (&Private->Lock);
|
||||
|
||||
if (This->Mode == NULL || !This->Mode->Started) {
|
||||
DEBUG ((EFI_D_ERROR, "BC was not started."));
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Private->Function = EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE;
|
||||
|
||||
//
|
||||
// Issue BC command
|
||||
//
|
||||
StatCode = UdpWrite (
|
||||
Private,
|
||||
OpFlags,
|
||||
DestIpPtr,
|
||||
DestPortPtr,
|
||||
GatewayIpPtr,
|
||||
SrcIpPtr,
|
||||
SrcPortPtr,
|
||||
HeaderSizePtr,
|
||||
HeaderPtr,
|
||||
BufferSizeptr,
|
||||
BufferPtr
|
||||
);
|
||||
|
||||
//
|
||||
// Unlock the instance data
|
||||
//
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return StatCode;
|
||||
}
|
||||
//
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Udp Read Routine - called by base code - e.g. TFTP - already locked
|
||||
//
|
||||
EFI_STATUS
|
||||
UdpRead (
|
||||
IN PXE_BASECODE_DEVICE *Private,
|
||||
IN UINT16 OpFlags,
|
||||
IN OUT EFI_IP_ADDRESS *DestIpPtr, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPortPtr, OPTIONAL
|
||||
IN OUT EFI_IP_ADDRESS *SrcIpPtr, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPortPtr, OPTIONAL
|
||||
IN UINTN *HeaderSizePtr, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN OUT UINTN *BufferSizeptr,
|
||||
IN VOID *BufferPtr,
|
||||
EFI_EVENT TimeoutEvent
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
UDP read packet.
|
||||
|
||||
Parameters:
|
||||
Private := Pointer to PxeBc interface
|
||||
OpFlags :=
|
||||
DestIpPtr :=
|
||||
DestPortPtr :=
|
||||
SrcIpPtr :=
|
||||
SrcPortPtr :=
|
||||
HeaderSizePtr :=
|
||||
HeaderPtr :=
|
||||
BufferSizeptr :=
|
||||
BufferPtr :=
|
||||
TimeoutEvent :=
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS :=
|
||||
EFI_INVALID_PARAMETER :=
|
||||
other :=
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS StatCode;
|
||||
EFI_IP_ADDRESS TmpSrcIp;
|
||||
EFI_IP_ADDRESS TmpDestIp;
|
||||
UINTN BufferSize;
|
||||
UINTN HeaderSize;
|
||||
|
||||
//
|
||||
// combination structure of pseudo header/udp header
|
||||
//
|
||||
#pragma pack (1)
|
||||
struct {
|
||||
UDPV4_PSEUDO_HEADER Udpv4PseudoHeader;
|
||||
UDPV4_HEADER Udpv4Header;
|
||||
UINT8 ProtHdr[64];
|
||||
} Hdrs;
|
||||
#pragma pack ()
|
||||
|
||||
HeaderSize = (HeaderSizePtr != NULL) ? *HeaderSizePtr : 0;
|
||||
//
|
||||
// read [with filtering]
|
||||
// check parameters
|
||||
//
|
||||
if (BufferSizeptr == NULL ||
|
||||
BufferPtr == NULL ||
|
||||
(HeaderSize != 0 && HeaderPtr == NULL) ||
|
||||
(OpFlags &~UDP_FILTER_MASK)
|
||||
//
|
||||
// if filtering on a particular IP/Port, need it
|
||||
//
|
||||
||
|
||||
(!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) && SrcIpPtr == NULL) ||
|
||||
(!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && SrcPortPtr == NULL) ||
|
||||
(!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && DestPortPtr == NULL)
|
||||
) {
|
||||
DEBUG ((EFI_D_INFO, "\nUdpRead() Exit #1 Invalid Parameter"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// in case we loop
|
||||
//
|
||||
BufferSize = *BufferSizeptr;
|
||||
//
|
||||
// we need source and dest IPs for pseudo header
|
||||
//
|
||||
if (SrcIpPtr == NULL) {
|
||||
SrcIpPtr = &TmpSrcIp;
|
||||
}
|
||||
|
||||
if (DestIpPtr == NULL) {
|
||||
DestIpPtr = &TmpDestIp;
|
||||
CopyMem (&TmpDestIp, &Private->EfiBc.Mode->StationIp, sizeof (TmpDestIp));
|
||||
}
|
||||
|
||||
#if SUPPORT_IPV6
|
||||
if (Private->EfiBc.Mode->UsingIpv6) {
|
||||
//
|
||||
// %%TBD
|
||||
//
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
*BufferSizeptr = BufferSize;
|
||||
|
||||
StatCode = IpReceive (
|
||||
Private,
|
||||
OpFlags,
|
||||
SrcIpPtr,
|
||||
DestIpPtr,
|
||||
PROT_UDP,
|
||||
&Hdrs.Udpv4Header,
|
||||
HeaderSize + sizeof Hdrs.Udpv4Header,
|
||||
BufferPtr,
|
||||
BufferSizeptr,
|
||||
TimeoutEvent
|
||||
);
|
||||
|
||||
if (StatCode == EFI_SUCCESS || StatCode == EFI_BUFFER_TOO_SMALL) {
|
||||
UINT16 SPort;
|
||||
UINT16 DPort;
|
||||
|
||||
SPort = NTOHS (Hdrs.Udpv4Header.SrcPort);
|
||||
DPort = NTOHS (Hdrs.Udpv4Header.DestPort);
|
||||
|
||||
//
|
||||
// do filtering
|
||||
//
|
||||
if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && *SrcPortPtr != SPort) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && *DestPortPtr != DPort) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// check checksum
|
||||
//
|
||||
if (StatCode == EFI_SUCCESS && Hdrs.Udpv4Header.Checksum) {
|
||||
Hdrs.Udpv4PseudoHeader.SrcAddr.L = SrcIpPtr->Addr[0];
|
||||
Hdrs.Udpv4PseudoHeader.DestAddr.L = DestIpPtr->Addr[0];
|
||||
Hdrs.Udpv4PseudoHeader.Zero = 0;
|
||||
Hdrs.Udpv4PseudoHeader.Protocol = PROT_UDP;
|
||||
Hdrs.Udpv4PseudoHeader.TotalLength = Hdrs.Udpv4Header.TotalLength;
|
||||
|
||||
if (Hdrs.Udpv4Header.Checksum == 0xffff) {
|
||||
Hdrs.Udpv4Header.Checksum = 0;
|
||||
}
|
||||
|
||||
if (IpChecksum2 (
|
||||
(UINT16 *) &Hdrs.Udpv4PseudoHeader,
|
||||
HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader) + sizeof (Hdrs.Udpv4Header),
|
||||
(UINT16 *) BufferPtr,
|
||||
*BufferSizeptr
|
||||
)) {
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nUdpRead() Hdrs.Udpv4PseudoHeader == %Xh",
|
||||
&Hdrs.Udpv4PseudoHeader)
|
||||
);
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nUdpRead() Header size == %d",
|
||||
HeaderSize + sizeof (Hdrs.Udpv4PseudoHeader))
|
||||
);
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nUdpRead() BufferPtr == %Xh",
|
||||
BufferPtr)
|
||||
);
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nUdpRead() Buffer size == %d",
|
||||
*BufferSizeptr)
|
||||
);
|
||||
DEBUG ((EFI_D_INFO, "\nUdpRead() Exit #2 Device Error"));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
//
|
||||
// all passed
|
||||
//
|
||||
if (SrcPortPtr != NULL) {
|
||||
*SrcPortPtr = SPort;
|
||||
}
|
||||
|
||||
if (DestPortPtr != NULL) {
|
||||
*DestPortPtr = DPort;
|
||||
}
|
||||
|
||||
if (HeaderSize != 0) {
|
||||
CopyMem (HeaderPtr, Hdrs.ProtHdr, HeaderSize);
|
||||
}
|
||||
}
|
||||
|
||||
switch (StatCode) {
|
||||
case EFI_SUCCESS:
|
||||
case EFI_TIMEOUT:
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nUdpRead() Exit #3 %Xh %r",
|
||||
StatCode,
|
||||
StatCode)
|
||||
);
|
||||
}
|
||||
|
||||
return StatCode;
|
||||
}
|
||||
}
|
||||
//
|
||||
// //////////////////////////////////////////////////////////
|
||||
//
|
||||
// BC Udp Read Routine
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
BcUdpRead (
|
||||
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
|
||||
IN UINT16 OpFlags,
|
||||
IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL
|
||||
IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL
|
||||
IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL
|
||||
IN UINTN *HeaderSize, OPTIONAL
|
||||
IN VOID *HeaderPtr, OPTIONAL
|
||||
IN OUT UINTN *BufferSize,
|
||||
IN VOID *BufferPtr
|
||||
)
|
||||
/*++
|
||||
Routine description:
|
||||
UDP read API entry point.
|
||||
|
||||
Parameters:
|
||||
This := Pointer to PxeBc interface.
|
||||
OpFlags :=
|
||||
DestIpPtr :=
|
||||
DestPortPtr :=
|
||||
SrcIpPtr :=
|
||||
SrcPortPtr :=
|
||||
HeaderSizePtr :=
|
||||
HeaderPtr :=
|
||||
BufferSizeptr :=
|
||||
BufferPtr :=
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS :=
|
||||
other :=
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS StatCode;
|
||||
PXE_BASECODE_DEVICE *Private;
|
||||
|
||||
//
|
||||
// Lock the instance data and make sure started
|
||||
//
|
||||
StatCode = EFI_SUCCESS;
|
||||
|
||||
if (This == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
|
||||
|
||||
if (Private == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EfiAcquireLock (&Private->Lock);
|
||||
|
||||
if (This->Mode == NULL || !This->Mode->Started) {
|
||||
DEBUG ((EFI_D_ERROR, "BC was not started."));
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Private->Function = EFI_PXE_BASE_CODE_FUNCTION_UDP_READ;
|
||||
|
||||
//
|
||||
// Issue BC command
|
||||
//
|
||||
StatCode = UdpRead (
|
||||
Private,
|
||||
OpFlags,
|
||||
DestIp,
|
||||
DestPort,
|
||||
SrcIp,
|
||||
SrcPort,
|
||||
HeaderSize,
|
||||
HeaderPtr,
|
||||
BufferSize,
|
||||
BufferPtr,
|
||||
0
|
||||
);
|
||||
|
||||
//
|
||||
// Unlock the instance data and return
|
||||
//
|
||||
EfiReleaseLock (&Private->Lock);
|
||||
return StatCode;
|
||||
}
|
||||
|
||||
/* eof - pxe_bc_udp.c */
|
1697
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c
Normal file
1697
EdkModulePkg/Universal/Network/PxeBc/Dxe/pxe_loadfile.c
Normal file
File diff suppressed because it is too large
Load Diff
153
EdkModulePkg/Universal/Network/PxeBc/Dxe/tftp.h
Normal file
153
EdkModulePkg/Universal/Network/PxeBc/Dxe/tftp.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
tftp.h
|
||||
|
||||
Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __TFTP_H__
|
||||
#define __TFTP_H__
|
||||
|
||||
//
|
||||
// Definitions for trivial file transfer protocol functionality with IP v4
|
||||
// Per RFC 1350, July 1992 and RFC 2347, 8, and 9, May 1998
|
||||
//
|
||||
#pragma pack(1)
|
||||
//
|
||||
// max and min packet sizes
|
||||
// (all data packets in transmission except last)
|
||||
//
|
||||
#define MAX_TFTP_PKT_SIZE (BUFFER_ALLOCATE_SIZE - 512)
|
||||
#define MIN_TFTP_PKT_SIZE 512
|
||||
|
||||
//
|
||||
// TFTPv4 OpCodes
|
||||
//
|
||||
#define TFTP_RRQ 1 // read request
|
||||
#define TFTP_WRQ 2 // write request
|
||||
#define TFTP_DATA 3 // data
|
||||
#define TFTP_ACK 4 // acknowledgement
|
||||
#define TFTP_ERROR 5 // error packet
|
||||
#define TFTP_OACK 6 // option acknowledge
|
||||
#define TFTP_DIR 7 // read directory request
|
||||
#define TFTP_DATA8 8
|
||||
#define TFTP_ACK8 9
|
||||
|
||||
//
|
||||
// request packet (read or write)
|
||||
// Fields shown (except file name) are not to be referenced directly,
|
||||
// since their placement is variable within a request packet.
|
||||
// All are null terminated case insensitive ascii strings.
|
||||
//
|
||||
struct Tftpv4Req {
|
||||
UINT16 OpCode; // TFTP Op code
|
||||
UINT8 FileName[2]; // file name
|
||||
UINT8 Mode[2]; // "netascii" or "octet"
|
||||
struct { // optionally, one or more option requests
|
||||
UINT8 Option[2]; // option name
|
||||
UINT8 Value[2]; // value requested
|
||||
} OpReq[1];
|
||||
};
|
||||
|
||||
//
|
||||
// modes
|
||||
//
|
||||
#define MODE_ASCII "netascii"
|
||||
#define MODE_BINARY "octet"
|
||||
|
||||
//
|
||||
// option strings
|
||||
//
|
||||
#define OP_BLKSIZE "blksize" // block size option
|
||||
#define OP_TIMEOUT "timeout" // time to wait before retransmitting
|
||||
#define OP_TFRSIZE "tsize" // total transfer size option
|
||||
#define OP_OVERWRITE "overwrite" // overwrite file option
|
||||
#define OP_BIGBLKNUM "bigblk#" // big block number
|
||||
// See RFC 2347, 8, and 9 for more information on TFTP options
|
||||
// option acknowledge packet (optional)
|
||||
// options not acknowledged are rejected
|
||||
//
|
||||
struct Tftpv4Oack {
|
||||
UINT16 OpCode; // TFTP Op code
|
||||
struct { // optionally, one or more option acknowledgements
|
||||
UINT8 Option[2]; // option name (of those requested)
|
||||
UINT8 Value[2]; // value acknowledged
|
||||
} OpAck[1];
|
||||
};
|
||||
|
||||
//
|
||||
// acknowledge packet
|
||||
//
|
||||
struct Tftpv4Ack {
|
||||
UINT16 OpCode; // TFTP Op code
|
||||
UINT16 BlockNum;
|
||||
};
|
||||
|
||||
//
|
||||
// data packet
|
||||
//
|
||||
struct Tftpv4Data {
|
||||
struct Tftpv4Ack Header;
|
||||
UINT8 Data[512];
|
||||
};
|
||||
|
||||
//
|
||||
// big block number ack packet
|
||||
//
|
||||
struct Tftpv4Ack8 {
|
||||
UINT16 OpCode;
|
||||
UINT64 BlockNum;
|
||||
};
|
||||
|
||||
//
|
||||
// big block number data packet
|
||||
//
|
||||
struct Tftpv4Data8 {
|
||||
struct Tftpv4Ack8 Header;
|
||||
UINT8 Data[506];
|
||||
};
|
||||
|
||||
//
|
||||
// error packet
|
||||
//
|
||||
struct Tftpv4Error {
|
||||
UINT16 OpCode; // TFTP Op code
|
||||
UINT16 ErrCode; // error code
|
||||
UINT8 ErrMsg[1]; // error message (nul terminated)
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
//
|
||||
// error codes
|
||||
//
|
||||
#define TFTP_ERR_UNDEF 0 // Not defined, see error message (if any).
|
||||
#define TFTP_ERR_NOT_FOUND 1 // File not found.
|
||||
#define TFTP_ERR_ACCESS 2 // Access violation.
|
||||
#define TFTP_ERR_FULL 3 // Disk full or allocation exceeded.
|
||||
#define TFTP_ERR_ILLEGAL 4 // Illegal TFTP operation.
|
||||
#define TFTP_ERR_BAD_ID 5 // Unknown transfer ID.
|
||||
#define TFTP_ERR_EXISTS 6 // File already exists.
|
||||
#define TFTP_ERR_NO_USER 7 // No such user.
|
||||
#define TFTP_ERR_OPTION 8 // Option negotiation termination
|
||||
//
|
||||
// some defines
|
||||
//
|
||||
#define REQ_RESP_TIMEOUT 5 // Wait five seconds for request response.
|
||||
#define ACK_TIMEOUT 4 // Wait four seconds for ack response.
|
||||
#define NUM_ACK_RETRIES 3
|
||||
#define NUM_MTFTP_OPEN_RETRIES 3
|
||||
|
||||
#endif /* __TFTP_H__ */
|
||||
|
||||
/* EOF - tftp.h */
|
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
160
EdkModulePkg/Universal/Network/Snp32_64/Dxe/ComponentName.c
Normal file
160
EdkModulePkg/Universal/Network/Snp32_64/Dxe/ComponentName.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*++
|
||||
|
||||
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:
|
||||
|
||||
--*/
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetControllerName (
|
||||
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 gSimpleNetworkComponentName = {
|
||||
SimpleNetworkComponentNameGetDriverName,
|
||||
SimpleNetworkComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
static EFI_UNICODE_STRING_TABLE mSimpleNetworkDriverNameTable[] = {
|
||||
{
|
||||
"eng",
|
||||
(CHAR16 *) L"Simple Network Protocol Driver"
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetDriverName (
|
||||
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,
|
||||
gSimpleNetworkComponentName.SupportedLanguages,
|
||||
mSimpleNetworkDriverNameTable,
|
||||
DriverName
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SimpleNetworkComponentNameGetControllerName (
|
||||
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;
|
||||
}
|
41
EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.mbd
Normal file
41
EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.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>SNP</BaseName>
|
||||
<Guid>A2f436EA-A127-4EF8-957C-8048606FF670</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>BaseMemoryLib</Library>
|
||||
<Library>UefiLib</Library>
|
||||
<Library>UefiDriverEntryPoint</Library>
|
||||
<Library>UefiDriverModelLib</Library>
|
||||
<Library>DxeReportStatusCodeLib</Library>
|
||||
<Library>BaseDebugLibReportStatusCode</Library>
|
||||
<Library>BaseLib</Library>
|
||||
<Library>DxeMemoryAllocationLib</Library>
|
||||
</Libraries>
|
||||
</ModuleBuildDescription>
|
85
EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.msa
Normal file
85
EdkModulePkg/Universal/Network/Snp32_64/Dxe/SNP.msa
Normal file
@@ -0,0 +1,85 @@
|
||||
<?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>SNP</BaseName>
|
||||
<ModuleType>UEFI_DRIVER</ModuleType>
|
||||
<ComponentType>BS_DRIVER</ComponentType>
|
||||
<Guid>A2f436EA-A127-4EF8-957C-8048606FF670</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">BaseLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
|
||||
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
|
||||
</LibraryClassDefinitions>
|
||||
<SourceFiles>
|
||||
<Filename>callback.c</Filename>
|
||||
<Filename>get_status.c</Filename>
|
||||
<Filename>initialize.c</Filename>
|
||||
<Filename>mcast_ip_to_mac.c</Filename>
|
||||
<Filename>nvdata.c</Filename>
|
||||
<Filename>receive.c</Filename>
|
||||
<Filename>receive_filters.c</Filename>
|
||||
<Filename>reset.c</Filename>
|
||||
<Filename>shutdown.c</Filename>
|
||||
<Filename>snp.c</Filename>
|
||||
<Filename>snp.h</Filename>
|
||||
<Filename>start.c</Filename>
|
||||
<Filename>station_address.c</Filename>
|
||||
<Filename>statistics.c</Filename>
|
||||
<Filename>stop.c</Filename>
|
||||
<Filename>transmit.c</Filename>
|
||||
<Filename>WaitForPacket.c</Filename>
|
||||
<Filename>ComponentName.c</Filename>
|
||||
</SourceFiles>
|
||||
<Includes>
|
||||
<PackageName>MdePkg</PackageName>
|
||||
<PackageName>EdkModulePkg</PackageName>
|
||||
</Includes>
|
||||
<Protocols>
|
||||
<Protocol Usage="BY_START">SimpleNetwork</Protocol>
|
||||
<Protocol Usage="TO_START">PciIo</Protocol>
|
||||
<Protocol Usage="TO_START">DevicePath</Protocol>
|
||||
<Protocol Usage="SOMETIMES_CONSUMED">NetworkInterfaceIdentifier</Protocol>
|
||||
<Protocol Usage="TO_START">NetworkInterfaceIdentifier2</Protocol>
|
||||
</Protocols>
|
||||
<Externs>
|
||||
<Extern>
|
||||
<ModuleEntryPoint></ModuleEntryPoint>
|
||||
<ModuleUnloadImage></ModuleUnloadImage>
|
||||
</Extern>
|
||||
<Extern>
|
||||
<DriverBinding>mSimpleNetworkDriverBinding</DriverBinding>
|
||||
<ComponentName>gSimpleNetworkComponentName</ComponentName>
|
||||
</Extern>
|
||||
</Externs>
|
||||
</ModuleSurfaceArea>
|
100
EdkModulePkg/Universal/Network/Snp32_64/Dxe/WaitForPacket.c
Normal file
100
EdkModulePkg/Universal/Network/Snp32_64/Dxe/WaitForPacket.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*++
|
||||
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:
|
||||
WaitForPacket.c
|
||||
|
||||
Abstract:
|
||||
Event handler to check for available packet.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpWaitForPacketNotify (
|
||||
EFI_EVENT Event,
|
||||
VOID *SnpPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_DB_GET_STATUS PxeDbGetStatus;
|
||||
|
||||
//
|
||||
// Do nothing if either parameter is a NULL pointer.
|
||||
//
|
||||
if (Event == NULL || SnpPtr == NULL) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Do nothing if the SNP interface is not initialized.
|
||||
//
|
||||
switch (((SNP_DRIVER *) SnpPtr)->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
case EfiSimpleNetworkStarted:
|
||||
default:
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Fill in CDB for UNDI GetStatus().
|
||||
//
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.OpCode = PXE_OPCODE_GET_STATUS;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.OpFlags = 0;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.DBsize = sizeof (UINT32) * 2;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.DBaddr = (UINT64) (UINTN) (((SNP_DRIVER *) SnpPtr)->db);
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.IFnum = ((SNP_DRIVER *) SnpPtr)->if_num;
|
||||
((SNP_DRIVER *) SnpPtr)->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Clear contents of DB buffer.
|
||||
//
|
||||
ZeroMem (((SNP_DRIVER *) SnpPtr)->db, sizeof (UINT32) * 2);
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
(*((SNP_DRIVER *) SnpPtr)->issue_undi32_command) ((UINT64) (UINTN) &((SNP_DRIVER *) SnpPtr)->cdb);
|
||||
|
||||
if (((SNP_DRIVER *) SnpPtr)->cdb.StatCode != EFI_SUCCESS) {
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// We might have a packet. Check the receive length and signal
|
||||
// the event if the length is not zero.
|
||||
//
|
||||
CopyMem (
|
||||
&PxeDbGetStatus,
|
||||
((SNP_DRIVER *) SnpPtr)->db,
|
||||
sizeof (UINT32) * 2
|
||||
);
|
||||
|
||||
if (PxeDbGetStatus.RxFrameLen != 0) {
|
||||
gBS->SignalEvent (Event);
|
||||
}
|
||||
}
|
||||
|
||||
/* eof - WaitForPacket.c */
|
47
EdkModulePkg/Universal/Network/Snp32_64/Dxe/build.xml
Normal file
47
EdkModulePkg/Universal/Network/Snp32_64/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="SNP"><!--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\Snp32_64\Dxe"/>
|
||||
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
|
||||
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
|
||||
<target name="SNP">
|
||||
<GenBuild baseName="SNP" mbdFilename="${MODULE_DIR}\SNP.mbd" msaFilename="${MODULE_DIR}\SNP.msa"/>
|
||||
</target>
|
||||
<target depends="SNP_clean" name="clean"/>
|
||||
<target depends="SNP_cleanall" name="cleanall"/>
|
||||
<target name="SNP_clean">
|
||||
<OutputDirSetup baseName="SNP" mbdFilename="${MODULE_DIR}\SNP.mbd" msaFilename="${MODULE_DIR}\SNP.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\SNP_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\SNP_build.xml" target="clean"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
|
||||
</target>
|
||||
<target name="SNP_cleanall">
|
||||
<OutputDirSetup baseName="SNP" mbdFilename="${MODULE_DIR}\SNP.mbd" msaFilename="${MODULE_DIR}\SNP.msa"/>
|
||||
<if>
|
||||
<available file="${DEST_DIR_OUTPUT}\SNP_build.xml"/>
|
||||
<then>
|
||||
<ant antfile="${DEST_DIR_OUTPUT}\SNP_build.xml" target="cleanall"/>
|
||||
</then>
|
||||
</if>
|
||||
<delete dir="${DEST_DIR_OUTPUT}"/>
|
||||
<delete dir="${DEST_DIR_DEBUG}"/>
|
||||
<delete>
|
||||
<fileset dir="${BIN_DIR}" includes="**SNP*"/>
|
||||
</delete>
|
||||
</target>
|
||||
</project>
|
613
EdkModulePkg/Universal/Network/Snp32_64/Dxe/callback.c
Normal file
613
EdkModulePkg/Universal/Network/Snp32_64/Dxe/callback.c
Normal file
@@ -0,0 +1,613 @@
|
||||
/*++
|
||||
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:
|
||||
callback.c
|
||||
|
||||
Abstract:
|
||||
This file contains two sets of callback routines for undi3.0 and undi3.1.
|
||||
the callback routines for Undi3.1 have an extra parameter UniqueId which
|
||||
stores the interface context for the NIC that snp is trying to talk..
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
//
|
||||
// Global variables
|
||||
// these 2 global variables are used only for 3.0 undi. we could not place
|
||||
// them in the snp structure because we will not know which snp structure
|
||||
// in the callback context!
|
||||
//
|
||||
STATIC BOOLEAN mInitializeLock = TRUE;
|
||||
STATIC EFI_LOCK mLock;
|
||||
|
||||
//
|
||||
// End Global variables
|
||||
//
|
||||
extern EFI_PCI_IO_PROTOCOL *mPciIoFncs;
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_v2p_30 (
|
||||
IN UINT64 CpuAddr,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with a virtual or CPU address that SNP provided
|
||||
to convert it to a physical or device address. Since EFI uses the identical
|
||||
mapping, this routine returns the physical address same as the virtual address
|
||||
for most of the addresses. an address above 4GB cannot generally be used as a
|
||||
device address, it needs to be mapped to a lower physical address. This routine
|
||||
does not call the map routine itself, but it assumes that the mapping was done
|
||||
at the time of providing the address to UNDI. This routine just looks up the
|
||||
address in a map table (which is the v2p structure chain)
|
||||
|
||||
Arguments:
|
||||
CpuAddr - virtual address of a buffer
|
||||
DeviceAddrPtr - pointer to the physical address
|
||||
|
||||
Returns:
|
||||
void - The DeviceAddrPtr will contain 0 in case of any error
|
||||
|
||||
--*/
|
||||
{
|
||||
struct s_v2p *v2p;
|
||||
//
|
||||
// Do nothing if virtual address is zero or physical pointer is NULL.
|
||||
// No need to map if the virtual address is within 4GB limit since
|
||||
// EFI uses identical mapping
|
||||
//
|
||||
if ((CpuAddr == 0) || (DeviceAddrPtr == 0)) {
|
||||
DEBUG ((EFI_D_ERROR, "\nv2p: Null virtual address or physical pointer.\n"));
|
||||
return ;
|
||||
}
|
||||
|
||||
if (CpuAddr < FOUR_GIGABYTES) {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// SNP creates a vaddr tp paddr mapping at the time of calling undi with any
|
||||
// big address, this callback routine just looks up in the v2p list and
|
||||
// returns the physical address for any given virtual address.
|
||||
//
|
||||
if (find_v2p (&v2p, (VOID *) (UINTN) CpuAddr) != EFI_SUCCESS) {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
|
||||
} else {
|
||||
*(UINT64 *) (UINTN) DeviceAddrPtr = v2p->paddr;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_block_30 (
|
||||
IN UINT32 Enable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it wants to have exclusive access to a critical
|
||||
section of the code/data
|
||||
|
||||
Arguments:
|
||||
Enable - non-zero indicates acquire
|
||||
zero indicates release
|
||||
|
||||
Returns:
|
||||
void
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// tcpip was calling snp at tpl_notify and if we acquire a lock that was
|
||||
// created at a lower level (TPL_CALLBACK) it gives an assert!
|
||||
//
|
||||
if (mInitializeLock) {
|
||||
EfiInitializeLock (&mLock, EFI_TPL_NOTIFY);
|
||||
mInitializeLock = FALSE;
|
||||
}
|
||||
|
||||
if (Enable != 0) {
|
||||
EfiAcquireLock (&mLock);
|
||||
} else {
|
||||
EfiReleaseLock (&mLock);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_delay_30 (
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with the number of micro seconds when it wants to
|
||||
pause.
|
||||
|
||||
Arguments:
|
||||
MicroSeconds - number of micro seconds to pause, ususlly multiple of 10
|
||||
|
||||
Returns:
|
||||
void
|
||||
--*/
|
||||
{
|
||||
if (MicroSeconds != 0) {
|
||||
gBS->Stall ((UINTN) MicroSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_memio_30 (
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 Address,
|
||||
IN OUT UINT64 BufferAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
This is the IO routine for UNDI. This is not currently being used by UNDI3.0
|
||||
because Undi3.0 uses io/mem offsets relative to the beginning of the device
|
||||
io/mem address and so it needs to use the PCI_IO_FUNCTION that abstracts the
|
||||
start of the device's io/mem addresses. Since SNP cannot retrive the context
|
||||
of the undi3.0 interface it cannot use the PCI_IO_FUNCTION that specific for
|
||||
that NIC and uses one global IO functions structure, this does not work.
|
||||
This however works fine for EFI1.0 Undis because they use absolute addresses
|
||||
for io/mem access.
|
||||
|
||||
Arguments:
|
||||
ReadOrWrite - indicates read or write, IO or Memory
|
||||
NumBytes - number of bytes to read or write
|
||||
Address - IO or memory address to read from or write to
|
||||
BufferAddr - memory location to read into or that contains the bytes
|
||||
to write
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_PCI_IO_PROTOCOL_WIDTH Width;
|
||||
|
||||
switch (NumBytes) {
|
||||
case 2:
|
||||
Width = 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Width = 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
Width = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
Width = 0;
|
||||
}
|
||||
|
||||
switch (ReadOrWrite) {
|
||||
case PXE_IO_READ:
|
||||
mPciIoFncs->Io.Read (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
1, // BAR 1, IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_IO_WRITE:
|
||||
mPciIoFncs->Io.Write (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
1, // BAR 1, IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_READ:
|
||||
mPciIoFncs->Mem.Read (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
0, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_WRITE:
|
||||
mPciIoFncs->Mem.Write (
|
||||
mPciIoFncs,
|
||||
Width,
|
||||
0, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// New callbacks for 3.1:
|
||||
// there won't be a virtual2physical callback for UNDI 3.1 because undi3.1 uses
|
||||
// the MemMap call to map the required address by itself!
|
||||
//
|
||||
VOID
|
||||
snp_undi32_callback_block (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT32 Enable
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI3.1 at undi_start time.
|
||||
UNDI call this routine when it wants to have exclusive access to a critical
|
||||
section of the code/data
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
Enable - non-zero indicates acquire
|
||||
zero indicates release
|
||||
|
||||
Returns:
|
||||
void
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
//
|
||||
// tcpip was calling snp at tpl_notify and when we acquire a lock that was
|
||||
// created at a lower level (TPL_CALLBACK) it gives an assert!
|
||||
//
|
||||
if (Enable != 0) {
|
||||
EfiAcquireLock (&snp->lock);
|
||||
} else {
|
||||
EfiReleaseLock (&snp->lock);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_delay (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine with the number of micro seconds when it wants to
|
||||
pause.
|
||||
|
||||
Arguments:
|
||||
MicroSeconds - number of micro seconds to pause, ususlly multiple of 10
|
||||
|
||||
Returns:
|
||||
void
|
||||
--*/
|
||||
{
|
||||
if (MicroSeconds != 0) {
|
||||
gBS->Stall ((UINTN) MicroSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IO routine for UNDI start CPB.
|
||||
*/
|
||||
VOID
|
||||
snp_undi32_callback_memio (
|
||||
UINT64 UniqueId,
|
||||
UINT8 ReadOrWrite,
|
||||
UINT8 NumBytes,
|
||||
UINT64 Address,
|
||||
UINT64 BufferAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
This is the IO routine for UNDI3.1.
|
||||
|
||||
Arguments:
|
||||
ReadOrWrite - indicates read or write, IO or Memory
|
||||
NumBytes - number of bytes to read or write
|
||||
Address - IO or memory address to read from or write to
|
||||
BufferAddr - memory location to read into or that contains the bytes
|
||||
to write
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_PCI_IO_PROTOCOL_WIDTH Width;
|
||||
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
|
||||
Width = 0;
|
||||
switch (NumBytes) {
|
||||
case 2:
|
||||
Width = 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Width = 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
Width = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ReadOrWrite) {
|
||||
case PXE_IO_READ:
|
||||
snp->IoFncs->Io.Read (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->IoBarIndex, // BAR 1 (for 32bit regs), IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_IO_WRITE:
|
||||
snp->IoFncs->Io.Write (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->IoBarIndex, // BAR 1 (for 32bit regs), IO base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_READ:
|
||||
snp->IoFncs->Mem.Read (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->MemoryBarIndex, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
|
||||
case PXE_MEM_WRITE:
|
||||
snp->IoFncs->Mem.Write (
|
||||
snp->IoFncs,
|
||||
Width,
|
||||
snp->MemoryBarIndex, // BAR 0, Memory base address
|
||||
Address,
|
||||
1, // count
|
||||
(VOID *) (UINTN) BufferAddr
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_map (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it has to map a CPU address to a device
|
||||
address.
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
CpuAddr - Virtual address to be mapped!
|
||||
NumBytes - size of memory to be mapped
|
||||
Direction - direction of data flow for this memory's usage:
|
||||
cpu->device, device->cpu or both ways
|
||||
DeviceAddrPtr - pointer to return the mapped device address
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS *DevAddrPtr;
|
||||
EFI_PCI_IO_PROTOCOL_OPERATION DirectionFlag;
|
||||
UINTN BuffSize;
|
||||
SNP_DRIVER *snp;
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
|
||||
BuffSize = (UINTN) NumBytes;
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
DevAddrPtr = (EFI_PHYSICAL_ADDRESS *) (UINTN) DeviceAddrPtr;
|
||||
|
||||
if (CpuAddr == 0) {
|
||||
*DevAddrPtr = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
switch (Direction) {
|
||||
case TO_AND_FROM_DEVICE:
|
||||
DirectionFlag = EfiPciIoOperationBusMasterCommonBuffer;
|
||||
break;
|
||||
|
||||
case FROM_DEVICE:
|
||||
DirectionFlag = EfiPciIoOperationBusMasterWrite;
|
||||
break;
|
||||
|
||||
case TO_DEVICE:
|
||||
DirectionFlag = EfiPciIoOperationBusMasterRead;
|
||||
break;
|
||||
|
||||
default:
|
||||
*DevAddrPtr = 0;
|
||||
//
|
||||
// any non zero indicates error!
|
||||
//
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// find an unused map_list entry
|
||||
//
|
||||
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
|
||||
if (snp->map_list[Index].virt == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index >= MAX_MAP_LENGTH) {
|
||||
SNP_PRINT (L"SNP maplist is FULL\n");
|
||||
*DevAddrPtr = 0;
|
||||
return ;
|
||||
}
|
||||
|
||||
snp->map_list[Index].virt = (EFI_PHYSICAL_ADDRESS) CpuAddr;
|
||||
|
||||
Status = snp->IoFncs->Map (
|
||||
snp->IoFncs,
|
||||
DirectionFlag,
|
||||
(VOID *) (UINTN) CpuAddr,
|
||||
&BuffSize,
|
||||
DevAddrPtr,
|
||||
&(snp->map_list[Index].map_cookie)
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
*DevAddrPtr = 0;
|
||||
snp->map_list[Index].virt = 0;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_unmap (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN UINT64 DeviceAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it wants to unmap an address that was previously
|
||||
mapped using map callback
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
CpuAddr - Virtual address that was mapped!
|
||||
NumBytes - size of memory mapped
|
||||
Direction- direction of data flow for this memory's usage:
|
||||
cpu->device, device->cpu or both ways
|
||||
DeviceAddr - the mapped device address
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
UINT16 Index;
|
||||
|
||||
snp = (SNP_DRIVER *) (UINTN) UniqueId;
|
||||
|
||||
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
|
||||
if (snp->map_list[Index].virt == CpuAddr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index >= MAX_MAP_LENGTH)
|
||||
{
|
||||
#if SNP_DEBUG
|
||||
Print (L"SNP could not find a mapping, failed to unmap.\n");
|
||||
#endif
|
||||
return ;
|
||||
}
|
||||
|
||||
snp->IoFncs->Unmap (snp->IoFncs, snp->map_list[Index].map_cookie);
|
||||
snp->map_list[Index].virt = 0;
|
||||
snp->map_list[Index].map_cookie = NULL;
|
||||
return ;
|
||||
}
|
||||
|
||||
VOID
|
||||
snp_undi32_callback_sync (
|
||||
UINT64 UniqueId,
|
||||
UINT64 CpuAddr,
|
||||
UINT32 NumBytes,
|
||||
UINT32 Direction,
|
||||
UINT64 DeviceAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is a callback routine supplied to UNDI at undi_start time.
|
||||
UNDI call this routine when it wants synchronize the virtual buffer contents
|
||||
with the mapped buffer contents. The virtual and mapped buffers need not
|
||||
correspond to the same physical memory (especially if the virtual address is
|
||||
> 4GB). Depending on the direction for which the buffer is mapped, undi will
|
||||
need to synchronize their contents whenever it writes to/reads from the buffer
|
||||
using either the cpu address or the device address.
|
||||
|
||||
EFI does not provide a sync call, since virt=physical, we sould just do
|
||||
the synchronization ourself here!
|
||||
|
||||
Arguments:
|
||||
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
|
||||
Undi interface context (Undi does not read or write this variable)
|
||||
CpuAddr - Virtual address that was mapped!
|
||||
NumBytes - size of memory mapped
|
||||
Direction- direction of data flow for this memory's usage:
|
||||
cpu->device, device->cpu or both ways
|
||||
DeviceAddr - the mapped device address
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
if ((CpuAddr == 0) || (DeviceAddr == 0) || (NumBytes == 0)) {
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
switch (Direction) {
|
||||
case FROM_DEVICE:
|
||||
CopyMem ((UINT8 *) (UINTN) CpuAddr, (UINT8 *) (UINTN) DeviceAddr, NumBytes);
|
||||
break;
|
||||
|
||||
case TO_DEVICE:
|
||||
CopyMem ((UINT8 *) (UINTN) DeviceAddr, (UINT8 *) (UINTN) CpuAddr, NumBytes);
|
||||
break;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
193
EdkModulePkg/Universal/Network/Snp32_64/Dxe/get_status.c
Normal file
193
EdkModulePkg/Universal/Network/Snp32_64/Dxe/get_status.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/*++
|
||||
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:
|
||||
get_status.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_getstatus (
|
||||
SNP_DRIVER *snp,
|
||||
UINT32 *InterruptStatusPtr,
|
||||
VOID **TransmitBufferListPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to get the status of the interrupts, get the list of
|
||||
transmit buffers that completed transmitting!
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
InterruptStatusPtr - a non null pointer gets the interrupt status
|
||||
TransmitBufferListPtrs - a non null ointer gets the list of pointers of previously
|
||||
transmitted buffers whose transmission was completed
|
||||
asynchrnously.
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_DB_GET_STATUS *db;
|
||||
UINT16 InterruptFlags;
|
||||
UINT64 TempData;
|
||||
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_GET_STATUS;
|
||||
|
||||
snp->cdb.OpFlags = 0;
|
||||
|
||||
if (TransmitBufferListPtr != NULL) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;
|
||||
}
|
||||
|
||||
if (InterruptStatusPtr != NULL) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_GET_INTERRUPT_STATUS;
|
||||
}
|
||||
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
|
||||
//
|
||||
// size DB for return of one buffer
|
||||
//
|
||||
snp->cdb.DBsize = (UINT16) (((UINT16) (sizeof (PXE_DB_GET_STATUS)) - (UINT16) (sizeof db->TxBuffer)) + (UINT16) (sizeof db->TxBuffer[0]));
|
||||
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.get_status() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.get_status() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatFlags)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// report the values back..
|
||||
//
|
||||
if (InterruptStatusPtr != NULL) {
|
||||
InterruptFlags = (UINT16) (snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK);
|
||||
|
||||
*InterruptStatusPtr = 0;
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_RECEIVE) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
|
||||
}
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_TRANSMIT) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
|
||||
}
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_COMMAND) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;
|
||||
}
|
||||
|
||||
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_SOFTWARE) {
|
||||
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (TransmitBufferListPtr != NULL) {
|
||||
*TransmitBufferListPtr =
|
||||
(
|
||||
(snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) ||
|
||||
(snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY)
|
||||
) ? 0 : (VOID *) (UINTN) db->TxBuffer[0];
|
||||
|
||||
TempData = (UINT64) (UINTN) (*TransmitBufferListPtr);
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
del_v2p ((VOID *) (UINTN) (db->TxBuffer[0]));
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_get_status (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINT32 *InterruptStatusPtr OPTIONAL,
|
||||
OUT VOID **TransmitBufferListPtr OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for getting the status
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_getstatus routine to actually get the undi status
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
InterruptStatusPtr - a non null pointer gets the interrupt status
|
||||
TransmitBufferListPtrs - a non null ointer gets the list of pointers of previously
|
||||
transmitted buffers whose transmission was completed
|
||||
asynchrnously.
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (InterruptStatusPtr == NULL && TransmitBufferListPtr == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return pxe_getstatus (snp, InterruptStatusPtr, TransmitBufferListPtr);
|
||||
}
|
244
EdkModulePkg/Universal/Network/Snp32_64/Dxe/initialize.c
Normal file
244
EdkModulePkg/Universal/Network/Snp32_64/Dxe/initialize.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/*++
|
||||
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:
|
||||
initialize.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-09 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SnpWaitForPacketNotify (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *SnpPtr
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
pxe_init (
|
||||
SNP_DRIVER *snp,
|
||||
UINT16 CableDetectFlag
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to initialize the interface.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
CableDetectFlag - Do/don't detect the cable (depending on what undi supports)
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_CPB_INITIALIZE *cpb;
|
||||
VOID *addr;
|
||||
EFI_STATUS Status;
|
||||
|
||||
cpb = snp->cpb;
|
||||
if (snp->tx_rx_bufsize != 0) {
|
||||
Status = snp->IoFncs->AllocateBuffer (
|
||||
snp->IoFncs,
|
||||
AllocateAnyPages,
|
||||
EfiBootServicesData,
|
||||
SNP_MEM_PAGES (snp->tx_rx_bufsize),
|
||||
&addr,
|
||||
0
|
||||
);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->pxe_init() AllocateBuffer %xh (%r)\n",
|
||||
Status,
|
||||
Status)
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
ASSERT (addr);
|
||||
|
||||
snp->tx_rx_buffer = addr;
|
||||
}
|
||||
|
||||
cpb->MemoryAddr = (UINT64) (UINTN) snp->tx_rx_buffer;
|
||||
|
||||
cpb->MemoryLength = snp->tx_rx_bufsize;
|
||||
|
||||
//
|
||||
// let UNDI decide/detect these values
|
||||
//
|
||||
cpb->LinkSpeed = 0;
|
||||
cpb->TxBufCnt = 0;
|
||||
cpb->TxBufSize = 0;
|
||||
cpb->RxBufCnt = 0;
|
||||
cpb->RxBufSize = 0;
|
||||
|
||||
cpb->DuplexMode = PXE_DUPLEX_DEFAULT;
|
||||
|
||||
cpb->LoopBackMode = LOOPBACK_NORMAL;
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_INITIALIZE;
|
||||
snp->cdb.OpFlags = CableDetectFlag;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_INITIALIZE);
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_INITIALIZE);
|
||||
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) snp->cpb;
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) snp->db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.initialize() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode == PXE_STATCODE_SUCCESS) {
|
||||
snp->mode.State = EfiSimpleNetworkInitialized;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
} else {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nsnp->undi.initialize() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
if (snp->tx_rx_buffer != NULL) {
|
||||
snp->IoFncs->FreeBuffer (
|
||||
snp->IoFncs,
|
||||
SNP_MEM_PAGES (snp->tx_rx_bufsize),
|
||||
(VOID *) snp->tx_rx_buffer
|
||||
);
|
||||
}
|
||||
|
||||
snp->tx_rx_buffer = NULL;
|
||||
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_initialize (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN UINTN extra_rx_buffer_size OPTIONAL,
|
||||
IN UINTN extra_tx_buffer_size OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for initializing the interface
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_initialize routine to actually do the undi initialization
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
extra_rx_buffer_size - optional parameter, indicates extra space for rx_buffers
|
||||
extra_tx_buffer_size - optional parameter, indicates extra space for tx_buffers
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS EfiStatus;
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkStarted:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkInitialized:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
EfiStatus = gBS->CreateEvent (
|
||||
EFI_EVENT_NOTIFY_WAIT,
|
||||
EFI_TPL_NOTIFY,
|
||||
&SnpWaitForPacketNotify,
|
||||
snp,
|
||||
&snp->snp.WaitForPacket
|
||||
);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
snp->snp.WaitForPacket = NULL;
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
snp->mode.MCastFilterCount = 0;
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);
|
||||
CopyMem (
|
||||
&snp->mode.CurrentAddress,
|
||||
&snp->mode.PermanentAddress,
|
||||
sizeof (EFI_MAC_ADDRESS)
|
||||
);
|
||||
|
||||
//
|
||||
// Compute tx/rx buffer sizes based on UNDI init info and parameters.
|
||||
//
|
||||
snp->tx_rx_bufsize = (UINT32) (snp->init_info.MemoryRequired + extra_rx_buffer_size + extra_tx_buffer_size);
|
||||
|
||||
if (snp->mode.MediaPresentSupported) {
|
||||
if (pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {
|
||||
snp->mode.MediaPresent = TRUE;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
snp->mode.MediaPresent = FALSE;
|
||||
|
||||
EfiStatus = pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);
|
||||
|
||||
if (EFI_ERROR (EfiStatus)) {
|
||||
gBS->CloseEvent (snp->snp.WaitForPacket);
|
||||
}
|
||||
|
||||
return EfiStatus;
|
||||
}
|
167
EdkModulePkg/Universal/Network/Snp32_64/Dxe/mcast_ip_to_mac.c
Normal file
167
EdkModulePkg/Universal/Network/Snp32_64/Dxe/mcast_ip_to_mac.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*++
|
||||
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:
|
||||
mcast_ip_to_mac.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_ip2mac (
|
||||
IN SNP_DRIVER *snp,
|
||||
IN BOOLEAN IPv6,
|
||||
IN EFI_IP_ADDRESS *IP,
|
||||
IN OUT EFI_MAC_ADDRESS *MAC
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to convert an multicast IP address to a MAC address
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
IPv6 - flag to indicate if this is an ipv6 address
|
||||
IP - multicast IP address
|
||||
MAC - pointer to hold the return MAC address
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_CPB_MCAST_IP_TO_MAC *cpb;
|
||||
PXE_DB_MCAST_IP_TO_MAC *db;
|
||||
|
||||
cpb = snp->cpb;
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_MCAST_IP_TO_MAC;
|
||||
snp->cdb.OpFlags = (UINT16) (IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC);
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_MCAST_IP_TO_MAC);
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_MCAST_IP_TO_MAC);
|
||||
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
CopyMem (&cpb->IP, IP, sizeof (PXE_IP_ADDR));
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.mcast_ip_to_mac() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_INVALID_CPB:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.mcast_ip_to_mac() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
default:
|
||||
//
|
||||
// UNDI command failed. Return EFI_DEVICE_ERROR
|
||||
// to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.mcast_ip_to_mac() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
CopyMem (MAC, &db->MAC, sizeof (PXE_MAC_ADDR));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_mcast_ip_to_mac (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN IPv6,
|
||||
IN EFI_IP_ADDRESS *IP,
|
||||
OUT EFI_MAC_ADDRESS *MAC
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for converting a multicast IP address to
|
||||
a MAC address.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_ip2mac routine to actually do the conversion
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
IPv6 - flag to indicate if this is an ipv6 address
|
||||
IP - multicast IP address
|
||||
MAC - pointer to hold the return MAC address
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
//
|
||||
// Get pointer to SNP driver instance for *this.
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (IP == NULL || MAC == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return pxe_ip2mac (snp, IPv6, IP, MAC);
|
||||
}
|
183
EdkModulePkg/Universal/Network/Snp32_64/Dxe/nvdata.c
Normal file
183
EdkModulePkg/Universal/Network/Snp32_64/Dxe/nvdata.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*++
|
||||
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:
|
||||
nvdata.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_nvdata_read (
|
||||
IN SNP_DRIVER *snp,
|
||||
IN UINTN RegOffset,
|
||||
IN UINTN NumBytes,
|
||||
IN OUT VOID *BufferPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine calls Undi to read the desired number of eeprom bytes.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to the snp driver structure
|
||||
RegOffset - eeprom register value relative to the base address
|
||||
NumBytes - number of bytes to read
|
||||
BufferPtr - pointer where to read into
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_DB_NVDATA *db;
|
||||
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_NVDATA;
|
||||
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NVDATA_READ;
|
||||
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_NVDATA);
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.nvdata () "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.nvdata() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_NET,
|
||||
"\nsnp->undi.nvdata() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
CopyMem (BufferPtr, db->Data.Byte + RegOffset, NumBytes);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_nvdata (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN ReadOrWrite,
|
||||
IN UINTN RegOffset,
|
||||
IN UINTN NumBytes,
|
||||
IN OUT VOID *BufferPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is an interface call provided by SNP.
|
||||
It does the basic checking on the input parameters and retrieves snp structure
|
||||
and then calls the read_nvdata() call which does the actual reading
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
ReadOrWrite - true for reading and false for writing
|
||||
RegOffset - eeprom register relative to the base
|
||||
NumBytes - how many bytes to read
|
||||
BufferPtr - address of memory to read into
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
//
|
||||
// Get pointer to SNP driver instance for *this.
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Return error if the SNP is not initialized.
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Return error if non-volatile memory variables are not valid.
|
||||
//
|
||||
if (snp->mode.NvRamSize == 0 || snp->mode.NvRamAccessSize == 0) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Check for invalid parameter combinations.
|
||||
//
|
||||
if ((NumBytes == 0) ||
|
||||
(BufferPtr == NULL) ||
|
||||
(RegOffset >= snp->mode.NvRamSize) ||
|
||||
(RegOffset + NumBytes > snp->mode.NvRamSize) ||
|
||||
(NumBytes % snp->mode.NvRamAccessSize != 0) ||
|
||||
(RegOffset % snp->mode.NvRamAccessSize != 0)
|
||||
) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
//
|
||||
// check the implementation flags of undi if we can write the nvdata!
|
||||
//
|
||||
if (!ReadOrWrite) {
|
||||
return EFI_UNSUPPORTED;
|
||||
} else {
|
||||
return pxe_nvdata_read (snp, RegOffset, NumBytes, BufferPtr);
|
||||
}
|
||||
}
|
255
EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive.c
Normal file
255
EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*++
|
||||
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:
|
||||
receive.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_receive (
|
||||
SNP_DRIVER *snp,
|
||||
VOID *BufferPtr,
|
||||
UINTN *BuffSizePtr,
|
||||
UINTN *HeaderSizePtr,
|
||||
EFI_MAC_ADDRESS *SourceAddrPtr,
|
||||
EFI_MAC_ADDRESS *DestinationAddrPtr,
|
||||
UINT16 *ProtocolPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to receive a packet and fills in the data in the
|
||||
input pointers!
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
BufferPtr - pointer to the memory for the received data
|
||||
BuffSizePtr - is a pointer to the length of the buffer on entry and contains
|
||||
the length of the received data on return
|
||||
HeaderSizePtr - pointer to the header portion of the data received.
|
||||
SourceAddrPtr - optional parameter, is a pointer to contain the source
|
||||
ethernet address on return
|
||||
DestinationAddrPtr - optional parameter, is a pointer to contain the destination
|
||||
ethernet address on return
|
||||
ProtocolPtr - optional parameter, is a pointer to contain the protocol type
|
||||
from the ethernet header on return
|
||||
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_CPB_RECEIVE *cpb;
|
||||
PXE_DB_RECEIVE *db;
|
||||
UINTN buf_size;
|
||||
UINT64 TempData;
|
||||
|
||||
cpb = snp->cpb;
|
||||
db = snp->db;
|
||||
buf_size = *BuffSizePtr;
|
||||
//
|
||||
// IMPORTANT NOTE:
|
||||
// In case of the older 3.0 UNDI, if the input buffer address is beyond 4GB,
|
||||
// DO NOT call the map function on the given buffer, instead use
|
||||
// a global buffer. The reason is that UNDI3.0 has some unnecessary check of
|
||||
// making sure that all the addresses (whether or not they will be given
|
||||
// to the NIC ) supplied to it are below 4GB. It may or may not use
|
||||
// the mapped address after all (like in case of CPB and DB)!
|
||||
// Instead of using the global buffer whose address is allocated within the
|
||||
// 2GB limit if I start mapping the given buffer we lose the data, here is
|
||||
// why!!!
|
||||
// if our address is > 4GB, the map call creates another buffer below 2GB and
|
||||
// copies data to/from the original buffer to the mapped buffer either at
|
||||
// map time or unmap time depending on the map direction.
|
||||
// UNDI will not complain since we already mapped the buffer to be
|
||||
// within the 2GB limit but will not use (I know undi) the mapped address
|
||||
// since it does not give the user buffers to the NIC's receive unit,
|
||||
// It just copies the received packet into the user buffer using the virtual
|
||||
// (CPU) address rather than the mapped (device or physical) address.
|
||||
// When the UNDI call returns, if we then unmap the buffer, we will lose
|
||||
// the contents because unmap copies the contents of the mapped buffer into
|
||||
// the original buffer (since the direction is FROM_DEVICE) !!!
|
||||
//
|
||||
// this is not a problem in Undi 3.1 because this undi uses it's map callback
|
||||
// routine to map a cpu address to device address and it does it only if
|
||||
// it is giving the address to the device and unmaps it before using the cpu
|
||||
// address!
|
||||
//
|
||||
TempData = (UINT64) (UINTN) BufferPtr;
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
cpb->BufferAddr = (UINT64) (UINTN) snp->receive_buf;
|
||||
cpb->BufferLen = (UINT32) (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);
|
||||
} else {
|
||||
cpb->BufferAddr = (UINT64) (UINTN) BufferPtr;
|
||||
cpb->BufferLen = (UINT32) *BuffSizePtr;
|
||||
}
|
||||
|
||||
cpb->reserved = 0;
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_RECEIVE);
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_RECEIVE);
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_INFO, "\nsnp->undi.receive () "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_NO_DATA:
|
||||
DEBUG (
|
||||
(EFI_D_INFO,
|
||||
"\nsnp->undi.receive () %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_NOT_READY;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
*BuffSizePtr = db->FrameLen;
|
||||
|
||||
if (HeaderSizePtr != NULL) {
|
||||
*HeaderSizePtr = db->MediaHeaderLen;
|
||||
}
|
||||
|
||||
if (SourceAddrPtr != NULL) {
|
||||
CopyMem (SourceAddrPtr, &db->SrcAddr, snp->mode.HwAddressSize);
|
||||
}
|
||||
|
||||
if (DestinationAddrPtr != NULL) {
|
||||
CopyMem (DestinationAddrPtr, &db->DestAddr, snp->mode.HwAddressSize);
|
||||
}
|
||||
|
||||
if (ProtocolPtr != NULL) {
|
||||
*ProtocolPtr = (UINT16) PXE_SWAP_UINT16 (db->Protocol); /* we need to do the byte swapping */
|
||||
}
|
||||
|
||||
TempData = (UINT64) (UINTN) BufferPtr;
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
CopyMem (BufferPtr, snp->receive_buf, snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);
|
||||
}
|
||||
|
||||
return (*BuffSizePtr <= buf_size) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINTN *HeaderSizePtr OPTIONAL,
|
||||
IN OUT UINTN *BuffSizePtr,
|
||||
OUT VOID *BufferPtr,
|
||||
OUT EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,
|
||||
OUT EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,
|
||||
OUT UINT16 *ProtocolPtr OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for receiving network data.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_receive routine to actually do the receive!
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
HeaderSizePtr - optional parameter and is a pointer to the header portion of
|
||||
the data received.
|
||||
BuffSizePtr - is a pointer to the length of the buffer on entry and contains
|
||||
the length of the received data on return
|
||||
BufferPtr - pointer to the memory for the received data
|
||||
SourceAddrPtr - optional parameter, is a pointer to contain the source
|
||||
ethernet address on return
|
||||
DestinationAddrPtr - optional parameter, is a pointer to contain the destination
|
||||
ethernet address on return
|
||||
ProtocolPtr - optional parameter, is a pointer to contain the protocol type
|
||||
from the ethernet header on return
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if ((BuffSizePtr == NULL) || (BufferPtr == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!snp->mode.ReceiveFilterSetting) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return pxe_receive (
|
||||
snp,
|
||||
BufferPtr,
|
||||
BuffSizePtr,
|
||||
HeaderSizePtr,
|
||||
SourceAddrPtr,
|
||||
DestinationAddrPtr,
|
||||
ProtocolPtr
|
||||
);
|
||||
}
|
411
EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive_filters.c
Normal file
411
EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive_filters.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/*++
|
||||
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:
|
||||
receive_filters.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_rcvfilter_enable (
|
||||
SNP_DRIVER *snp,
|
||||
UINT32 EnableFlags,
|
||||
UINTN MCastAddressCount,
|
||||
EFI_MAC_ADDRESS *MCastAddressList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to enable the receive filters.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
EnableFlags - bit mask for enabling the receive filters
|
||||
MCastAddressCount - multicast address count for a new multicast address list
|
||||
MCastAddressList - list of new multicast addresses
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
|
||||
}
|
||||
|
||||
if (MCastAddressCount != 0) {
|
||||
snp->cdb.CPBsize = (UINT16) (MCastAddressCount * sizeof (EFI_MAC_ADDRESS));
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) snp->cpb;
|
||||
CopyMem (snp->cpb, MCastAddressList, snp->cdb.CPBsize);
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive_filters() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_INVALID_CDB:
|
||||
case PXE_STATCODE_INVALID_CPB:
|
||||
case PXE_STATCODE_INVALID_PARAMETER:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
pxe_rcvfilter_disable (
|
||||
SNP_DRIVER *snp,
|
||||
UINT32 DisableFlags,
|
||||
BOOLEAN ResetMCastList
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to disable the receive filters.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
DisableFlags - bit mask for disabling the receive filters
|
||||
ResetMCastList - boolean flag to reset/delete the multicast filter list
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
snp->cdb.OpFlags = (UINT16) (DisableFlags ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);
|
||||
|
||||
if (ResetMCastList) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
|
||||
}
|
||||
|
||||
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
|
||||
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive_filters() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
pxe_rcvfilter_read (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to read the receive filters.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_READ;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = (UINT16) (snp->mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
if (snp->cdb.DBsize == 0) {
|
||||
snp->cdb.DBaddr = (UINT64) NULL;
|
||||
} else {
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) snp->db;
|
||||
ZeroMem (snp->db, snp->cdb.DBsize);
|
||||
}
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != EFI_SUCCESS) {
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.receive_filters() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Convert UNDI32 StatFlags to EFI SNP filter flags.
|
||||
//
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
|
||||
}
|
||||
|
||||
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
|
||||
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
|
||||
}
|
||||
|
||||
CopyMem (snp->mode.MCastFilter, snp->db, snp->cdb.DBsize);
|
||||
|
||||
//
|
||||
// Count number of active entries in multicast filter list.
|
||||
//
|
||||
{
|
||||
EFI_MAC_ADDRESS ZeroMacAddr;
|
||||
|
||||
SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);
|
||||
|
||||
for (snp->mode.MCastFilterCount = 0;
|
||||
snp->mode.MCastFilterCount < snp->mode.MaxMCastFilterCount;
|
||||
snp->mode.MCastFilterCount++
|
||||
) {
|
||||
if (CompareMem (
|
||||
&snp->mode.MCastFilter[snp->mode.MCastFilterCount],
|
||||
&ZeroMacAddr,
|
||||
sizeof ZeroMacAddr
|
||||
) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive_filters (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINT32 EnableFlags,
|
||||
IN UINT32 DisableFlags,
|
||||
IN BOOLEAN ResetMCastList,
|
||||
IN UINTN MCastAddressCount OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * MCastAddressList OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for reading/enabling/disabling the
|
||||
receive filters.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
checks the parameter validity, calls one of the above routines to actually
|
||||
do the work
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
EnableFlags - bit mask for enabling the receive filters
|
||||
DisableFlags - bit mask for disabling the receive filters
|
||||
ResetMCastList - boolean flag to reset/delete the multicast filter list
|
||||
MCastAddressCount - multicast address count for a new multicast address list
|
||||
MCastAddressList - list of new multicast addresses
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// check if we are asked to enable or disable something that the UNDI
|
||||
// does not even support!
|
||||
//
|
||||
if ((EnableFlags &~snp->mode.ReceiveFilterMask) != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((DisableFlags &~snp->mode.ReceiveFilterMask) != 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (ResetMCastList) {
|
||||
DisableFlags |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & snp->mode.ReceiveFilterMask;
|
||||
MCastAddressCount = 0;
|
||||
MCastAddressList = NULL;
|
||||
} else {
|
||||
if (MCastAddressCount != 0) {
|
||||
if (MCastAddressCount > snp->mode.MaxMCastFilterCount) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (MCastAddressList == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EnableFlags == 0 && DisableFlags == 0 && !ResetMCastList && MCastAddressCount == 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastAddressCount == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((EnableFlags != 0) || (MCastAddressCount != 0)) {
|
||||
Status = pxe_rcvfilter_enable (
|
||||
snp,
|
||||
EnableFlags,
|
||||
MCastAddressCount,
|
||||
MCastAddressList
|
||||
);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if ((DisableFlags != 0) || ResetMCastList) {
|
||||
Status = pxe_rcvfilter_disable (snp, DisableFlags, ResetMCastList);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return pxe_rcvfilter_read (snp);
|
||||
}
|
129
EdkModulePkg/Universal/Network/Snp32_64/Dxe/reset.c
Normal file
129
EdkModulePkg/Universal/Network/Snp32_64/Dxe/reset.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*++
|
||||
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:
|
||||
reset.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-09 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_reset (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine calls undi to reset the nic.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to the snp driver structure
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESSFUL for a successful completion
|
||||
other for failed calls
|
||||
|
||||
--*/
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_RESET;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.reset() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nsnp->undi32.reset() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
//
|
||||
// UNDI could not be reset. Return UNDI error.
|
||||
//
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_reset (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN ExtendedVerification
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for resetting the NIC
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_reset routine to actually do the reset!
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
ExtendedVerification - not implemented
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
//
|
||||
// Resolve Warning 4 unreferenced parameter problem
|
||||
//
|
||||
ExtendedVerification = 0;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return pxe_reset (snp);
|
||||
}
|
152
EdkModulePkg/Universal/Network/Snp32_64/Dxe/shutdown.c
Normal file
152
EdkModulePkg/Universal/Network/Snp32_64/Dxe/shutdown.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*++
|
||||
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:
|
||||
shutdown.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-14 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_shutdown (
|
||||
IN SNP_DRIVER *snp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to shut down the interface.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_SHUTDOWN;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.shutdown() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
//
|
||||
// UNDI could not be shutdown. Return UNDI error.
|
||||
//
|
||||
DEBUG ((EFI_D_WARN, "\nsnp->undi.shutdown() %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Free allocated memory.
|
||||
//
|
||||
if (snp->tx_rx_buffer != NULL) {
|
||||
snp->IoFncs->FreeBuffer (
|
||||
snp->IoFncs,
|
||||
SNP_MEM_PAGES (snp->tx_rx_bufsize),
|
||||
(VOID *) snp->tx_rx_buffer
|
||||
);
|
||||
}
|
||||
|
||||
snp->tx_rx_buffer = NULL;
|
||||
snp->tx_rx_bufsize = 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_shutdown (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for shutting down the interface
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_shutdown routine to actually do the undi shutdown
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS status;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
status = pxe_shutdown (snp);
|
||||
|
||||
snp->mode.State = EfiSimpleNetworkStarted;
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
|
||||
snp->mode.MCastFilterCount = 0;
|
||||
snp->mode.ReceiveFilterSetting = 0;
|
||||
ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);
|
||||
CopyMem (
|
||||
&snp->mode.CurrentAddress,
|
||||
&snp->mode.PermanentAddress,
|
||||
sizeof (EFI_MAC_ADDRESS)
|
||||
);
|
||||
|
||||
gBS->CloseEvent (snp->snp.WaitForPacket);
|
||||
|
||||
return status;
|
||||
}
|
1315
EdkModulePkg/Universal/Network/Snp32_64/Dxe/snp.c
Normal file
1315
EdkModulePkg/Universal/Network/Snp32_64/Dxe/snp.c
Normal file
File diff suppressed because it is too large
Load Diff
410
EdkModulePkg/Universal/Network/Snp32_64/Dxe/snp.h
Normal file
410
EdkModulePkg/Universal/Network/Snp32_64/Dxe/snp.h
Normal file
@@ -0,0 +1,410 @@
|
||||
/*++
|
||||
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:
|
||||
snp.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
--*/
|
||||
#ifndef _SNP_H
|
||||
#define _SNP_H
|
||||
|
||||
|
||||
#include "IndustryStandard/pci22.h"
|
||||
|
||||
#define SNP_DEBUG 0
|
||||
#define FOUR_GIGABYTES (UINT64) 0x100000000ULL
|
||||
|
||||
#if SNP_DEBUG
|
||||
#undef D_NET
|
||||
#define D_NET D_WARN
|
||||
#define SNP_PRINT(DebugInfo) Print (DebugInfo)
|
||||
#else
|
||||
#define SNP_PRINT(DebugInfo)
|
||||
#endif
|
||||
|
||||
#define SNP_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('s', 'n', 'd', 's')
|
||||
#define MAX_MAP_LENGTH 100
|
||||
|
||||
#define PCI_BAR_IO_MASK 0x00000003
|
||||
#define PCI_BAR_IO_MODE 0x00000001
|
||||
|
||||
#define PCI_BAR_MEM_MASK 0x0000000F
|
||||
#define PCI_BAR_MEM_MODE 0x00000000
|
||||
#define PCI_BAR_MEM_64BIT 0x00000004
|
||||
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
EFI_LOCK lock;
|
||||
|
||||
EFI_SIMPLE_NETWORK_PROTOCOL snp;
|
||||
EFI_SIMPLE_NETWORK_MODE mode;
|
||||
|
||||
EFI_HANDLE device_handle;
|
||||
EFI_DEVICE_PATH_PROTOCOL *device_path;
|
||||
|
||||
//
|
||||
// Local instance data needed by SNP driver
|
||||
//
|
||||
// Pointer to S/W UNDI API entry point
|
||||
// This will be NULL for H/W UNDI
|
||||
//
|
||||
EFI_STATUS (*issue_undi32_command) (UINT64 cdb);
|
||||
|
||||
BOOLEAN is_swundi;
|
||||
|
||||
//
|
||||
// undi interface number, if one undi manages more nics
|
||||
//
|
||||
PXE_IFNUM if_num;
|
||||
|
||||
//
|
||||
// Allocated tx/rx buffer that was passed to UNDI Initialize.
|
||||
//
|
||||
UINT32 tx_rx_bufsize;
|
||||
VOID *tx_rx_buffer;
|
||||
//
|
||||
// mappable buffers for receive and fill header for undi3.0
|
||||
// these will be used if the user buffers are above 4GB limit (instead of
|
||||
// mapping the user buffers)
|
||||
//
|
||||
UINT8 *receive_buf;
|
||||
VOID *ReceiveBufUnmap;
|
||||
UINT8 *fill_hdr_buf;
|
||||
VOID *FillHdrBufUnmap;
|
||||
|
||||
EFI_PCI_IO_PROTOCOL *IoFncs;
|
||||
UINT8 IoBarIndex;
|
||||
UINT8 MemoryBarIndex;
|
||||
BOOLEAN IsOldUndi; // true for EFI1.0 UNDI (3.0) drivers
|
||||
//
|
||||
// Buffers for command descriptor block, command parameter block
|
||||
// and data block.
|
||||
//
|
||||
PXE_CDB cdb;
|
||||
VOID *cpb;
|
||||
VOID *CpbUnmap;
|
||||
VOID *db;
|
||||
|
||||
//
|
||||
// UNDI structure, we need to remember the init info for a long time!
|
||||
//
|
||||
PXE_DB_GET_INIT_INFO init_info;
|
||||
|
||||
VOID *SnpDriverUnmap;
|
||||
//
|
||||
// when ever we map an address, we must remember it's address and the un-map
|
||||
// cookie so that we can unmap later
|
||||
//
|
||||
struct s_map_list {
|
||||
EFI_PHYSICAL_ADDRESS virt;
|
||||
VOID *map_cookie;
|
||||
} map_list[MAX_MAP_LENGTH];
|
||||
}
|
||||
SNP_DRIVER;
|
||||
|
||||
#define EFI_SIMPLE_NETWORK_DEV_FROM_THIS(a) CR (a, SNP_DRIVER, snp, SNP_DRIVER_SIGNATURE)
|
||||
|
||||
//
|
||||
// Global Variables
|
||||
//
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName;
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding;
|
||||
|
||||
//
|
||||
// Virtual to physical mapping for all UNDI 3.0s.
|
||||
//
|
||||
extern struct s_v2p {
|
||||
struct s_v2p *next;
|
||||
VOID *vaddr;
|
||||
UINTN bsize;
|
||||
EFI_PHYSICAL_ADDRESS paddr;
|
||||
VOID *unmap;
|
||||
}
|
||||
*_v2p;
|
||||
|
||||
EFI_STATUS
|
||||
add_v2p (
|
||||
struct s_v2p **v2p,
|
||||
EFI_PCI_IO_PROTOCOL_OPERATION type,
|
||||
VOID *vaddr,
|
||||
UINTN bsize
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
find_v2p (
|
||||
struct s_v2p **v2p,
|
||||
VOID *vaddr
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
del_v2p (
|
||||
VOID *vaddr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_block_30 (
|
||||
IN UINT32 Enable
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_delay_30 (
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_memio_30 (
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 MemOrPortAddress,
|
||||
IN OUT UINT64 BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_v2p_30 (
|
||||
IN UINT64 CpuAddr,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_block (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT32 Enable
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_delay (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 MicroSeconds
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_memio (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT8 ReadOrWrite,
|
||||
IN UINT8 NumBytes,
|
||||
IN UINT64 MemOrPortAddr,
|
||||
IN OUT UINT64 BufferPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_map (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN OUT UINT64 DeviceAddrPtr
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_unmap (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN UINT64 DeviceAddr // not a pointer to device address
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
VOID
|
||||
snp_undi32_callback_sync (
|
||||
IN UINT64 UniqueId,
|
||||
IN UINT64 CpuAddr,
|
||||
IN UINT32 NumBytes,
|
||||
IN UINT32 Direction,
|
||||
IN UINT64 DeviceAddr // not a pointer to device address
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_start (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_stop (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_initialize (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN UINTN extra_rx_buffer_size OPTIONAL,
|
||||
IN UINTN extra_tx_buffer_size OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_reset (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN ExtendedVerification
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_shutdown (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive_filters (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINT32 enable,
|
||||
IN UINT32 disable,
|
||||
IN BOOLEAN reset_mcast_filter,
|
||||
IN UINTN mcast_filter_count OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * mcast_filter OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_station_address (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN reset,
|
||||
IN EFI_MAC_ADDRESS *new OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_statistics (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN reset,
|
||||
IN OUT UINTN *statistics_size OPTIONAL,
|
||||
IN OUT EFI_NETWORK_STATISTICS * statistics_table OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_mcast_ip_to_mac (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN IPv6,
|
||||
IN EFI_IP_ADDRESS *IP,
|
||||
OUT EFI_MAC_ADDRESS *MAC
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_nvdata (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
|
||||
IN BOOLEAN read_write,
|
||||
IN UINTN offset,
|
||||
IN UINTN buffer_size,
|
||||
IN OUT VOID *buffer
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_get_status (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINT32 *interrupt_status OPTIONAL,
|
||||
OUT VOID **tx_buffer OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_transmit (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINTN header_size,
|
||||
IN UINTN buffer_size,
|
||||
IN VOID *buffer,
|
||||
IN EFI_MAC_ADDRESS * src_addr OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * dest_addr OPTIONAL,
|
||||
IN UINT16 *protocol OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
extern
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_receive (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
OUT UINTN *header_size OPTIONAL,
|
||||
IN OUT UINTN *buffer_size,
|
||||
OUT VOID *buffer,
|
||||
OUT EFI_MAC_ADDRESS * src_addr OPTIONAL,
|
||||
OUT EFI_MAC_ADDRESS * dest_addr OPTIONAL,
|
||||
OUT UINT16 *protocol OPTIONAL
|
||||
)
|
||||
;
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(*issue_undi32_command) (
|
||||
UINT64 cdb
|
||||
);
|
||||
typedef
|
||||
VOID
|
||||
(*ptr) (
|
||||
VOID
|
||||
);
|
||||
|
||||
#define SNP_MEM_PAGES(x) (((x) - 1) / 4096 + 1)
|
||||
|
||||
#if SNP_DEBUG
|
||||
extern
|
||||
VOID
|
||||
snp_wait_for_key (
|
||||
VOID
|
||||
)
|
||||
;
|
||||
#endif
|
||||
|
||||
#endif /* _SNP_H */
|
191
EdkModulePkg/Universal/Network/Snp32_64/Dxe/start.c
Normal file
191
EdkModulePkg/Universal/Network/Snp32_64/Dxe/start.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*++
|
||||
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:
|
||||
start.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-07 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_start (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to start the interface and changes the snp state!
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_CPB_START_30 *cpb;
|
||||
PXE_CPB_START_31 *cpb_31;
|
||||
|
||||
cpb = snp->cpb;
|
||||
cpb_31 = snp->cpb;
|
||||
//
|
||||
// Initialize UNDI Start CDB for H/W UNDI
|
||||
//
|
||||
snp->cdb.OpCode = PXE_OPCODE_START;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Make changes to H/W UNDI Start CDB if this is
|
||||
// a S/W UNDI.
|
||||
//
|
||||
if (snp->is_swundi) {
|
||||
if (snp->IsOldUndi) {
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_START_30);
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
|
||||
|
||||
cpb->Delay = (UINT64) &snp_undi32_callback_delay_30;
|
||||
cpb->Block = (UINT64) &snp_undi32_callback_block_30;
|
||||
|
||||
//
|
||||
// Virtual == Physical. This can be set to zero.
|
||||
//
|
||||
cpb->Virt2Phys = (UINT64) &snp_undi32_callback_v2p_30;
|
||||
cpb->Mem_IO = (UINT64) &snp_undi32_callback_memio_30;
|
||||
} else {
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_START_31);
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb_31;
|
||||
|
||||
cpb_31->Delay = (UINT64) &snp_undi32_callback_delay;
|
||||
cpb_31->Block = (UINT64) &snp_undi32_callback_block;
|
||||
|
||||
//
|
||||
// Virtual == Physical. This can be set to zero.
|
||||
//
|
||||
cpb_31->Virt2Phys = (UINT64) 0;
|
||||
cpb_31->Mem_IO = (UINT64) &snp_undi32_callback_memio;
|
||||
|
||||
cpb_31->Map_Mem = (UINT64) &snp_undi32_callback_map;
|
||||
cpb_31->UnMap_Mem = (UINT64) &snp_undi32_callback_unmap;
|
||||
cpb_31->Sync_Mem = (UINT64) &snp_undi32_callback_sync;
|
||||
|
||||
cpb_31->Unique_ID = (UINT64) (UINTN) snp;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.start() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
//
|
||||
// UNDI could not be started. Return UNDI error.
|
||||
//
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.start() %xh:%xh\n",
|
||||
snp->cdb.StatCode,
|
||||
snp->cdb.StatFlags)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Set simple network state to Started and return success.
|
||||
//
|
||||
snp->mode.State = EfiSimpleNetworkStarted;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_start (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *This
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for starting the interface
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_start routine to actually do start undi interface
|
||||
|
||||
Arguments:
|
||||
This - context pointer
|
||||
|
||||
Returns:
|
||||
EFI_INVALID_PARAMETER - "This" is Null
|
||||
- No SNP driver can be extracted from "This"
|
||||
EFI_ALREADY_STARTED - The state of SNP is EfiSimpleNetworkStarted
|
||||
or EfiSimpleNetworkInitialized
|
||||
EFI_DEVICE_ERROR - The state of SNP is other than EfiSimpleNetworkStarted,
|
||||
EfiSimpleNetworkInitialized, and EfiSimpleNetworkStopped
|
||||
EFI_SUCCESS - UNDI interface is succesfully started
|
||||
Other - Error occurs while calling pxe_start function.
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *Snp;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
|
||||
|
||||
if (Snp == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (Snp->mode.State) {
|
||||
case EfiSimpleNetworkStopped:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
case EfiSimpleNetworkInitialized:
|
||||
return EFI_ALREADY_STARTED;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Status = pxe_start (Snp);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// clear the map_list in SNP structure
|
||||
//
|
||||
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
|
||||
Snp->map_list[Index].virt = 0;
|
||||
Snp->map_list[Index].map_cookie = 0;
|
||||
}
|
||||
|
||||
Snp->mode.MCastFilterCount = 0;
|
||||
|
||||
return Status;
|
||||
}
|
248
EdkModulePkg/Universal/Network/Snp32_64/Dxe/station_address.c
Normal file
248
EdkModulePkg/Universal/Network/Snp32_64/Dxe/station_address.c
Normal file
@@ -0,0 +1,248 @@
|
||||
/*++
|
||||
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:
|
||||
station_address.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_get_stn_addr (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to read the MAC address of the NIC and updates the
|
||||
mode structure with the address.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_DB_STATION_ADDRESS *db;
|
||||
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
|
||||
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.station_addr() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Set new station address in SNP->Mode structure and return success.
|
||||
//
|
||||
CopyMem (
|
||||
&(snp->mode.CurrentAddress),
|
||||
&db->StationAddr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&snp->mode.BroadcastAddress,
|
||||
&db->BroadcastAddr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
CopyMem (
|
||||
&snp->mode.PermanentAddress,
|
||||
&db->PermanentAddr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
pxe_set_stn_addr (
|
||||
SNP_DRIVER *snp,
|
||||
EFI_MAC_ADDRESS *NewMacAddr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to set a new MAC address for the NIC,
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL
|
||||
then this routine resets the mac address to the NIC's original
|
||||
address.
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_CPB_STATION_ADDRESS *cpb;
|
||||
PXE_DB_STATION_ADDRESS *db;
|
||||
|
||||
cpb = snp->cpb;
|
||||
db = snp->db;
|
||||
snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
|
||||
|
||||
if (NewMacAddr == NULL) {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_RESET;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
} else {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
|
||||
//
|
||||
// even though the OPFLAGS are set to READ, supplying a new address
|
||||
// in the CPB will make undi change the mac address to the new one.
|
||||
//
|
||||
CopyMem (&cpb->StationAddr, NewMacAddr, snp->mode.HwAddressSize);
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_STATION_ADDRESS);
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
|
||||
}
|
||||
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) db;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.station_addr() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
//
|
||||
// UNDI command failed. Return UNDI status to caller.
|
||||
//
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// read the changed address and save it in SNP->Mode structure
|
||||
//
|
||||
pxe_get_stn_addr (snp);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_station_address (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN ResetFlag,
|
||||
IN EFI_MAC_ADDRESS * NewMacAddr OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for changing the NIC's mac address.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the above routines to actually do the work
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL
|
||||
then this routine resets the mac address to the NIC's original
|
||||
address.
|
||||
ResetFlag - If true, the mac address will change to NIC's original address
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Get pointer to SNP driver instance for *this.
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Return error if the SNP is not initialized.
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Check for invalid parameter combinations.
|
||||
//
|
||||
if (!ResetFlag && NewMacAddr == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (ResetFlag) {
|
||||
Status = pxe_set_stn_addr (snp, NULL);
|
||||
} else {
|
||||
Status = pxe_set_stn_addr (snp, NewMacAddr);
|
||||
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
193
EdkModulePkg/Universal/Network/Snp32_64/Dxe/statistics.c
Normal file
193
EdkModulePkg/Universal/Network/Snp32_64/Dxe/statistics.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/*++
|
||||
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:
|
||||
statistics.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-17 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "Snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_statistics (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN BOOLEAN ResetFlag,
|
||||
IN OUT UINTN *StatTableSizePtr OPTIONAL,
|
||||
IN OUT EFI_NETWORK_STATISTICS * StatTablePtr OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for getting the NIC's statistics.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_ routine to actually do the
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
ResetFlag - true to reset the NIC's statistics counters to zero.
|
||||
StatTableSizePtr - pointer to the statistics table size
|
||||
StatTablePtr - pointer to the statistics table
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
PXE_DB_STATISTICS *db;
|
||||
UINT64 *stp;
|
||||
UINT64 mask;
|
||||
UINTN size;
|
||||
UINTN n;
|
||||
|
||||
//
|
||||
// Get pointer to SNP driver instance for *this.
|
||||
//
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Return error if the SNP is not initialized.
|
||||
//
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// if we are not resetting the counters, we have to have a valid stat table
|
||||
// with >0 size. if no reset, no table and no size, return success.
|
||||
//
|
||||
if (!ResetFlag && StatTableSizePtr == NULL) {
|
||||
return StatTablePtr ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// Initialize UNDI Statistics CDB
|
||||
//
|
||||
snp->cdb.OpCode = PXE_OPCODE_STATISTICS;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
if (ResetFlag) {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_RESET;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
db = snp->db;
|
||||
} else {
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_READ;
|
||||
snp->cdb.DBsize = sizeof (PXE_DB_STATISTICS);
|
||||
snp->cdb.DBaddr = (UINT64) (UINTN) (db = snp->db);
|
||||
}
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.statistics() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
break;
|
||||
|
||||
case PXE_STATCODE_UNSUPPORTED:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.statistics() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.statistics() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (ResetFlag) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (StatTablePtr == NULL) {
|
||||
*StatTableSizePtr = sizeof (EFI_NETWORK_STATISTICS);
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
//
|
||||
// Convert the UNDI statistics information to SNP statistics
|
||||
// information.
|
||||
//
|
||||
ZeroMem (StatTablePtr, *StatTableSizePtr);
|
||||
stp = (UINT64 *) StatTablePtr;
|
||||
size = 0;
|
||||
|
||||
for (n = 0, mask = 1; n < 64; n++, mask = LShiftU64 (mask, 1), stp++) {
|
||||
//
|
||||
// There must be room for a full UINT64. Partial
|
||||
// numbers will not be stored.
|
||||
//
|
||||
if ((n + 1) * sizeof (UINT64) > *StatTableSizePtr) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (db->Supported & mask) {
|
||||
*stp = db->Data[n];
|
||||
size = n + 1;
|
||||
} else {
|
||||
SetMem (stp, sizeof (UINT64), 0xFF);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Compute size up to last supported statistic.
|
||||
//
|
||||
while (++n < 64) {
|
||||
if (db->Supported & (mask = LShiftU64 (mask, 1))) {
|
||||
size = n;
|
||||
}
|
||||
}
|
||||
|
||||
size *= sizeof (UINT64);
|
||||
|
||||
if (*StatTableSizePtr >= size) {
|
||||
*StatTableSizePtr = size;
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
*StatTableSizePtr = size;
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
}
|
120
EdkModulePkg/Universal/Network/Snp32_64/Dxe/stop.c
Normal file
120
EdkModulePkg/Universal/Network/Snp32_64/Dxe/stop.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*++
|
||||
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:
|
||||
stop.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-09 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_stop (
|
||||
SNP_DRIVER *snp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
this routine calls undi to stop the interface and changes the snp state
|
||||
|
||||
Arguments:
|
||||
snp - pointer to snp driver structure
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
snp->cdb.OpCode = PXE_OPCODE_STOP;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
|
||||
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.stop() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
|
||||
DEBUG (
|
||||
(EFI_D_WARN,
|
||||
"\nsnp->undi.stop() %xh:%xh\n",
|
||||
snp->cdb.StatCode,
|
||||
snp->cdb.StatFlags)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Set simple network state to Started and return success.
|
||||
//
|
||||
snp->mode.State = EfiSimpleNetworkStopped;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_stop (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the SNP interface routine for stopping the interface.
|
||||
This routine basically retrieves snp structure, checks the SNP state and
|
||||
calls the pxe_stop routine to actually stop the undi interface
|
||||
|
||||
Arguments:
|
||||
this - context pointer
|
||||
|
||||
Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkStarted:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkInitialized:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
return pxe_stop (snp);
|
||||
}
|
396
EdkModulePkg/Universal/Network/Snp32_64/Dxe/transmit.c
Normal file
396
EdkModulePkg/Universal/Network/Snp32_64/Dxe/transmit.c
Normal file
@@ -0,0 +1,396 @@
|
||||
/*++
|
||||
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:
|
||||
|
||||
transmit.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Revision history:
|
||||
2000-Feb-03 M(f)J Genesis.
|
||||
--*/
|
||||
|
||||
|
||||
#include "snp.h"
|
||||
|
||||
EFI_STATUS
|
||||
pxe_fillheader (
|
||||
SNP_DRIVER *snp,
|
||||
VOID *MacHeaderPtr,
|
||||
UINTN MacHeaderSize,
|
||||
VOID *BufferPtr,
|
||||
UINTN BufferLength,
|
||||
EFI_MAC_ADDRESS *DestinationAddrPtr,
|
||||
EFI_MAC_ADDRESS *SourceAddrPtr,
|
||||
UINT16 *ProtocolPtr
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine calls undi to create the meadia header for the given data buffer.
|
||||
|
||||
Arguments:
|
||||
snp - pointer to SNP driver structure
|
||||
MacHeaderPtr - address where the media header will be filled in.
|
||||
MacHeaderSize - size of the memory at MacHeaderPtr
|
||||
BufferPtr - data buffer pointer
|
||||
BufferLength - Size of data in the BufferPtr
|
||||
DestinationAddrPtr - address of the destination mac address buffer
|
||||
SourceAddrPtr - address of the source mac address buffer
|
||||
ProtocolPtr - address of the protocol type
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - if successfully completed the undi call
|
||||
Other - error return from undi call.
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_CPB_FILL_HEADER_FRAGMENTED *cpb;
|
||||
EFI_STATUS Status;
|
||||
struct s_v2p *pkt_v2p;
|
||||
UINT64 TempData;
|
||||
|
||||
cpb = snp->cpb;
|
||||
if (SourceAddrPtr) {
|
||||
CopyMem (
|
||||
(VOID *) cpb->SrcAddr,
|
||||
(VOID *) SourceAddrPtr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
} else {
|
||||
CopyMem (
|
||||
(VOID *) cpb->SrcAddr,
|
||||
(VOID *) &(snp->mode.CurrentAddress),
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
(VOID *) cpb->DestAddr,
|
||||
(VOID *) DestinationAddrPtr,
|
||||
snp->mode.HwAddressSize
|
||||
);
|
||||
|
||||
//
|
||||
// we need to do the byte swapping
|
||||
//
|
||||
cpb->Protocol = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);
|
||||
|
||||
cpb->PacketLen = (UINT32) (BufferLength);
|
||||
cpb->MediaHeaderLen = (UINT16) MacHeaderSize;
|
||||
|
||||
cpb->FragCnt = 2;
|
||||
cpb->reserved = 0;
|
||||
|
||||
cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) MacHeaderPtr;
|
||||
cpb->FragDesc[0].FragLen = (UINT32) MacHeaderSize;
|
||||
cpb->FragDesc[1].FragAddr = (UINT64) (UINTN) BufferPtr;
|
||||
cpb->FragDesc[1].FragLen = (UINT32) BufferLength;
|
||||
|
||||
cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;
|
||||
|
||||
if (snp->IsOldUndi) {
|
||||
TempData = (UINT64) (UINTN) MacHeaderPtr;
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) snp->fill_hdr_buf;
|
||||
cpb->FragDesc[0].FragLen = (UINT32) snp->init_info.MediaHeaderLen;
|
||||
}
|
||||
|
||||
TempData = (UINT64) (UINTN) (BufferPtr);
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
//
|
||||
// Let the device just read this buffer
|
||||
//
|
||||
Status = add_v2p (
|
||||
&pkt_v2p,
|
||||
EfiPciIoOperationBusMasterRead,
|
||||
BufferPtr,
|
||||
BufferLength
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// give the virtual address to UNDI and it will call back on Virt2Phys
|
||||
// to get the mapped address, if it needs it
|
||||
//
|
||||
cpb->FragDesc[1].FragLen = (UINT32) pkt_v2p->bsize;
|
||||
}
|
||||
}
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_FILL_HEADER;
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;
|
||||
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header() "));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
if (snp->IsOldUndi) {
|
||||
TempData = (UINT64) (UINTN) (BufferPtr);
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
del_v2p (BufferPtr);
|
||||
}
|
||||
//
|
||||
// if we used the global buffer for header, copy the contents
|
||||
//
|
||||
TempData = (UINT64) (UINTN) MacHeaderPtr;
|
||||
if (TempData >= FOUR_GIGABYTES) {
|
||||
CopyMem (
|
||||
MacHeaderPtr,
|
||||
snp->fill_hdr_buf,
|
||||
snp->init_info.MediaHeaderLen
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
return EFI_SUCCESS;
|
||||
|
||||
case PXE_STATCODE_INVALID_PARAMETER:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.fill_header() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
default:
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.fill_header() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
pxe_transmit (
|
||||
SNP_DRIVER *snp,
|
||||
VOID *BufferPtr,
|
||||
UINTN BufferLength
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This routine calls undi to transmit the given data buffer
|
||||
|
||||
Arguments:
|
||||
snp - pointer to SNP driver structure
|
||||
BufferPtr - data buffer pointer
|
||||
BufferLength - Size of data in the BufferPtr
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - if successfully completed the undi call
|
||||
Other - error return from undi call.
|
||||
|
||||
--*/
|
||||
{
|
||||
PXE_CPB_TRANSMIT *cpb;
|
||||
EFI_STATUS Status;
|
||||
struct s_v2p *v2p;
|
||||
UINT64 TempData;
|
||||
|
||||
cpb = snp->cpb;
|
||||
cpb->FrameAddr = (UINT64) (UINTN) BufferPtr;
|
||||
cpb->DataLen = (UINT32) BufferLength;
|
||||
|
||||
TempData = (UINT64) (UINTN) BufferPtr;
|
||||
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
|
||||
//
|
||||
// we need to create a mapping now and give it to the undi when it calls
|
||||
// the Virt2Phys on this address.
|
||||
// this is a transmit, just map it for the device to READ
|
||||
//
|
||||
Status = add_v2p (
|
||||
&v2p,
|
||||
EfiPciIoOperationBusMasterRead,
|
||||
BufferPtr,
|
||||
BufferLength
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
cpb->DataLen = (UINT32) v2p->bsize;
|
||||
}
|
||||
|
||||
cpb->MediaheaderLen = 0;
|
||||
cpb->reserved = 0;
|
||||
|
||||
snp->cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;
|
||||
|
||||
snp->cdb.CPBsize = sizeof (PXE_CPB_TRANSMIT);
|
||||
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
|
||||
|
||||
snp->cdb.OpCode = PXE_OPCODE_TRANSMIT;
|
||||
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
|
||||
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
|
||||
|
||||
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
|
||||
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
|
||||
snp->cdb.IFnum = snp->if_num;
|
||||
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
|
||||
|
||||
//
|
||||
// Issue UNDI command and check result.
|
||||
//
|
||||
DEBUG ((EFI_D_NET, "\nsnp->undi.transmit() "));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode == %x", snp->cdb.OpCode));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %X", snp->cdb.CPBaddr));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr == %X", snp->cdb.DBaddr));
|
||||
DEBUG ((EFI_D_NET, "\ncpb->FrameAddr == %X\n", cpb->FrameAddr));
|
||||
|
||||
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
|
||||
|
||||
DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit() "));
|
||||
DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));
|
||||
|
||||
//
|
||||
// we will unmap the buffers in get_status call, not here
|
||||
//
|
||||
switch (snp->cdb.StatCode) {
|
||||
case PXE_STATCODE_SUCCESS:
|
||||
return EFI_SUCCESS;
|
||||
|
||||
case PXE_STATCODE_QUEUE_FULL:
|
||||
case PXE_STATCODE_BUSY:
|
||||
Status = EFI_NOT_READY;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
DEBUG (
|
||||
(EFI_D_ERROR,
|
||||
"\nsnp->undi.transmit() %xh:%xh\n",
|
||||
snp->cdb.StatFlags,
|
||||
snp->cdb.StatCode)
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
snp_undi32_transmit (
|
||||
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
|
||||
IN UINTN MacHeaderSize,
|
||||
IN UINTN BufferLength,
|
||||
IN VOID *BufferPtr,
|
||||
IN EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,
|
||||
IN EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,
|
||||
IN UINT16 *ProtocolPtr OPTIONAL
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the snp interface routine for transmitting a packet. this routine
|
||||
basically retrieves the snp structure, checks the snp state and calls
|
||||
pxe_fill_header and pxe_transmit calls to complete the transmission.
|
||||
|
||||
Arguments:
|
||||
this - pointer to SNP driver context
|
||||
MacHeaderSize - size of the memory at MacHeaderPtr
|
||||
BufferLength - Size of data in the BufferPtr
|
||||
BufferPtr - data buffer pointer
|
||||
SourceAddrPtr - address of the source mac address buffer
|
||||
DestinationAddrPtr - address of the destination mac address buffer
|
||||
ProtocolPtr - address of the protocol type
|
||||
|
||||
Returns:
|
||||
EFI_SUCCESS - if successfully completed the undi call
|
||||
Other - error return from undi call.
|
||||
|
||||
--*/
|
||||
{
|
||||
SNP_DRIVER *snp;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (this == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
|
||||
|
||||
if (snp == NULL) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
switch (snp->mode.State) {
|
||||
case EfiSimpleNetworkInitialized:
|
||||
break;
|
||||
|
||||
case EfiSimpleNetworkStopped:
|
||||
return EFI_NOT_STARTED;
|
||||
|
||||
case EfiSimpleNetworkStarted:
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
default:
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (BufferPtr == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (BufferLength < snp->mode.MediaHeaderSize) {
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
//
|
||||
// if the MacHeaderSize is non-zero, we need to fill up the header and for that
|
||||
// we need the destination address and the protocol
|
||||
//
|
||||
if (MacHeaderSize != 0) {
|
||||
if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = pxe_fillheader (
|
||||
snp,
|
||||
BufferPtr,
|
||||
MacHeaderSize,
|
||||
(UINT8 *) BufferPtr + MacHeaderSize,
|
||||
BufferLength - MacHeaderSize,
|
||||
DestinationAddrPtr,
|
||||
SourceAddrPtr,
|
||||
ProtocolPtr
|
||||
);
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
return pxe_transmit (snp, BufferPtr, BufferLength);
|
||||
}
|
Reference in New Issue
Block a user