pxe_bc_arp.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 617 行 · 第 1/2 页
C
617 行
return TRUE;
}
}
return FALSE;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
STATIC
EFI_STATUS
SendRequest (
IN PXE_BASECODE_DEVICE *Private,
IN EFI_IP_ADDRESS *ProtocolAddrPtr,
IN EFI_MAC_ADDRESS *HardwareAddrPtr
)
/*++
Routine description:
Transmit ARP request packet
Parameters:
Private := Pointer to PxeBc interface
ProtocolAddrPtr := Pointer IP address to find
HardwareAddrPtr := Pointer to MAC address to find
Returns:
EFI_SUCCESS := ARP request sent
other := ARP request could not be sent
--*/
{
EFI_PXE_BASE_CODE_MODE *PxeBcMode;
EFI_SIMPLE_NETWORK_MODE *SnpMode;
ARP_PACKET *ArpPacket;
EFI_STATUS Status;
UINTN HardwareAddrLength;
UINT8 *SrcProtocolAddrPtr;
UINT8 *DestHardwareAddrptr;
UINT8 *DestProtocolAddrPtr;
//
//
//
PxeBcMode = Private->EfiBc.Mode;
SnpMode = Private->SimpleNetwork->Mode;
HardwareAddrLength = SnpMode->HwAddressSize;
//
// Allocate ARP buffer
//
if (Private->ArpBuffer == NULL) {
Status = gBS->AllocatePool (
EfiBootServicesData,
SnpMode->MediaHeaderSize + sizeof (ARP_PACKET),
&Private->ArpBuffer
);
if (EFI_ERROR (Status)) {
return Status;
}
}
ArpPacket = (VOID *) (Private->ArpBuffer + SnpMode->MediaHeaderSize);
//
// for now, only handle one kind of hw and pr address
//
ArpPacket->ArpHeader = ArpHeader;
ArpPacket->ArpHeader.HwAddLen = (UINT8) HardwareAddrLength;
ArpPacket->ArpHeader.ProtAddLen = (UINT8) Private->IpLength;
//
// rest more generic
//
SrcProtocolAddrPtr = (UINT8 *) (&ArpPacket->SrcHardwareAddr) + HardwareAddrLength;
DestHardwareAddrptr = SrcProtocolAddrPtr + Private->IpLength;
DestProtocolAddrPtr = DestHardwareAddrptr + HardwareAddrLength;
EfiCopyMem (DestProtocolAddrPtr, ProtocolAddrPtr, Private->IpLength);
EfiCopyMem (DestHardwareAddrptr, HardwareAddrPtr, HardwareAddrLength);
EfiCopyMem (SrcProtocolAddrPtr, &PxeBcMode->StationIp, Private->IpLength);
EfiCopyMem (
&ArpPacket->SrcHardwareAddr,
&SnpMode->CurrentAddress,
HardwareAddrLength
);
return SendPacket (
Private,
Private->ArpBuffer,
ArpPacket,
sizeof (ARP_HEADER) + ((Private->IpLength + HardwareAddrLength) << 1),
&SnpMode->BroadcastAddress,
PXE_PROTOCOL_ETHERNET_ARP,
EFI_PXE_BASE_CODE_FUNCTION_ARP
);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
//
// check for address - if not there, send ARP request, wait and check again
// not how it would be done in a full system
//
#define ARP_REQUEST_TIMEOUT_MS 500 // try for half a second
////////////////////////////////////////////////////////////
//
// BC Arp Routine
//
EFI_STATUS
EFIAPI
BcArp (
IN EFI_PXE_BASE_CODE_PROTOCOL * This,
IN EFI_IP_ADDRESS * ProtocolAddrPtr,
OUT EFI_MAC_ADDRESS * HardwareAddrPtr OPTIONAL
)
/*++
Routine description:
PxeBc ARP API.
Parameters:
This := Pointer to PxeBc interface
ProtocolAddrPtr := Pointer to IP address to find
HardwareAddrPtr := Pointer to MAC address found.
Returns:
--*/
{
EFI_MAC_ADDRESS Mac;
EFI_STATUS StatCode;
PXE_BASECODE_DEVICE *Private;
//
// Lock the instance data and make sure started
//
StatCode = EFI_SUCCESS;
if (This == NULL) {
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));
return EFI_INVALID_PARAMETER;
}
Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);
if (Private == NULL) {
DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));
return EFI_INVALID_PARAMETER;
}
EfiAcquireLock (&Private->Lock);
if (This->Mode == NULL || !This->Mode->Started) {
DEBUG ((EFI_D_ERROR, "BC was not started."));
EfiReleaseLock (&Private->Lock);
return EFI_NOT_STARTED;
}
DEBUG ((EFI_D_INFO, "\nBcArp()"));
//
// Issue BC command
//
if (ProtocolAddrPtr == NULL) {
DEBUG (
(EFI_D_INFO,
"\nBcArp() Exit #1 %Xh (%r)",
EFI_INVALID_PARAMETER,
EFI_INVALID_PARAMETER)
);
EfiReleaseLock (&Private->Lock);
return EFI_INVALID_PARAMETER;
}
if (HardwareAddrPtr == NULL) {
HardwareAddrPtr = &Mac;
}
EfiZeroMem (HardwareAddrPtr, Private->SimpleNetwork->Mode->HwAddressSize);
if (GetHwAddr (Private, ProtocolAddrPtr, HardwareAddrPtr)) {
DEBUG (
(EFI_D_INFO,
"\nBcArp() Exit #2 %Xh (%r)",
EFI_SUCCESS,
EFI_SUCCESS)
);
EfiReleaseLock (&Private->Lock);
return EFI_SUCCESS;
}
StatCode = DoArp (Private, ProtocolAddrPtr, HardwareAddrPtr);
DEBUG ((EFI_D_INFO, "\nBcArp() Exit #3 %Xh (%r)", StatCode, StatCode));
EfiReleaseLock (&Private->Lock);
return StatCode;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
EFI_STATUS
DoArp (
IN PXE_BASECODE_DEVICE *Private,
IN EFI_IP_ADDRESS *ProtocolAddrPtr,
OUT EFI_MAC_ADDRESS *HardwareAddrPtr
)
/*++
Routine description:
Internal ARP implementation.
Parameters:
Private := Pointer to PxeBc interface
ProtocolAddrPtr := Pointer to IP address to find
HardwareAddrPtr := Pointer to MAC address found
Returns:
EFI_SUCCESS := MAC address found
other := MAC address could not be found
--*/
{
EFI_STATUS StatCode;
EFI_EVENT TimeoutEvent;
UINTN HeaderSize;
UINTN BufferSize;
UINT16 Protocol;
DEBUG ((EFI_D_INFO, "\nDoArp()"));
//
//
//
StatCode = SendRequest (Private, ProtocolAddrPtr, HardwareAddrPtr);
if (EFI_ERROR (StatCode)) {
DEBUG ((EFI_D_INFO, "\nDoArp() Exit #1 %Xh (%r)", StatCode, StatCode));
return StatCode;
}
//
//
//
StatCode = gBS->CreateEvent (
EFI_EVENT_TIMER,
EFI_TPL_CALLBACK,
NULL,
NULL,
&TimeoutEvent
);
if (EFI_ERROR (StatCode)) {
return StatCode;
}
StatCode = gBS->SetTimer (
TimeoutEvent,
TimerRelative,
ARP_REQUEST_TIMEOUT_MS * 10000
);
if (EFI_ERROR (StatCode)) {
gBS->CloseEvent (TimeoutEvent);
return StatCode;
}
//
//
//
for (;;) {
StatCode = WaitForReceive (
Private,
EFI_PXE_BASE_CODE_FUNCTION_ARP,
TimeoutEvent,
&HeaderSize,
&BufferSize,
&Protocol
);
if (EFI_ERROR (StatCode)) {
break;
}
if (Protocol != PXE_PROTOCOL_ETHERNET_ARP) {
continue;
}
HandleArpReceive (
Private,
(ARP_PACKET *) (Private->ReceiveBufferPtr + HeaderSize),
Private->ReceiveBufferPtr
);
if (GetHwAddr (Private, ProtocolAddrPtr, HardwareAddrPtr)) {
break;
}
}
DEBUG (
(EFI_D_INFO,
"\nDoArp() Exit #2 %Xh, (%r)",
StatCode,
StatCode)
);
gBS->CloseEvent (TimeoutEvent);
return StatCode;
}
/* eof - pxe_bc_arp.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?