NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
Signed-off-by: Liming Gao <liming.gao@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>
This commit is contained in:
811
NetworkPkg/ArpDxe/ArpDriver.c
Normal file
811
NetworkPkg/ArpDxe/ArpDriver.c
Normal file
@@ -0,0 +1,811 @@
|
||||
/** @file
|
||||
ARP driver functions.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "ArpDriver.h"
|
||||
#include "ArpImpl.h"
|
||||
|
||||
EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding = {
|
||||
ArpDriverBindingSupported,
|
||||
ArpDriverBindingStart,
|
||||
ArpDriverBindingStop,
|
||||
0xa,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Create and initialize the arp service context data.
|
||||
|
||||
@param[in] ImageHandle The image handle representing the loaded driver
|
||||
image.
|
||||
@param[in] ControllerHandle The controller handle the driver binds to.
|
||||
@param[in, out] ArpService Pointer to the buffer containing the arp service
|
||||
context data.
|
||||
|
||||
@retval EFI_SUCCESS The arp service context is initialized.
|
||||
|
||||
@retval EFI_UNSUPPORTED The underlayer Snp mode type is not ethernet.
|
||||
Failed to initialize the service context.
|
||||
@retval other Failed to initialize the arp service context.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ArpCreateService (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN OUT ARP_SERVICE_DATA *ArpService
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
ASSERT (ArpService != NULL);
|
||||
|
||||
ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;
|
||||
|
||||
//
|
||||
// Init the lists.
|
||||
//
|
||||
InitializeListHead (&ArpService->ChildrenList);
|
||||
InitializeListHead (&ArpService->PendingRequestTable);
|
||||
InitializeListHead (&ArpService->DeniedCacheTable);
|
||||
InitializeListHead (&ArpService->ResolvedCacheTable);
|
||||
|
||||
//
|
||||
// Init the servicebinding protocol members.
|
||||
//
|
||||
ArpService->ServiceBinding.CreateChild = ArpServiceBindingCreateChild;
|
||||
ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;
|
||||
|
||||
//
|
||||
// Save the handles.
|
||||
//
|
||||
ArpService->ImageHandle = ImageHandle;
|
||||
ArpService->ControllerHandle = ControllerHandle;
|
||||
|
||||
//
|
||||
// Create a MNP child instance.
|
||||
//
|
||||
Status = NetLibCreateServiceChild (
|
||||
ControllerHandle,
|
||||
ImageHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
&ArpService->MnpChildHandle
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the MNP protocol.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
(VOID **)&ArpService->Mnp,
|
||||
ImageHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the underlayer Snp mode data.
|
||||
//
|
||||
Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);
|
||||
if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
|
||||
//
|
||||
// Only support the ethernet.
|
||||
//
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the Mnp config parameters.
|
||||
//
|
||||
ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;
|
||||
ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;
|
||||
ArpService->MnpConfigData.ProtocolTypeFilter = ARP_ETHER_PROTO_TYPE;
|
||||
ArpService->MnpConfigData.EnableUnicastReceive = TRUE;
|
||||
ArpService->MnpConfigData.EnableMulticastReceive = FALSE;
|
||||
ArpService->MnpConfigData.EnableBroadcastReceive = TRUE;
|
||||
ArpService->MnpConfigData.EnablePromiscuousReceive = FALSE;
|
||||
ArpService->MnpConfigData.FlushQueuesOnReset = TRUE;
|
||||
ArpService->MnpConfigData.EnableReceiveTimestamps = FALSE;
|
||||
ArpService->MnpConfigData.DisableBackgroundPolling = FALSE;
|
||||
|
||||
//
|
||||
// Configure the Mnp child.
|
||||
//
|
||||
Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the event used in the RxToken.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
ArpOnFrameRcvd,
|
||||
ArpService,
|
||||
&ArpService->RxToken.Event
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the Arp heartbeat timer.
|
||||
//
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL | EVT_TIMER,
|
||||
TPL_CALLBACK,
|
||||
ArpTimerHandler,
|
||||
ArpService,
|
||||
&ArpService->PeriodicTimer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Start the heartbeat timer.
|
||||
//
|
||||
Status = gBS->SetTimer (
|
||||
ArpService->PeriodicTimer,
|
||||
TimerPeriodic,
|
||||
ARP_PERIODIC_TIMER_INTERVAL
|
||||
);
|
||||
|
||||
ERROR_EXIT:
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Clean the arp service context data.
|
||||
|
||||
@param[in, out] ArpService Pointer to the buffer containing the arp service
|
||||
context data.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpCleanService (
|
||||
IN OUT ARP_SERVICE_DATA *ArpService
|
||||
)
|
||||
{
|
||||
NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);
|
||||
|
||||
if (ArpService->PeriodicTimer != NULL) {
|
||||
//
|
||||
// Cancle and close the PeriodicTimer.
|
||||
//
|
||||
gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);
|
||||
gBS->CloseEvent (ArpService->PeriodicTimer);
|
||||
}
|
||||
|
||||
if (ArpService->RxToken.Event != NULL) {
|
||||
//
|
||||
// Cancle the RxToken and close the event in the RxToken.
|
||||
//
|
||||
ArpService->Mnp->Cancel (ArpService->Mnp, NULL);
|
||||
gBS->CloseEvent (ArpService->RxToken.Event);
|
||||
}
|
||||
|
||||
if (ArpService->Mnp != NULL) {
|
||||
//
|
||||
// Reset the Mnp child and close the Mnp protocol.
|
||||
//
|
||||
ArpService->Mnp->Configure (ArpService->Mnp, NULL);
|
||||
gBS->CloseProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
ArpService->ImageHandle,
|
||||
ArpService->ControllerHandle
|
||||
);
|
||||
}
|
||||
|
||||
if (ArpService->MnpChildHandle != NULL) {
|
||||
//
|
||||
// Destroy the mnp child.
|
||||
//
|
||||
NetLibDestroyServiceChild(
|
||||
ArpService->ControllerHandle,
|
||||
ArpService->ImageHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
ArpService->MnpChildHandle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Callback function which provided by user to remove one node in NetDestroyLinkList process.
|
||||
|
||||
@param[in] Entry The entry to be removed.
|
||||
@param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been removed successfully.
|
||||
@retval Others Fail to remove the entry.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDestroyChildEntryInHandleBuffer (
|
||||
IN LIST_ENTRY *Entry,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
|
||||
if (Entry == NULL || Context == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
|
||||
ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
|
||||
|
||||
return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
|
||||
}
|
||||
|
||||
/**
|
||||
Tests to see if this driver supports a given controller.
|
||||
|
||||
If a child device is provided, it further tests to see if this driver supports
|
||||
creating a handle for the specified child device.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver
|
||||
specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed
|
||||
by the driver specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by
|
||||
a different driver or an application that
|
||||
requires exclusive acces. Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the
|
||||
driver specified by This.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Test to see if Arp SB is already installed.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Test to see if MNP SB is installed.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ControllerHandle,
|
||||
&gEfiManagedNetworkServiceBindingProtocolGuid,
|
||||
NULL,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||
);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been
|
||||
moved into this common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
|
||||
aligned EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified
|
||||
by This must have been called with the same calling parameters, and Supported()
|
||||
must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.
|
||||
Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
|
||||
resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
|
||||
//
|
||||
// Allocate a zero pool for ArpService.
|
||||
//
|
||||
ArpService = AllocateZeroPool (sizeof(ARP_SERVICE_DATA));
|
||||
if (ArpService == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the arp service context data.
|
||||
//
|
||||
Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// Install the ARP service binding protocol.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&ControllerHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
&ArpService->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// OK, start to receive arp packets from Mnp.
|
||||
//
|
||||
Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
||||
ERROR:
|
||||
|
||||
//
|
||||
// On error, clean the arp service context data, and free the memory allocated.
|
||||
//
|
||||
ArpCleanService (ArpService);
|
||||
FreePool (ArpService);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
Release the control of this controller and remove the IScsi functions. The Stop()
|
||||
function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
Not used.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.Not used.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE NicHandle;
|
||||
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
LIST_ENTRY *List;
|
||||
|
||||
//
|
||||
// Get the NicHandle which the arp servicebinding is installed on.
|
||||
//
|
||||
NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
|
||||
if (NicHandle == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Try to get the arp servicebinding protocol on the NicHandle.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
NicHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
(VOID **)&ServiceBinding,
|
||||
This->DriverBindingHandle,
|
||||
ControllerHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
|
||||
|
||||
if (NumberOfChildren != 0) {
|
||||
//
|
||||
// NumberOfChildren is not zero, destroy all the ARP children instances.
|
||||
//
|
||||
List = &ArpService->ChildrenList;
|
||||
Status = NetDestroyLinkList (
|
||||
List,
|
||||
ArpDestroyChildEntryInHandleBuffer,
|
||||
ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
|
||||
ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
|
||||
ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
|
||||
} else if (IsListEmpty (&ArpService->ChildrenList)) {
|
||||
//
|
||||
// Uninstall the ARP ServiceBinding protocol.
|
||||
//
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
NicHandle,
|
||||
&gEfiArpServiceBindingProtocolGuid,
|
||||
&ArpService->ServiceBinding,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Clean the arp servicebinding context data and free the memory allocated.
|
||||
//
|
||||
ArpCleanService (ArpService);
|
||||
|
||||
FreePool (ArpService);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned
|
||||
in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
|
||||
installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing
|
||||
UEFI handle, then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
VOID *Mnp;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Allocate memory for the instance context data.
|
||||
//
|
||||
Instance = AllocateZeroPool (sizeof(ARP_INSTANCE_DATA));
|
||||
if (Instance == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
|
||||
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
//
|
||||
// Init the instance context data.
|
||||
//
|
||||
ArpInitInstance (ArpService, Instance);
|
||||
|
||||
//
|
||||
// Install the ARP protocol onto the ChildHandle.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
(VOID *)&Instance->ArpProto,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));
|
||||
|
||||
FreePool (Instance);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the ChildHandle.
|
||||
//
|
||||
Instance->Handle = *ChildHandle;
|
||||
|
||||
//
|
||||
// Open the Managed Network protocol BY_CHILD.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
(VOID **) &Mnp,
|
||||
gArpDriverBinding.DriverBindingHandle,
|
||||
Instance->Handle,
|
||||
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Insert the instance into children list managed by the arp service context data.
|
||||
//
|
||||
InsertTailList (&ArpService->ChildrenList, &Instance->List);
|
||||
ArpService->ChildrenNumber++;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
ERROR:
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
||||
gBS->CloseProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
gArpDriverBinding.DriverBindingHandle,
|
||||
Instance->Handle
|
||||
);
|
||||
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
Instance->Handle,
|
||||
&gEfiArpProtocolGuid,
|
||||
&Instance->ArpProto,
|
||||
NULL
|
||||
);
|
||||
|
||||
//
|
||||
// Free the allocated memory.
|
||||
//
|
||||
FreePool (Instance);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
|
||||
being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_ARP_PROTOCOL *Arp;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (ChildHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
|
||||
|
||||
//
|
||||
// Get the arp protocol.
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
(VOID **)&Arp,
|
||||
ArpService->ImageHandle,
|
||||
ChildHandle,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
|
||||
|
||||
if (Instance->InDestroy) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// Use the InDestroy as a flag to avoid re-entrance.
|
||||
//
|
||||
Instance->InDestroy = TRUE;
|
||||
|
||||
//
|
||||
// Close the Managed Network protocol.
|
||||
//
|
||||
gBS->CloseProtocol (
|
||||
ArpService->MnpChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid,
|
||||
gArpDriverBinding.DriverBindingHandle,
|
||||
ChildHandle
|
||||
);
|
||||
|
||||
//
|
||||
// Uninstall the ARP protocol.
|
||||
//
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
&Instance->ArpProto,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
|
||||
Status));
|
||||
|
||||
Instance->InDestroy = FALSE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
if (Instance->Configured) {
|
||||
//
|
||||
// Delete the related cache entry.
|
||||
//
|
||||
ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);
|
||||
|
||||
//
|
||||
// Reset the instance configuration.
|
||||
//
|
||||
ArpConfigureInstance (Instance, NULL);
|
||||
}
|
||||
|
||||
//
|
||||
// Remove this instance from the ChildrenList.
|
||||
//
|
||||
RemoveEntryList (&Instance->List);
|
||||
ArpService->ChildrenNumber--;
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
FreePool (Instance);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
The entry point for Arp driver which installs the driver binding and component name
|
||||
protocol on its ImageHandle.
|
||||
|
||||
@param[in] ImageHandle The image handle of the driver.
|
||||
@param[in] SystemTable The system table.
|
||||
|
||||
@retval EFI_SUCCESS if the driver binding and component name protocols
|
||||
are successfully
|
||||
@retval Others Failed to install the protocols.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverEntryPoint (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
return EfiLibInstallDriverBindingComponentName2 (
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
&gArpDriverBinding,
|
||||
ImageHandle,
|
||||
&gArpComponentName,
|
||||
&gArpComponentName2
|
||||
);
|
||||
}
|
||||
|
334
NetworkPkg/ArpDxe/ArpDriver.h
Normal file
334
NetworkPkg/ArpDxe/ArpDriver.h
Normal file
@@ -0,0 +1,334 @@
|
||||
/** @file
|
||||
ARP driver header file.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _ARP_DRIVER_H_
|
||||
#define _ARP_DRIVER_H_
|
||||
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/Arp.h>
|
||||
#include <Protocol/ManagedNetwork.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
|
||||
|
||||
//
|
||||
// Global variables
|
||||
//
|
||||
extern EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding;
|
||||
extern EFI_COMPONENT_NAME_PROTOCOL gArpComponentName;
|
||||
extern EFI_COMPONENT_NAME2_PROTOCOL gArpComponentName2;
|
||||
|
||||
//
|
||||
// Function prototypes for the Drivr Binding Protocol
|
||||
//
|
||||
/**
|
||||
Tests to see if this driver supports a given controller.
|
||||
|
||||
If a child device is provided, it further tests to see if this driver supports
|
||||
creating a handle for the specified child device.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||||
RemainingDevicePath is supported by the driver
|
||||
specified by This.
|
||||
@retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed
|
||||
by the driver specified by This.
|
||||
@retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is already being managed by
|
||||
a different driver or an application that
|
||||
requires exclusive acces. Currently not implemented.
|
||||
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||||
RemainingDevicePath is not supported by the
|
||||
driver specified by This.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingSupported (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Start this driver on ControllerHandle.
|
||||
|
||||
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||||
As a result, much of the error checking on the parameters to Start() has been
|
||||
moved into this common boot service. It is legal to call Start() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE.
|
||||
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
|
||||
aligned EFI_DEVICE_PATH_PROTOCOL.
|
||||
3. Prior to calling Start(), the Supported() function for the driver specified
|
||||
by This must have been called with the same calling parameters, and Supported()
|
||||
must have returned EFI_SUCCESS.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||||
must support a protocol interface that supplies
|
||||
an I/O abstraction to the driver.
|
||||
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
|
||||
This parameter is ignored by device drivers,
|
||||
and is optional for bus drivers.
|
||||
|
||||
@retval EFI_SUCCESS The device was started.
|
||||
@retval EFI_DEVICE_ERROR The device could not be started due to a device error.
|
||||
Currently not implemented.
|
||||
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
|
||||
resources.
|
||||
@retval Others The driver failded to start the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStart (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Stop this driver on ControllerHandle.
|
||||
|
||||
Release the control of this controller and remove the IScsi functions. The Stop()
|
||||
function is designed to be invoked from the EFI boot service DisconnectController().
|
||||
As a result, much of the error checking on the parameters to Stop() has been moved
|
||||
into this common boot service. It is legal to call Stop() from other locations,
|
||||
but the following calling restrictions must be followed or the system behavior
|
||||
will not be deterministic.
|
||||
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||||
same driver's Start() function.
|
||||
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||||
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||||
Start() function, and the Start() function must have called OpenProtocol() on
|
||||
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
|
||||
|
||||
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||||
@param[in] ControllerHandle A handle to the device being stopped. The handle must
|
||||
support a bus specific I/O protocol for the driver
|
||||
to use to stop the device.
|
||||
@param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
|
||||
Not used.
|
||||
@param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
|
||||
if NumberOfChildren is 0.Not used.
|
||||
|
||||
@retval EFI_SUCCESS The device was stopped.
|
||||
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDriverBindingStop (
|
||||
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN UINTN NumberOfChildren,
|
||||
IN EFI_HANDLE *ChildHandleBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
Creates a child handle and installs a protocol.
|
||||
|
||||
The CreateChild() function installs a protocol on ChildHandle.
|
||||
If ChildHandle is a pointer to NULL, then a new handle is created and returned
|
||||
in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
|
||||
installs on the existing ChildHandle.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Pointer to the handle of the child to create. If it is NULL,
|
||||
then a new handle is created. If it is a pointer to an existing
|
||||
UEFI handle, then the protocol is added to the existing UEFI handle.
|
||||
|
||||
@retval EFI_SUCCES The protocol was added to ChildHandle.
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is NULL.
|
||||
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
|
||||
the child
|
||||
@retval other The child handle was not created
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingCreateChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE *ChildHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Destroys a child handle with a protocol installed on it.
|
||||
|
||||
The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
|
||||
that was installed by CreateChild() from ChildHandle. If the removed protocol is the
|
||||
last protocol on ChildHandle, then ChildHandle is destroyed.
|
||||
|
||||
@param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
|
||||
@param ChildHandle Handle of the child to destroy
|
||||
|
||||
@retval EFI_SUCCES The protocol was removed from ChildHandle.
|
||||
@retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
|
||||
being removed.
|
||||
@retval EFI_INVALID_PARAMETER Child handle is NULL.
|
||||
@retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
|
||||
because its services are being used.
|
||||
@retval other The child handle was not destroyed
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpServiceBindingDestroyChild (
|
||||
IN EFI_SERVICE_BINDING_PROTOCOL *This,
|
||||
IN EFI_HANDLE ChildHandle
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// EFI Component Name Functions
|
||||
//
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the driver.
|
||||
|
||||
This function retrieves the user readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name 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. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] 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.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] 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.
|
||||
|
||||
@param[in] 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.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name 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. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] 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.
|
||||
|
||||
@retval 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.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
|
62
NetworkPkg/ArpDxe/ArpDxe.inf
Normal file
62
NetworkPkg/ArpDxe/ArpDxe.inf
Normal file
@@ -0,0 +1,62 @@
|
||||
## @file
|
||||
# This module produces EFI ARP Protocol and EFI ARP Service Binding Protocol.
|
||||
#
|
||||
# This module produces EFI ARP Protocol upon EFI MNP Protocol, to provide a generic
|
||||
# implementation of the Address Resolution Protocol that is described in RFCs 826
|
||||
# and 1122.
|
||||
#
|
||||
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = ArpDxe
|
||||
MODULE_UNI_FILE = ArpDxe.uni
|
||||
FILE_GUID = 529D3F93-E8E9-4e73-B1E1-BDF6A9D50113
|
||||
MODULE_TYPE = UEFI_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = ArpDriverEntryPoint
|
||||
UNLOAD_IMAGE = NetLibDefaultUnload
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 EBC
|
||||
#
|
||||
# DRIVER_BINDING = gArpDriverBinding
|
||||
# COMPONENT_NAME = gArpComponentName
|
||||
# COMPONENT_NAME2 = gArpComponentName2
|
||||
#
|
||||
|
||||
[Sources]
|
||||
ArpMain.c
|
||||
ArpDriver.h
|
||||
ComponentName.c
|
||||
ArpImpl.h
|
||||
ArpImpl.c
|
||||
ArpDriver.c
|
||||
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
UefiDriverEntryPoint
|
||||
DebugLib
|
||||
NetLib
|
||||
DpcLib
|
||||
|
||||
[Protocols]
|
||||
gEfiArpServiceBindingProtocolGuid ## BY_START
|
||||
gEfiManagedNetworkServiceBindingProtocolGuid ## TO_START
|
||||
gEfiArpProtocolGuid ## BY_START
|
||||
gEfiManagedNetworkProtocolGuid ## TO_START
|
||||
|
||||
[UserExtensions.TianoCore."ExtraFiles"]
|
||||
ArpDxeExtra.uni
|
18
NetworkPkg/ArpDxe/ArpDxe.uni
Normal file
18
NetworkPkg/ArpDxe/ArpDxe.uni
Normal file
@@ -0,0 +1,18 @@
|
||||
// /** @file
|
||||
// This module produces EFI ARP Protocol and EFI ARP Service Binding Protocol.
|
||||
//
|
||||
// This module produces EFI ARP Protocol upon EFI MNP Protocol, to provide a generic
|
||||
// implementation of the Address Resolution Protocol that is described in RFCs 826
|
||||
// and 1122.
|
||||
//
|
||||
// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
|
||||
#string STR_MODULE_ABSTRACT #language en-US "EFI Address Resolution Protocol"
|
||||
|
||||
#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI ARP Protocol using the EFI MNP Protocol to provide a generic implementation of the Address Resolution Protocol that is described in RFCs 826 and 1122."
|
||||
|
14
NetworkPkg/ArpDxe/ArpDxeExtra.uni
Normal file
14
NetworkPkg/ArpDxe/ArpDxeExtra.uni
Normal file
@@ -0,0 +1,14 @@
|
||||
// /** @file
|
||||
// ArpDxe Localized Strings and Content
|
||||
//
|
||||
// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
//
|
||||
// **/
|
||||
|
||||
#string STR_PROPERTIES_MODULE_NAME
|
||||
#language en-US
|
||||
"ARP DXE Driver"
|
||||
|
||||
|
1667
NetworkPkg/ArpDxe/ArpImpl.c
Normal file
1667
NetworkPkg/ArpDxe/ArpImpl.c
Normal file
File diff suppressed because it is too large
Load Diff
770
NetworkPkg/ArpDxe/ArpImpl.h
Normal file
770
NetworkPkg/ArpDxe/ArpImpl.h
Normal file
@@ -0,0 +1,770 @@
|
||||
/** @file
|
||||
EFI Address Resolution Protocol (ARP) Protocol interface header file.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _ARP_IMPL_H_
|
||||
#define _ARP_IMPL_H_
|
||||
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <Protocol/Arp.h>
|
||||
#include <Protocol/ManagedNetwork.h>
|
||||
#include <Protocol/ServiceBinding.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/UefiDriverEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/NetLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/DpcLib.h>
|
||||
|
||||
//
|
||||
// Ethernet protocol type definitions.
|
||||
//
|
||||
#define ARP_ETHER_PROTO_TYPE 0x0806
|
||||
#define IPV4_ETHER_PROTO_TYPE 0x0800
|
||||
#define IPV6_ETHER_PROTO_TYPE 0x86DD
|
||||
|
||||
//
|
||||
// ARP opcode definitions.
|
||||
//
|
||||
#define ARP_OPCODE_REQUEST 0x0001
|
||||
#define ARP_OPCODE_REPLY 0x0002
|
||||
|
||||
//
|
||||
// ARP timeout, retry count and interval definitions.
|
||||
//
|
||||
#define ARP_DEFAULT_TIMEOUT_VALUE (400 * TICKS_PER_SECOND)
|
||||
#define ARP_DEFAULT_RETRY_COUNT 2
|
||||
#define ARP_DEFAULT_RETRY_INTERVAL (5 * TICKS_PER_MS)
|
||||
#define ARP_PERIODIC_TIMER_INTERVAL (500 * TICKS_PER_MS)
|
||||
|
||||
//
|
||||
// ARP packet head definition.
|
||||
//
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
UINT16 HwType;
|
||||
UINT16 ProtoType;
|
||||
UINT8 HwAddrLen;
|
||||
UINT8 ProtoAddrLen;
|
||||
UINT16 OpCode;
|
||||
} ARP_HEAD;
|
||||
#pragma pack()
|
||||
|
||||
//
|
||||
// ARP Address definition for internal use.
|
||||
//
|
||||
typedef struct {
|
||||
UINT8 *SenderHwAddr;
|
||||
UINT8 *SenderProtoAddr;
|
||||
UINT8 *TargetHwAddr;
|
||||
UINT8 *TargetProtoAddr;
|
||||
} ARP_ADDRESS;
|
||||
|
||||
#define MATCH_SW_ADDRESS 0x1
|
||||
#define MATCH_HW_ADDRESS 0x2
|
||||
|
||||
//
|
||||
// Enumeration for the search type. A search type is specified as the keyword to find
|
||||
// a cache entry in the cache table.
|
||||
//
|
||||
typedef enum {
|
||||
ByNone = 0,
|
||||
ByProtoAddress = MATCH_SW_ADDRESS,
|
||||
ByHwAddress = MATCH_HW_ADDRESS,
|
||||
ByBoth = MATCH_SW_ADDRESS | MATCH_HW_ADDRESS
|
||||
} FIND_OPTYPE;
|
||||
|
||||
#define ARP_INSTANCE_DATA_SIGNATURE SIGNATURE_32('A', 'R', 'P', 'I')
|
||||
|
||||
/**
|
||||
Returns a pointer to the ARP_INSTANCE_DATA structure from the input a.
|
||||
|
||||
If the signatures matches, then a pointer to the data structure that contains
|
||||
a specified field of that data structure is returned.
|
||||
|
||||
@param a Pointer to the field specified by ArpProto within a data
|
||||
structure of type ARP_INSTANCE_DATA.
|
||||
|
||||
**/
|
||||
#define ARP_INSTANCE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
ARP_INSTANCE_DATA, \
|
||||
ArpProto, \
|
||||
ARP_INSTANCE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
typedef struct _ARP_SERVICE_DATA ARP_SERVICE_DATA;
|
||||
|
||||
//
|
||||
// ARP instance context data structure.
|
||||
//
|
||||
typedef struct {
|
||||
UINT32 Signature;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_ARP_PROTOCOL ArpProto;
|
||||
LIST_ENTRY List;
|
||||
EFI_ARP_CONFIG_DATA ConfigData;
|
||||
BOOLEAN Configured;
|
||||
BOOLEAN InDestroy;
|
||||
} ARP_INSTANCE_DATA;
|
||||
|
||||
#define ARP_SERVICE_DATA_SIGNATURE SIGNATURE_32('A', 'R', 'P', 'S')
|
||||
|
||||
/**
|
||||
Returns a pointer to the ARP_SERVICE_DATA structure from the input a.
|
||||
|
||||
If the signatures matches, then a pointer to the data structure that contains
|
||||
a specified field of that data structure is returned.
|
||||
|
||||
@param a Pointer to the field specified by ServiceBinding within
|
||||
a data structure of type ARP_SERVICE_DATA.
|
||||
|
||||
**/
|
||||
#define ARP_SERVICE_DATA_FROM_THIS(a) \
|
||||
CR ( \
|
||||
(a), \
|
||||
ARP_SERVICE_DATA, \
|
||||
ServiceBinding, \
|
||||
ARP_SERVICE_DATA_SIGNATURE \
|
||||
)
|
||||
|
||||
//
|
||||
// ARP service data structure.
|
||||
//
|
||||
struct _ARP_SERVICE_DATA {
|
||||
UINT32 Signature;
|
||||
EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
|
||||
|
||||
EFI_HANDLE MnpChildHandle;
|
||||
EFI_HANDLE ImageHandle;
|
||||
EFI_HANDLE ControllerHandle;
|
||||
|
||||
EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
|
||||
EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
|
||||
EFI_MANAGED_NETWORK_COMPLETION_TOKEN RxToken;
|
||||
|
||||
EFI_SIMPLE_NETWORK_MODE SnpMode;
|
||||
|
||||
UINTN ChildrenNumber;
|
||||
LIST_ENTRY ChildrenList;
|
||||
|
||||
LIST_ENTRY PendingRequestTable;
|
||||
LIST_ENTRY DeniedCacheTable;
|
||||
LIST_ENTRY ResolvedCacheTable;
|
||||
|
||||
EFI_EVENT PeriodicTimer;
|
||||
};
|
||||
|
||||
//
|
||||
// User request context structure.
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY List;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_EVENT UserRequestEvent;
|
||||
VOID *UserHwAddrBuffer;
|
||||
} USER_REQUEST_CONTEXT;
|
||||
|
||||
#define ARP_MAX_PROTOCOL_ADDRESS_LEN sizeof(EFI_IP_ADDRESS)
|
||||
#define ARP_MAX_HARDWARE_ADDRESS_LEN sizeof(EFI_MAC_ADDRESS)
|
||||
|
||||
typedef union {
|
||||
UINT8 ProtoAddress[ARP_MAX_PROTOCOL_ADDRESS_LEN];
|
||||
UINT8 HwAddress[ARP_MAX_HARDWARE_ADDRESS_LEN];
|
||||
} NET_ARP_ADDRESS_UNION;
|
||||
|
||||
//
|
||||
// ARP address structure in an ARP packet.
|
||||
//
|
||||
typedef struct {
|
||||
UINT16 Type;
|
||||
UINT8 Length;
|
||||
UINT8 *AddressPtr;
|
||||
NET_ARP_ADDRESS_UNION Buffer;
|
||||
} NET_ARP_ADDRESS;
|
||||
|
||||
//
|
||||
// Enumeration for ARP address type.
|
||||
//
|
||||
typedef enum {
|
||||
Hardware,
|
||||
Protocol
|
||||
} ARP_ADDRESS_TYPE;
|
||||
|
||||
//
|
||||
// ARP cache entry definition.
|
||||
//
|
||||
typedef struct {
|
||||
LIST_ENTRY List;
|
||||
|
||||
UINT32 RetryCount;
|
||||
UINT32 DefaultDecayTime;
|
||||
UINT32 DecayTime;
|
||||
UINT32 NextRetryTime;
|
||||
|
||||
NET_ARP_ADDRESS Addresses[2];
|
||||
|
||||
LIST_ENTRY UserRequestList;
|
||||
} ARP_CACHE_ENTRY;
|
||||
|
||||
/**
|
||||
This function is used to assign a station address to the ARP cache for this instance
|
||||
of the ARP driver.
|
||||
|
||||
Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will
|
||||
respond to ARP requests that match this registered station address. A call to
|
||||
this function with the ConfigData field set to NULL will reset this ARP instance.
|
||||
|
||||
Once a protocol type and station address have been assigned to this ARP instance,
|
||||
all the following ARP functions will use this information. Attempting to change
|
||||
the protocol type or station address to a configured ARP instance will result in errors.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure.
|
||||
|
||||
@retval EFI_SUCCESS The new station address was successfully
|
||||
registered.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. SwAddressLength is zero when
|
||||
ConfigData is not NULL. StationAddress is NULL
|
||||
when ConfigData is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or
|
||||
StationAddress is different from the one that is
|
||||
already registered.
|
||||
@retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be
|
||||
allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpConfigure (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This function is used to insert entries into the ARP cache.
|
||||
|
||||
ARP cache entries are typically inserted and updated by network protocol drivers
|
||||
as network traffic is processed. Most ARP cache entries will time out and be
|
||||
deleted if the network traffic stops. ARP cache entries that were inserted
|
||||
by the Add() function may be static (will not time out) or dynamic (will time out).
|
||||
Default ARP cache timeout values are not covered in most network protocol
|
||||
specifications (although RFC 1122 comes pretty close) and will only be
|
||||
discussed in general in this specification. The timeout values that are
|
||||
used in the EFI Sample Implementation should be used only as a guideline.
|
||||
Final product implementations of the EFI network stack should be tuned for
|
||||
their expected network environments.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param DenyFlag Set to TRUE if this entry is a deny entry. Set to
|
||||
FALSE if this entry is a normal entry.
|
||||
@param TargetSwAddress Pointer to a protocol address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TargetHwAddress Pointer to a hardware address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TimeoutValue Time in 100-ns units that this entry will remain
|
||||
in the ARP cache. A value of zero means that the
|
||||
entry is permanent. A nonzero value will override
|
||||
the one given by Configure() if the entry to be
|
||||
added is a dynamic entry.
|
||||
@param Overwrite If TRUE, the matching cache entry will be
|
||||
overwritten with the supplied parameters. If
|
||||
FALSE, EFI_ACCESS_DENIED is returned if the
|
||||
corresponding cache entry already exists.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been added or updated.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. DenyFlag is FALSE and
|
||||
TargetHwAddress is NULL. DenyFlag is FALSE and
|
||||
TargetSwAddress is NULL. TargetHwAddress is NULL
|
||||
and TargetSwAddress is NULL. Both TargetSwAddress
|
||||
and TargetHwAddress are not NULL when DenyFlag is
|
||||
TRUE.
|
||||
@retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated.
|
||||
@retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite
|
||||
is not true.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpAdd (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN DenyFlag,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN VOID *TargetHwAddress OPTIONAL,
|
||||
IN UINT32 TimeoutValue,
|
||||
IN BOOLEAN Overwrite
|
||||
);
|
||||
|
||||
/**
|
||||
This function searches the ARP cache for matching entries and allocates a buffer into
|
||||
which those entries are copied.
|
||||
|
||||
The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which
|
||||
are protocol address pairs and hardware address pairs.
|
||||
When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer
|
||||
is not NULL), the ARP cache timeout for the found entry is reset if Refresh is
|
||||
set to TRUE. If the found ARP cache entry is a permanent entry, it is not
|
||||
affected by Refresh.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to look for matching software protocol
|
||||
addresses. Set to FALSE to look for matching
|
||||
hardware protocol addresses.
|
||||
@param AddressBuffer Pointer to address buffer. Set to NULL to match
|
||||
all addresses.
|
||||
@param EntryLength The size of an entry in the entries buffer.
|
||||
@param EntryCount The number of ARP cache entries that are found by
|
||||
the specified criteria.
|
||||
@param Entries Pointer to the buffer that will receive the ARP
|
||||
cache entries.
|
||||
@param Refresh Set to TRUE to refresh the timeout value of the
|
||||
matching ARP cache entry.
|
||||
|
||||
@retval EFI_SUCCESS The requested ARP cache entries were copied into
|
||||
the buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. Both EntryCount and EntryLength are
|
||||
NULL, when Refresh is FALSE.
|
||||
@retval EFI_NOT_FOUND No matching entries were found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFind (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL,
|
||||
OUT UINT32 *EntryLength OPTIONAL,
|
||||
OUT UINT32 *EntryCount OPTIONAL,
|
||||
OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
|
||||
IN BOOLEAN Refresh
|
||||
);
|
||||
|
||||
/**
|
||||
This function removes specified ARP cache entries.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to delete matching protocol addresses.
|
||||
Set to FALSE to delete matching hardware
|
||||
addresses.
|
||||
@param AddressBuffer Pointer to the address buffer that is used as a
|
||||
key to look for the cache entry. Set to NULL to
|
||||
delete all entries.
|
||||
|
||||
@retval EFI_SUCCESS The entry was removed from the ARP cache.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND The specified deletion key was not found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDelete (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
This function delete all dynamic entries from the ARP cache that match the specified
|
||||
software protocol type.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS The cache has been flushed.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND There are no matching dynamic cache entries.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFlush (
|
||||
IN EFI_ARP_PROTOCOL *This
|
||||
);
|
||||
|
||||
/**
|
||||
This function tries to resolve the TargetSwAddress and optionally returns a
|
||||
TargetHwAddress if it already exists in the ARP cache.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address to resolve.
|
||||
@param ResolvedEvent Pointer to the event that will be signaled when
|
||||
the address is resolved or some error occurs.
|
||||
@param TargetHwAddress Pointer to the buffer for the resolved hardware
|
||||
address in network byte order.
|
||||
|
||||
@retval EFI_SUCCESS The data is copied from the ARP cache into the
|
||||
TargetHwAddress buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetHwAddress is NULL.
|
||||
@retval EFI_ACCESS_DENIED The requested address is not present in the normal
|
||||
ARP cache but is present in the deny address list.
|
||||
Outgoing traffic to that address is forbidden.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_READY The request has been started and is not finished.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpRequest (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL,
|
||||
OUT VOID *TargetHwAddress
|
||||
);
|
||||
|
||||
/**
|
||||
This function aborts the previous ARP request (identified by This, TargetSwAddress
|
||||
and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
If the request is in the internal ARP request queue, the request is aborted
|
||||
immediately and its ResolvedEvent is signaled. Only an asynchronous address
|
||||
request needs to be canceled. If TargeSwAddress and ResolveEvent are both
|
||||
NULL, all the pending asynchronous requests that have been issued by This
|
||||
instance will be cancelled and their corresponding events will be signaled.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address in previous
|
||||
request session.
|
||||
@param ResolvedEvent Pointer to the event that is used as the
|
||||
notification event in previous request session.
|
||||
|
||||
@retval EFI_SUCCESS The pending request session(s) is/are aborted and
|
||||
corresponding event(s) is/are signaled.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetSwAddress is not NULL and
|
||||
ResolvedEvent is NULL. TargetSwAddress is NULL and
|
||||
ResolvedEvent is not NULL.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_FOUND The request is not issued by
|
||||
EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpCancel (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Configure the instance using the ConfigData. ConfigData is already validated.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data to be
|
||||
configured.
|
||||
@param[in] ConfigData Pointer to the configuration data used to
|
||||
configure the instance.
|
||||
|
||||
@retval EFI_SUCCESS The instance is configured with the ConfigData.
|
||||
@retval EFI_ACCESS_DENIED The instance is already configured and the
|
||||
ConfigData tries to reset some unchangeable
|
||||
fields.
|
||||
@retval EFI_INVALID_PARAMETER The ConfigData provides a non-unicast IPv4 address
|
||||
when the SwAddressType is IPv4.
|
||||
@retval EFI_OUT_OF_RESOURCES The instance fails to configure due to memory
|
||||
limitation.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ArpConfigureInstance (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Find the CacheEntry, using ProtocolAddress or HardwareAddress or both, as the keyword,
|
||||
in the DeniedCacheTable.
|
||||
|
||||
@param[in] ArpService Pointer to the arp service context data.
|
||||
@param[in] ProtocolAddress Pointer to the protocol address.
|
||||
@param[in] HardwareAddress Pointer to the hardware address.
|
||||
|
||||
@return Pointer to the matched cache entry, if NULL no match is found.
|
||||
|
||||
**/
|
||||
ARP_CACHE_ENTRY *
|
||||
ArpFindDeniedCacheEntry (
|
||||
IN ARP_SERVICE_DATA *ArpService,
|
||||
IN NET_ARP_ADDRESS *ProtocolAddress OPTIONAL,
|
||||
IN NET_ARP_ADDRESS *HardwareAddress OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Find the CacheEntry which matches the requirements in the specified CacheTable.
|
||||
|
||||
@param[in] CacheTable Pointer to the arp cache table.
|
||||
@param[in] StartEntry Pointer to the start entry this search begins with
|
||||
in the cache table.
|
||||
@param[in] FindOpType The search type.
|
||||
@param[in] ProtocolAddress Pointer to the protocol address to match.
|
||||
@param[in] HardwareAddress Pointer to the hardware address to match.
|
||||
|
||||
@return Pointer to the matched arp cache entry, if NULL, no match is found.
|
||||
|
||||
**/
|
||||
ARP_CACHE_ENTRY *
|
||||
ArpFindNextCacheEntryInTable (
|
||||
IN LIST_ENTRY *CacheTable,
|
||||
IN LIST_ENTRY *StartEntry,
|
||||
IN FIND_OPTYPE FindOpType,
|
||||
IN NET_ARP_ADDRESS *ProtocolAddress OPTIONAL,
|
||||
IN NET_ARP_ADDRESS *HardwareAddress OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Allocate a cache entry and initialize it.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
|
||||
@return Pointer to the new created cache entry.
|
||||
|
||||
**/
|
||||
ARP_CACHE_ENTRY *
|
||||
ArpAllocCacheEntry (
|
||||
IN ARP_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Fill the addresses in the CacheEntry using the information passed in by
|
||||
HwAddr and SwAddr.
|
||||
|
||||
@param[in] CacheEntry Pointer to the cache entry.
|
||||
@param[in] HwAddr Pointer to the software address.
|
||||
@param[in] SwAddr Pointer to the hardware address.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpFillAddressInCacheEntry (
|
||||
IN ARP_CACHE_ENTRY *CacheEntry,
|
||||
IN NET_ARP_ADDRESS *HwAddr OPTIONAL,
|
||||
IN NET_ARP_ADDRESS *SwAddr OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Turn the CacheEntry into the resolved status.
|
||||
|
||||
@param[in] CacheEntry Pointer to the resolved cache entry.
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] UserEvent Pointer to the UserEvent to notify.
|
||||
|
||||
@return The count of notifications sent to the instance.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
ArpAddressResolved (
|
||||
IN ARP_CACHE_ENTRY *CacheEntry,
|
||||
IN ARP_INSTANCE_DATA *Instance OPTIONAL,
|
||||
IN EFI_EVENT UserEvent OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Delete cache entries in all the cache tables.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] BySwAddress Delete the cache entry by software address or by
|
||||
hardware address.
|
||||
@param[in] AddressBuffer Pointer to the buffer containing the address to
|
||||
match for the deletion.
|
||||
@param[in] Force This deletion is forced or not.
|
||||
|
||||
@return The count of the deleted cache entries.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
ArpDeleteCacheEntry (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN UINT8 *AddressBuffer OPTIONAL,
|
||||
IN BOOLEAN Force
|
||||
);
|
||||
|
||||
/**
|
||||
Send out an arp frame using the CachEntry and the ArpOpCode.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] CacheEntry Pointer to the configuration data used to
|
||||
configure the instance.
|
||||
@param[in] ArpOpCode The opcode used to send out this Arp frame, either
|
||||
request or reply.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpSendFrame (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN ARP_CACHE_ENTRY *CacheEntry,
|
||||
IN UINT16 ArpOpCode
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize the instance context data.
|
||||
|
||||
@param[in] ArpService Pointer to the arp service context data this
|
||||
instance belongs to.
|
||||
@param[out] Instance Pointer to the instance context data.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ArpInitInstance (
|
||||
IN ARP_SERVICE_DATA *ArpService,
|
||||
OUT ARP_INSTANCE_DATA *Instance
|
||||
);
|
||||
|
||||
/**
|
||||
Process the Arp packets received from Mnp, the procedure conforms to RFC826.
|
||||
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameRcvdDpc (
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Queue ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK.
|
||||
|
||||
@param[in] Event The Event this notify function registered to.
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameRcvd (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Process the already sent arp packets.
|
||||
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameSentDpc (
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK.
|
||||
|
||||
@param[in] Event The Event this notify function registered to.
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpOnFrameSent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Process the arp cache olding and drive the retrying arp requests.
|
||||
|
||||
@param[in] Event The Event this notify function registered to.
|
||||
@param[in] Context Pointer to the context data registerd to the
|
||||
Event.
|
||||
|
||||
@return None.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ArpTimerHandler (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Cancel the arp request.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] TargetSwAddress Pointer to the buffer containing the target
|
||||
software address to match the arp request.
|
||||
@param[in] UserEvent The user event used to notify this request
|
||||
cancellation.
|
||||
|
||||
@return The count of the cancelled requests.
|
||||
|
||||
**/
|
||||
UINTN
|
||||
ArpCancelRequest (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT UserEvent OPTIONAL
|
||||
);
|
||||
|
||||
/**
|
||||
Find the cache entry in the cache table.
|
||||
|
||||
@param[in] Instance Pointer to the instance context data.
|
||||
@param[in] BySwAddress Set to TRUE to look for matching software protocol
|
||||
addresses. Set to FALSE to look for matching
|
||||
hardware protocol addresses.
|
||||
@param[in] AddressBuffer Pointer to address buffer. Set to NULL to match
|
||||
all addresses.
|
||||
@param[out] EntryLength The size of an entry in the entries buffer.
|
||||
@param[out] EntryCount The number of ARP cache entries that are found by
|
||||
the specified criteria.
|
||||
@param[out] Entries Pointer to the buffer that will receive the ARP
|
||||
cache entries.
|
||||
@param[in] Refresh Set to TRUE to refresh the timeout value of the
|
||||
matching ARP cache entry.
|
||||
|
||||
@retval EFI_SUCCESS The requested ARP cache entries are copied into
|
||||
the buffer.
|
||||
@retval EFI_NOT_FOUND No matching entries found.
|
||||
@retval EFI_OUT_OF_RESOURCE There is a memory allocation failure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ArpFindCacheEntry (
|
||||
IN ARP_INSTANCE_DATA *Instance,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL,
|
||||
OUT UINT32 *EntryLength OPTIONAL,
|
||||
OUT UINT32 *EntryCount OPTIONAL,
|
||||
OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
|
||||
IN BOOLEAN Refresh
|
||||
);
|
||||
|
||||
#endif
|
739
NetworkPkg/ArpDxe/ArpMain.c
Normal file
739
NetworkPkg/ArpDxe/ArpMain.c
Normal file
@@ -0,0 +1,739 @@
|
||||
/** @file
|
||||
Implementation of EFI Address Resolution Protocol (ARP) Protocol interface functions.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "ArpImpl.h"
|
||||
|
||||
|
||||
/**
|
||||
This function is used to assign a station address to the ARP cache for this instance
|
||||
of the ARP driver.
|
||||
|
||||
Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will
|
||||
respond to ARP requests that match this registered station address. A call to
|
||||
this function with the ConfigData field set to NULL will reset this ARP instance.
|
||||
|
||||
Once a protocol type and station address have been assigned to this ARP instance,
|
||||
all the following ARP functions will use this information. Attempting to change
|
||||
the protocol type or station address to a configured ARP instance will result in errors.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure.
|
||||
|
||||
@retval EFI_SUCCESS The new station address was successfully
|
||||
registered.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. SwAddressLength is zero when
|
||||
ConfigData is not NULL. StationAddress is NULL
|
||||
when ConfigData is not NULL.
|
||||
@retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or
|
||||
StationAddress is different from the one that is
|
||||
already registered.
|
||||
@retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be
|
||||
allocated.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpConfigure (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((ConfigData != NULL) &&
|
||||
((ConfigData->SwAddressLength == 0) ||
|
||||
(ConfigData->StationAddress == NULL) ||
|
||||
(ConfigData->SwAddressType <= 1500))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Configure this instance, the ConfigData has already passed the basic checks.
|
||||
//
|
||||
Status = ArpConfigureInstance (Instance, ConfigData);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function is used to insert entries into the ARP cache.
|
||||
|
||||
ARP cache entries are typically inserted and updated by network protocol drivers
|
||||
as network traffic is processed. Most ARP cache entries will time out and be
|
||||
deleted if the network traffic stops. ARP cache entries that were inserted
|
||||
by the Add() function may be static (will not time out) or dynamic (will time out).
|
||||
Default ARP cache timeout values are not covered in most network protocol
|
||||
specifications (although RFC 1122 comes pretty close) and will only be
|
||||
discussed in general in this specification. The timeout values that are
|
||||
used in the EFI Sample Implementation should be used only as a guideline.
|
||||
Final product implementations of the EFI network stack should be tuned for
|
||||
their expected network environments.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param DenyFlag Set to TRUE if this entry is a deny entry. Set to
|
||||
FALSE if this entry is a normal entry.
|
||||
@param TargetSwAddress Pointer to a protocol address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TargetHwAddress Pointer to a hardware address to add (or deny).
|
||||
May be set to NULL if DenyFlag is TRUE.
|
||||
@param TimeoutValue Time in 100-ns units that this entry will remain
|
||||
in the ARP cache. A value of zero means that the
|
||||
entry is permanent. A nonzero value will override
|
||||
the one given by Configure() if the entry to be
|
||||
added is a dynamic entry.
|
||||
@param Overwrite If TRUE, the matching cache entry will be
|
||||
overwritten with the supplied parameters. If
|
||||
FALSE, EFI_ACCESS_DENIED is returned if the
|
||||
corresponding cache entry already exists.
|
||||
|
||||
@retval EFI_SUCCESS The entry has been added or updated.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. DenyFlag is FALSE and
|
||||
TargetHwAddress is NULL. DenyFlag is FALSE and
|
||||
TargetSwAddress is NULL. TargetHwAddress is NULL
|
||||
and TargetSwAddress is NULL. Both TargetSwAddress
|
||||
and TargetHwAddress are not NULL when DenyFlag is
|
||||
TRUE.
|
||||
@retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated.
|
||||
@retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite
|
||||
is not true.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpAdd (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN DenyFlag,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN VOID *TargetHwAddress OPTIONAL,
|
||||
IN UINT32 TimeoutValue,
|
||||
IN BOOLEAN Overwrite
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
ARP_CACHE_ENTRY *CacheEntry;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpMode;
|
||||
NET_ARP_ADDRESS MatchAddress[2];
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (((!DenyFlag) && ((TargetHwAddress == NULL) || (TargetSwAddress == NULL))) ||
|
||||
(DenyFlag && (TargetHwAddress != NULL) && (TargetSwAddress != NULL)) ||
|
||||
((TargetHwAddress == NULL) && (TargetSwAddress == NULL))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
ArpService = Instance->ArpService;
|
||||
SnpMode = &Instance->ArpService->SnpMode;
|
||||
|
||||
//
|
||||
// Fill the hardware address part in the MatchAddress.
|
||||
//
|
||||
MatchAddress[Hardware].Type = SnpMode->IfType;
|
||||
MatchAddress[Hardware].Length = (UINT8) SnpMode->HwAddressSize;
|
||||
MatchAddress[Hardware].AddressPtr = TargetHwAddress;
|
||||
|
||||
//
|
||||
// Fill the software address part in the MatchAddress.
|
||||
//
|
||||
MatchAddress[Protocol].Type = Instance->ConfigData.SwAddressType;
|
||||
MatchAddress[Protocol].Length = Instance->ConfigData.SwAddressLength;
|
||||
MatchAddress[Protocol].AddressPtr = TargetSwAddress;
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// See whether the entry to add exists. Check the DeinedCacheTable first.
|
||||
//
|
||||
CacheEntry = ArpFindDeniedCacheEntry (
|
||||
ArpService,
|
||||
&MatchAddress[Protocol],
|
||||
&MatchAddress[Hardware]
|
||||
);
|
||||
|
||||
if (CacheEntry == NULL) {
|
||||
//
|
||||
// Check the ResolvedCacheTable
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->ResolvedCacheTable,
|
||||
NULL,
|
||||
ByBoth,
|
||||
&MatchAddress[Protocol],
|
||||
&MatchAddress[Hardware]
|
||||
);
|
||||
}
|
||||
|
||||
if ((CacheEntry != NULL) && !Overwrite) {
|
||||
//
|
||||
// The entry to add exists, if not Overwirte, deny this add request.
|
||||
//
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
if ((CacheEntry == NULL) && (TargetSwAddress != NULL)) {
|
||||
//
|
||||
// Check whether there are pending requests matching the entry to be added.
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->PendingRequestTable,
|
||||
NULL,
|
||||
ByProtoAddress,
|
||||
&MatchAddress[Protocol],
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
if (CacheEntry != NULL) {
|
||||
//
|
||||
// Remove it from the Table.
|
||||
//
|
||||
RemoveEntryList (&CacheEntry->List);
|
||||
} else {
|
||||
//
|
||||
// It's a new entry, allocate memory for the entry.
|
||||
//
|
||||
CacheEntry = ArpAllocCacheEntry (Instance);
|
||||
|
||||
if (CacheEntry == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpAdd: Failed to allocate pool for CacheEntry.\n"));
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Overwrite these parameters.
|
||||
//
|
||||
CacheEntry->DefaultDecayTime = TimeoutValue;
|
||||
CacheEntry->DecayTime = TimeoutValue;
|
||||
|
||||
//
|
||||
// Fill in the addresses.
|
||||
//
|
||||
ArpFillAddressInCacheEntry (
|
||||
CacheEntry,
|
||||
&MatchAddress[Hardware],
|
||||
&MatchAddress[Protocol]
|
||||
);
|
||||
|
||||
//
|
||||
// Inform the user if there is any.
|
||||
//
|
||||
ArpAddressResolved (CacheEntry, NULL, NULL);
|
||||
|
||||
//
|
||||
// Add this CacheEntry to the corresponding CacheTable.
|
||||
//
|
||||
if (DenyFlag) {
|
||||
InsertHeadList (&ArpService->DeniedCacheTable, &CacheEntry->List);
|
||||
} else {
|
||||
InsertHeadList (&ArpService->ResolvedCacheTable, &CacheEntry->List);
|
||||
}
|
||||
|
||||
UNLOCK_EXIT:
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function searches the ARP cache for matching entries and allocates a buffer into
|
||||
which those entries are copied.
|
||||
|
||||
The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which
|
||||
are protocol address pairs and hardware address pairs.
|
||||
When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer
|
||||
is not NULL), the ARP cache timeout for the found entry is reset if Refresh is
|
||||
set to TRUE. If the found ARP cache entry is a permanent entry, it is not
|
||||
affected by Refresh.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to look for matching software protocol
|
||||
addresses. Set to FALSE to look for matching
|
||||
hardware protocol addresses.
|
||||
@param AddressBuffer Pointer to address buffer. Set to NULL to match
|
||||
all addresses.
|
||||
@param EntryLength The size of an entry in the entries buffer.
|
||||
@param EntryCount The number of ARP cache entries that are found by
|
||||
the specified criteria.
|
||||
@param Entries Pointer to the buffer that will receive the ARP
|
||||
cache entries.
|
||||
@param Refresh Set to TRUE to refresh the timeout value of the
|
||||
matching ARP cache entry.
|
||||
|
||||
@retval EFI_SUCCESS The requested ARP cache entries were copied into
|
||||
the buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. Both EntryCount and EntryLength are
|
||||
NULL, when Refresh is FALSE.
|
||||
@retval EFI_NOT_FOUND No matching entries were found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFind (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL,
|
||||
OUT UINT32 *EntryLength OPTIONAL,
|
||||
OUT UINT32 *EntryCount OPTIONAL,
|
||||
OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
|
||||
IN BOOLEAN Refresh
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) ||
|
||||
(!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) ||
|
||||
((Entries != NULL) && ((EntryLength == NULL) || (EntryCount == NULL)))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// All the check passed, find the cache entries now.
|
||||
//
|
||||
Status = ArpFindCacheEntry (
|
||||
Instance,
|
||||
BySwAddress,
|
||||
AddressBuffer,
|
||||
EntryLength,
|
||||
EntryCount,
|
||||
Entries,
|
||||
Refresh
|
||||
);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function removes specified ARP cache entries.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param BySwAddress Set to TRUE to delete matching protocol addresses.
|
||||
Set to FALSE to delete matching hardware
|
||||
addresses.
|
||||
@param AddressBuffer Pointer to the address buffer that is used as a
|
||||
key to look for the cache entry. Set to NULL to
|
||||
delete all entries.
|
||||
|
||||
@retval EFI_SUCCESS The entry was removed from the ARP cache.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND The specified deletion key was not found.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpDelete (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN BOOLEAN BySwAddress,
|
||||
IN VOID *AddressBuffer OPTIONAL
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
UINTN Count;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Delete the specified cache entries.
|
||||
//
|
||||
Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function delete all dynamic entries from the ARP cache that match the specified
|
||||
software protocol type.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS The cache has been flushed.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval EFI_NOT_FOUND There are no matching dynamic cache entries.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpFlush (
|
||||
IN EFI_ARP_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
UINTN Count;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if (This == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Delete the dynamic entries from the cache table.
|
||||
//
|
||||
Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE);
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function tries to resolve the TargetSwAddress and optionally returns a
|
||||
TargetHwAddress if it already exists in the ARP cache.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address to resolve.
|
||||
@param ResolvedEvent Pointer to the event that will be signaled when
|
||||
the address is resolved or some error occurs.
|
||||
@param TargetHwAddress Pointer to the buffer for the resolved hardware
|
||||
address in network byte order.
|
||||
|
||||
@retval EFI_SUCCESS The data is copied from the ARP cache into the
|
||||
TargetHwAddress buffer.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetHwAddress is NULL.
|
||||
@retval EFI_ACCESS_DENIED The requested address is not present in the normal
|
||||
ARP cache but is present in the deny address list.
|
||||
Outgoing traffic to that address is forbidden.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_READY The request has been started and is not finished.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpRequest (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL,
|
||||
OUT VOID *TargetHwAddress
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
ARP_SERVICE_DATA *ArpService;
|
||||
EFI_SIMPLE_NETWORK_MODE *SnpMode;
|
||||
ARP_CACHE_ENTRY *CacheEntry;
|
||||
NET_ARP_ADDRESS HardwareAddress;
|
||||
NET_ARP_ADDRESS ProtocolAddress;
|
||||
USER_REQUEST_CONTEXT *RequestContext;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) || (TargetHwAddress == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
ArpService = Instance->ArpService;
|
||||
SnpMode = &ArpService->SnpMode;
|
||||
|
||||
if ((TargetSwAddress == NULL) ||
|
||||
((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
|
||||
IP4_IS_LOCAL_BROADCAST (*((UINT32 *)TargetSwAddress)))) {
|
||||
//
|
||||
// Return the hardware broadcast address.
|
||||
//
|
||||
CopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);
|
||||
|
||||
goto SIGNAL_USER;
|
||||
}
|
||||
|
||||
if ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
|
||||
IP4_IS_MULTICAST (NTOHL (*((UINT32 *)TargetSwAddress)))) {
|
||||
//
|
||||
// If the software address is an IPv4 multicast address, invoke Mnp to
|
||||
// resolve the address.
|
||||
//
|
||||
Status = ArpService->Mnp->McastIpToMac (
|
||||
ArpService->Mnp,
|
||||
FALSE,
|
||||
TargetSwAddress,
|
||||
TargetHwAddress
|
||||
);
|
||||
goto SIGNAL_USER;
|
||||
}
|
||||
|
||||
HardwareAddress.Type = SnpMode->IfType;
|
||||
HardwareAddress.Length = (UINT8)SnpMode->HwAddressSize;
|
||||
HardwareAddress.AddressPtr = NULL;
|
||||
|
||||
ProtocolAddress.Type = Instance->ConfigData.SwAddressType;
|
||||
ProtocolAddress.Length = Instance->ConfigData.SwAddressLength;
|
||||
ProtocolAddress.AddressPtr = TargetSwAddress;
|
||||
|
||||
//
|
||||
// Initialize the TargetHwAddrss to a zero address.
|
||||
//
|
||||
ZeroMem (TargetHwAddress, SnpMode->HwAddressSize);
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Check whether the software address is in the denied table.
|
||||
//
|
||||
CacheEntry = ArpFindDeniedCacheEntry (ArpService, &ProtocolAddress, NULL);
|
||||
if (CacheEntry != NULL) {
|
||||
Status = EFI_ACCESS_DENIED;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether the software address is already resolved.
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->ResolvedCacheTable,
|
||||
NULL,
|
||||
ByProtoAddress,
|
||||
&ProtocolAddress,
|
||||
NULL
|
||||
);
|
||||
if (CacheEntry != NULL) {
|
||||
//
|
||||
// Resolved, copy the address into the user buffer.
|
||||
//
|
||||
CopyMem (
|
||||
TargetHwAddress,
|
||||
CacheEntry->Addresses[Hardware].AddressPtr,
|
||||
CacheEntry->Addresses[Hardware].Length
|
||||
);
|
||||
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
if (ResolvedEvent == NULL) {
|
||||
Status = EFI_NOT_READY;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Create a request context for this arp request.
|
||||
//
|
||||
RequestContext = AllocatePool (sizeof(USER_REQUEST_CONTEXT));
|
||||
if (RequestContext == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for RequestContext failed.\n"));
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
RequestContext->Instance = Instance;
|
||||
RequestContext->UserRequestEvent = ResolvedEvent;
|
||||
RequestContext->UserHwAddrBuffer = TargetHwAddress;
|
||||
InitializeListHead (&RequestContext->List);
|
||||
|
||||
//
|
||||
// Check whether there is a same request.
|
||||
//
|
||||
CacheEntry = ArpFindNextCacheEntryInTable (
|
||||
&ArpService->PendingRequestTable,
|
||||
NULL,
|
||||
ByProtoAddress,
|
||||
&ProtocolAddress,
|
||||
NULL
|
||||
);
|
||||
if (CacheEntry != NULL) {
|
||||
|
||||
CacheEntry->NextRetryTime = Instance->ConfigData.RetryTimeOut;
|
||||
CacheEntry->RetryCount = Instance->ConfigData.RetryCount;
|
||||
} else {
|
||||
//
|
||||
// Allocate a cache entry for this request.
|
||||
//
|
||||
CacheEntry = ArpAllocCacheEntry (Instance);
|
||||
if (CacheEntry == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for CacheEntry failed.\n"));
|
||||
FreePool (RequestContext);
|
||||
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto UNLOCK_EXIT;
|
||||
}
|
||||
|
||||
//
|
||||
// Fill the software address.
|
||||
//
|
||||
ArpFillAddressInCacheEntry (CacheEntry, &HardwareAddress, &ProtocolAddress);
|
||||
|
||||
//
|
||||
// Add this entry into the PendingRequestTable.
|
||||
//
|
||||
InsertTailList (&ArpService->PendingRequestTable, &CacheEntry->List);
|
||||
}
|
||||
|
||||
//
|
||||
// Link this request context into the cache entry.
|
||||
//
|
||||
InsertHeadList (&CacheEntry->UserRequestList, &RequestContext->List);
|
||||
|
||||
//
|
||||
// Send out the ARP Request frame.
|
||||
//
|
||||
ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST);
|
||||
Status = EFI_NOT_READY;
|
||||
|
||||
UNLOCK_EXIT:
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
SIGNAL_USER:
|
||||
|
||||
if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) {
|
||||
gBS->SignalEvent (ResolvedEvent);
|
||||
|
||||
//
|
||||
// Dispatch the DPC queued by the NotifyFunction of ResolvedEvent.
|
||||
//
|
||||
DispatchDpc ();
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This function aborts the previous ARP request (identified by This, TargetSwAddress
|
||||
and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
If the request is in the internal ARP request queue, the request is aborted
|
||||
immediately and its ResolvedEvent is signaled. Only an asynchronous address
|
||||
request needs to be canceled. If TargeSwAddress and ResolveEvent are both
|
||||
NULL, all the pending asynchronous requests that have been issued by This
|
||||
instance will be cancelled and their corresponding events will be signaled.
|
||||
|
||||
@param This Pointer to the EFI_ARP_PROTOCOL instance.
|
||||
@param TargetSwAddress Pointer to the protocol address in previous
|
||||
request session.
|
||||
@param ResolvedEvent Pointer to the event that is used as the
|
||||
notification event in previous request session.
|
||||
|
||||
@retval EFI_SUCCESS The pending request session(s) is/are aborted and
|
||||
corresponding event(s) is/are signaled.
|
||||
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
|
||||
This is NULL. TargetSwAddress is not NULL and
|
||||
ResolvedEvent is NULL. TargetSwAddress is NULL and
|
||||
ResolvedEvent is not NULL.
|
||||
@retval EFI_NOT_STARTED The ARP driver instance has not been configured.
|
||||
@retval EFI_NOT_FOUND The request is not issued by
|
||||
EFI_ARP_PROTOCOL.Request().
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpCancel (
|
||||
IN EFI_ARP_PROTOCOL *This,
|
||||
IN VOID *TargetSwAddress OPTIONAL,
|
||||
IN EFI_EVENT ResolvedEvent OPTIONAL
|
||||
)
|
||||
{
|
||||
ARP_INSTANCE_DATA *Instance;
|
||||
UINTN Count;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
if ((This == NULL) ||
|
||||
((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) ||
|
||||
((TargetSwAddress == NULL) && (ResolvedEvent != NULL))) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
|
||||
|
||||
if (!Instance->Configured) {
|
||||
return EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
|
||||
|
||||
//
|
||||
// Cancel the specified request.
|
||||
//
|
||||
Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent);
|
||||
|
||||
//
|
||||
// Dispatch the DPCs queued by the NotifyFunction of the events signaled
|
||||
// by ArpCancleRequest.
|
||||
//
|
||||
DispatchDpc ();
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
|
||||
}
|
219
NetworkPkg/ArpDxe/ComponentName.c
Normal file
219
NetworkPkg/ArpDxe/ComponentName.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/** @file
|
||||
UEFI Component Name(2) protocol implementation for ArpDxe driver.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "ArpDriver.h"
|
||||
|
||||
|
||||
//
|
||||
// EFI Component Name Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gArpComponentName = {
|
||||
ArpComponentNameGetDriverName,
|
||||
ArpComponentNameGetControllerName,
|
||||
"eng"
|
||||
};
|
||||
|
||||
//
|
||||
// EFI Component Name 2 Protocol
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gArpComponentName2 = {
|
||||
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) ArpComponentNameGetDriverName,
|
||||
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) ArpComponentNameGetControllerName,
|
||||
"en"
|
||||
};
|
||||
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpDriverNameTable[] = {
|
||||
{ "eng;en", L"ARP Network Service Driver" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mArpControllerNameTable[] = {
|
||||
{ "eng;en", L"ARP Controller" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the driver.
|
||||
|
||||
This function retrieves the user readable name of a driver in the form of a
|
||||
Unicode string. If the driver specified by This has a user readable name in
|
||||
the language specified by Language, then a pointer to the driver name is
|
||||
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||
by This does not support the language specified by Language,
|
||||
then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name 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. Language is specified
|
||||
in RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] 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.
|
||||
|
||||
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||
This and the language specified by Language was
|
||||
returned in DriverName.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetDriverName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **DriverName
|
||||
)
|
||||
{
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mArpDriverNameTable,
|
||||
DriverName,
|
||||
(BOOLEAN)(This == &gArpComponentName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves a Unicode string that is the user readable name of the controller
|
||||
that is being managed by a driver.
|
||||
|
||||
This function retrieves the user readable name of the controller specified by
|
||||
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||
driver specified by This has a user readable name in the language specified by
|
||||
Language, then a pointer to the controller name is returned in ControllerName,
|
||||
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||
managing the controller specified by ControllerHandle and ChildHandle,
|
||||
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||
|
||||
@param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||
|
||||
@param[in] 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.
|
||||
|
||||
@param[in] 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.
|
||||
|
||||
@param[in] Language A pointer to a Null-terminated ASCII string
|
||||
array indicating the language. This is the
|
||||
language of the driver name 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. Language is specified in
|
||||
RFC 4646 or ISO 639-2 language code format.
|
||||
|
||||
@param[out] 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.
|
||||
|
||||
@retval 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.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||
EFI_HANDLE.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||
|
||||
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||
managing the controller specified by
|
||||
ControllerHandle and ChildHandle.
|
||||
|
||||
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||
the language specified by Language.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ArpComponentNameGetControllerName (
|
||||
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
||||
IN EFI_HANDLE ControllerHandle,
|
||||
IN EFI_HANDLE ChildHandle OPTIONAL,
|
||||
IN CHAR8 *Language,
|
||||
OUT CHAR16 **ControllerName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_ARP_PROTOCOL *Arp;
|
||||
|
||||
//
|
||||
// Only provide names for child handles.
|
||||
//
|
||||
if (ChildHandle == NULL) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Make sure this driver produced ChildHandle
|
||||
//
|
||||
Status = EfiTestChildHandle (
|
||||
ControllerHandle,
|
||||
ChildHandle,
|
||||
&gEfiManagedNetworkProtocolGuid
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve an instance of a produced protocol from ChildHandle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
ChildHandle,
|
||||
&gEfiArpProtocolGuid,
|
||||
(VOID **)&Arp,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
return LookupUnicodeString2 (
|
||||
Language,
|
||||
This->SupportedLanguages,
|
||||
mArpControllerNameTable,
|
||||
ControllerName,
|
||||
(BOOLEAN)(This == &gArpComponentName)
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user