arpmain.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 757 行 · 第 1/2 页
C
757 行
EFI_SUCCESS - The entry was removed from the ARP cache.
EFI_INVALID_PARAMETER - This is NULL.
EFI_NOT_FOUND - The specified deletion key was not found.
EFI_NOT_STARTED - The ARP driver instance has not been configured.
--*/
{
ARP_INSTANCE_DATA *Instance;
ARP_SERVICE_DATA *ArpService;
UINTN Count;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
if (!Instance->Configured) {
return EFI_NOT_STARTED;
}
ArpService = Instance->ArpService;
if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
return EFI_ACCESS_DENIED;
}
//
// Delete the specified cache entries.
//
Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE);
NET_UNLOCK (&ArpService->Lock);
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ArpFlush (
IN EFI_ARP_PROTOCOL *This
)
/*++
Routine Description:
This function delete all dynamic entries from the ARP cache that match the specified
software protocol type.
Arguments:
This - Pointer to the EFI_ARP_PROTOCOL instance.
Returns:
EFI_SUCCESS - The cache has been flushed.
EFI_INVALID_PARAMETER - This is NULL.
EFI_NOT_FOUND - There are no matching dynamic cache entries.
EFI_NOT_STARTED - The ARP driver instance has not been configured.
--*/
{
ARP_INSTANCE_DATA *Instance;
ARP_SERVICE_DATA *ArpService;
UINTN Count;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
if (!Instance->Configured) {
return EFI_NOT_STARTED;
}
ArpService = Instance->ArpService;
if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
return EFI_ACCESS_DENIED;
}
//
// Delete the dynamic entries from the cache table.
//
Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE);
NET_UNLOCK (&ArpService->Lock);
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ArpRequest (
IN EFI_ARP_PROTOCOL *This,
IN VOID *TargetSwAddress OPTIONAL,
IN EFI_EVENT ResolvedEvent OPTIONAL,
OUT VOID *TargetHwAddress
)
/*++
Routine Description:
This function tries to resolve the TargetSwAddress and optionally returns a
TargetHwAddress if it already exists in the ARP cache.
Arguments:
This - Pointer to the EFI_ARP_PROTOCOL instance.
TargetSwAddress - Pointer to the protocol address to resolve.
ResolvedEvent - Pointer to the event that will be signaled when the address is
resolved or some error occurs.
TargetHwAddress - Pointer to the buffer for the resolved hardware address in
network byte order.
Returns:
EFI_SUCCESS - The data is copied from the ARP cache into the TargetHwAddress
buffer.
EFI_INVALID_PARAMETER - One or more of the following conditions is TRUE:
This is NULL.
TargetHwAddress is NULL.
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.
EFI_NOT_STARTED - The ARP driver instance has not been configured.
EFI_NOT_READY - The request has been started and is not finished.
--*/
{
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;
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.
//
NetCopyMem (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.
//
NetZeroMem (TargetHwAddress, SnpMode->HwAddressSize);
if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
return EFI_ACCESS_DENIED;
}
//
// 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.
//
NetCopyMem (
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 = NetAllocatePool (sizeof(USER_REQUEST_CONTEXT));
if (RequestContext == NULL) {
ARP_DEBUG_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;
NetListInit (&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) {
ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for CacheEntry failed.\n"));
NetFreePool (RequestContext);
Status = EFI_OUT_OF_RESOURCES;
goto UNLOCK_EXIT;
}
//
// Fill the software address.
//
ArpFillAddressInCacheEntry (CacheEntry, &HardwareAddress, &ProtocolAddress);
//
// Add this entry into the PendingRequestTable.
//
NetListInsertTail (&ArpService->PendingRequestTable, &CacheEntry->List);
}
//
// Link this request context into the cache entry.
//
NetListInsertHead (&CacheEntry->UserRequestList, &RequestContext->List);
//
// Send out the ARP Request frame.
//
ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST);
Status = EFI_NOT_READY;
UNLOCK_EXIT:
NET_UNLOCK (&ArpService->Lock);
SIGNAL_USER:
if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) {
gBS->SignalEvent (ResolvedEvent);
}
return Status;
}
EFI_STATUS
EFIAPI
ArpCancel (
IN EFI_ARP_PROTOCOL *This,
IN VOID *TargetSwAddress OPTIONAL,
IN EFI_EVENT ResolvedEvent OPTIONAL
)
/*++
Routine Description:
This function aborts the previous ARP request (identified by This, TargetSwAddress
and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
Arguments:
This - Pointer to the EFI_ARP_PROTOCOL instance.
TargetSwAddress - Pointer to the protocol address in previous request session.
ResolvedEvent - Pointer to the event that is used as the notification event in
previous request session.
Returns:
EFI_SUCCESS - The pending request session(s) is/are aborted and corresponding
event(s) is/are signaled.
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.
EFI_NOT_STARTED - The ARP driver instance has not been configured.
EFI_NOT_FOUND - The request is not issued by EFI_ARP_PROTOCOL.Request().
--*/
{
ARP_INSTANCE_DATA *Instance;
ARP_SERVICE_DATA *ArpService;
UINTN Count;
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;
}
ArpService = Instance->ArpService;
if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {
return EFI_ACCESS_DENIED;
}
//
// Cancel the specified request.
//
Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent);
NET_UNLOCK (&ArpService->Lock);
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?