ip4if.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,274 行 · 第 1/3 页
C
1,274 行
/*++
Copyright (c) 2005 - 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Ip4If.c
Abstract:
Implement IP4 pesudo interface.
--*/
#include "Ip4Impl.h"
//
// Mac address with all zero, used to determine whethter the ARP
// resolve succeeded. Failed ARP requests zero the MAC address buffer.
//
STATIC EFI_MAC_ADDRESS mZeroMacAddress;
STATIC
VOID
EFIAPI
Ip4OnFrameSent (
IN EFI_EVENT Event,
IN VOID *Context
);
STATIC
VOID
EFIAPI
Ip4OnArpResolved (
IN EFI_EVENT Event,
IN VOID *Context
);
STATIC
VOID
EFIAPI
Ip4OnFrameReceived (
IN EFI_EVENT Event,
IN VOID *Context
);
STATIC
VOID
Ip4CancelFrameArp (
IN IP4_ARP_QUE *ArpQue,
IN EFI_STATUS IoStatus,
IN IP4_FRAME_TO_CANCEL FrameToCancel, OPTIONAL
IN VOID *Context
);
STATIC
IP4_LINK_TX_TOKEN *
Ip4WrapLinkTxToken (
IN IP4_INTERFACE *Interface,
IN IP4_PROTOCOL *IpInstance, OPTIONAL
IN NET_BUF *Packet,
IN IP4_FRAME_CALLBACK CallBack,
IN VOID *Context
)
/*++
Routine Description:
Wrap a transmit request into a newly allocated IP4_LINK_TX_TOKEN.
Arguments:
Interface - The interface to send out from
IpInstance - The IpInstance that transmit the packet.
NULL if the packet is sent by the IP4 driver itself.
Packet - The packet to transmit
CallBack - Call back function to execute if transmission finished.
Context - Opaque parameter to the call back.
Returns:
The wrapped token if succeed or NULL
--*/
{
EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken;
EFI_MANAGED_NETWORK_TRANSMIT_DATA *MnpTxData;
IP4_LINK_TX_TOKEN *Token;
EFI_STATUS Status;
UINT32 Count;
Token = NetAllocatePool (sizeof (IP4_LINK_TX_TOKEN) + \
(Packet->BlockOpNum - 1) * sizeof (EFI_MANAGED_NETWORK_FRAGMENT_DATA));
if (Token == NULL) {
return NULL;
}
Token->Signature = IP4_FRAME_TX_SIGNATURE;
NetListInit (&Token->Link);
Token->Interface = Interface;
Token->IpInstance = IpInstance;
Token->CallBack = CallBack;
Token->Packet = Packet;
Token->Context = Context;
Token->DstMac = mZeroMacAddress;
Token->SrcMac = Interface->Mac;
MnpToken = &(Token->MnpToken);
MnpToken->Status = EFI_NOT_READY;
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
Ip4OnFrameSent,
Token,
&MnpToken->Event
);
if (EFI_ERROR (Status)) {
NetFreePool (Token);
return NULL;
}
MnpTxData = &Token->MnpTxData;
MnpToken->Packet.TxData = MnpTxData;
MnpTxData->DestinationAddress = &Token->DstMac;
MnpTxData->SourceAddress = &Token->SrcMac;
MnpTxData->ProtocolType = IP4_ETHER_PROTO;
MnpTxData->DataLength = Packet->TotalSize;
MnpTxData->HeaderLength = 0;
Count = Packet->BlockOpNum;
NetbufBuildExt (Packet, (NET_FRAGMENT *) MnpTxData->FragmentTable, &Count);
MnpTxData->FragmentCount = (UINT16)Count;
return Token;
}
STATIC
VOID
Ip4FreeLinkTxToken (
IN IP4_LINK_TX_TOKEN *Token
)
/*++
Routine Description:
Free the link layer transmit token. It will close the event
then free the memory used.
Arguments:
Token - Token to free
Returns:
NONE
--*/
{
NET_CHECK_SIGNATURE (Token, IP4_FRAME_TX_SIGNATURE);
gBS->CloseEvent (Token->MnpToken.Event);
NetFreePool (Token);
}
STATIC
IP4_ARP_QUE *
Ip4CreateArpQue (
IN IP4_INTERFACE *Interface,
IN IP4_ADDR DestIp
)
/*++
Routine Description:
Create an IP_ARP_QUE structure to request ARP service.
Arguments:
Interface - The interface to send ARP from.
DestIp - The destination IP (host byte order) to request MAC for
Returns:
Point to newly created IP4_ARP_QUE if succeed, otherwise NULL.
--*/
{
IP4_ARP_QUE *ArpQue;
EFI_STATUS Status;
ArpQue = NetAllocatePool (sizeof (IP4_ARP_QUE));
if (ArpQue == NULL) {
return NULL;
}
ArpQue->Signature = IP4_FRAME_ARP_SIGNATURE;
NetListInit (&ArpQue->Link);
NetListInit (&ArpQue->Frames);
ArpQue->Interface = Interface;
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
Ip4OnArpResolved,
ArpQue,
&ArpQue->OnResolved
);
if (EFI_ERROR (Status)) {
NetFreePool (ArpQue);
return NULL;
}
ArpQue->Ip = DestIp;
ArpQue->Mac = mZeroMacAddress;
return ArpQue;
}
STATIC
VOID
Ip4FreeArpQue (
IN IP4_ARP_QUE *ArpQue,
IN EFI_STATUS IoStatus
)
/*++
Routine Description:
Remove all the transmit requests queued on the ARP queue, then free it.
Arguments:
ArpQue - Arp queue to free
IoStatus - The transmit status returned to transmit requests' callback.
Returns:
NONE
--*/
{
NET_CHECK_SIGNATURE (ArpQue, IP4_FRAME_ARP_SIGNATURE);
//
// Remove all the frame waiting the ARP response
//
Ip4CancelFrameArp (ArpQue, IoStatus, NULL, NULL);
gBS->CloseEvent (ArpQue->OnResolved);
NetFreePool (ArpQue);
}
STATIC
IP4_LINK_RX_TOKEN *
Ip4CreateLinkRxToken (
IN IP4_INTERFACE *Interface,
IN IP4_PROTOCOL *IpInstance,
IN IP4_FRAME_CALLBACK CallBack,
IN VOID *Context
)
/*++
Routine Description:
Create a link layer receive token to wrap the receive request
Arguments:
Interface - The interface to receive from
IpInstance - The instance that request the receive (NULL for IP4 driver itself)
CallBack - Call back function to execute when finished.
Context - Opaque parameters to the callback
Returns:
Point to created IP4_LINK_RX_TOKEN if succeed, otherwise NULL.
--*/
{
EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken;
IP4_LINK_RX_TOKEN *Token;
EFI_STATUS Status;
Token = NetAllocatePool (sizeof (IP4_LINK_RX_TOKEN));
if (Token == NULL) {
return NULL;
}
Token->Signature = IP4_FRAME_RX_SIGNATURE;
Token->Interface = Interface;
Token->IpInstance = IpInstance;
Token->CallBack = CallBack;
Token->Context = Context;
MnpToken = &Token->MnpToken;
MnpToken->Status = EFI_NOT_READY;
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
Ip4OnFrameReceived,
Token,
&MnpToken->Event
);
if (EFI_ERROR (Status)) {
NetFreePool (Token);
return NULL;
}
MnpToken->Packet.RxData = NULL;
return Token;
}
STATIC
VOID
Ip4FreeFrameRxToken (
IN IP4_LINK_RX_TOKEN *Token
)
/*++
Routine Description:
Free the link layer request token. It will close the event
then free the memory used.
Arguments:
Token - Request token to free
Returns:
NONE
--*/
{
NET_CHECK_SIGNATURE (Token, IP4_FRAME_RX_SIGNATURE);
gBS->CloseEvent (Token->MnpToken.Event);
NetFreePool (Token);
}
STATIC
VOID
Ip4CancelFrameArp (
IN IP4_ARP_QUE *ArpQue,
IN EFI_STATUS IoStatus,
IN IP4_FRAME_TO_CANCEL FrameToCancel, OPTIONAL
IN VOID *Context
)
/*++
Routine Description:
Remove all the frames on the ARP queue that pass the FrameToCancel,
that is, either FrameToCancel is NULL or it returns true for the frame.
Arguments:
ArpQue - ARP frame to remove the frames from.
IoStatus - The status returned to the cancelled frames' callback function.
FrameToCancel - Function to select which frame to cancel.
Context - Opaque parameter to the FrameToCancel.
Returns:
NONE
--*/
{
NET_LIST_ENTRY *Entry;
NET_LIST_ENTRY *Next;
IP4_LINK_TX_TOKEN *Token;
NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) {
Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link);
if ((FrameToCancel == NULL) || FrameToCancel (Token, Context)) {
NetListRemoveEntry (Entry);
Token->CallBack (Token->IpInstance, Token->Packet, IoStatus, 0, Token->Context);
Ip4FreeLinkTxToken (Token);
}
}
}
VOID
Ip4CancelFrames (
IN IP4_INTERFACE *Interface,
IN EFI_STATUS IoStatus,
IN IP4_FRAME_TO_CANCEL FrameToCancel, OPTIONAL
IN VOID *Context
)
/*++
Routine Description:
Remove all the frames on the interface that pass the FrameToCancel,
either queued on ARP queues or that have already been delivered to
MNP and not yet recycled.
Arguments:
Interface - Interface to remove the frames from
IoStatus - The transmit status returned to the frames' callback
FrameToCancel - Function to select the frame to cancel, NULL to select all
Context - Opaque parameters passed to FrameToCancel
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?