bc.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,547 行 · 第 1/5 页
C
2,547 行
EfiReleaseLock (&Private->Lock);
return EFI_OUT_OF_RESOURCES;
}
//
// Initialize private BaseCode instance data
//
do {
Private->RandomPort = (UINT16) (Private->RandomPort + PXE_RND_PORT_LOW + Random (Private));
} while (Private->RandomPort < PXE_RND_PORT_LOW);
Private->Igmpv1TimeoutEvent = NULL;
Private->UseIgmpv1Reporting = TRUE;
Private->IpLength = IP_ADDRESS_LENGTH (Private->EfiBc.Mode);
//
// Initialize Mode structure
//
//
// check for callback protocol and set boolean
//
SetMakeCallback (Private);
Private->EfiBc.Mode->Started = TRUE;
Private->EfiBc.Mode->TTL = DEFAULT_TTL;
Private->EfiBc.Mode->ToS = DEFAULT_ToS;
Private->EfiBc.Mode->UsingIpv6 = UseIPv6;
Private->EfiBc.Mode->DhcpDiscoverValid = FALSE;
Private->EfiBc.Mode->DhcpAckReceived = FALSE;
Private->EfiBc.Mode->ProxyOfferReceived = FALSE;
Private->EfiBc.Mode->PxeDiscoverValid = FALSE;
Private->EfiBc.Mode->PxeReplyReceived = FALSE;
Private->EfiBc.Mode->PxeBisReplyReceived = FALSE;
Private->EfiBc.Mode->IcmpErrorReceived = FALSE;
Private->EfiBc.Mode->TftpErrorReceived = FALSE;
EfiZeroMem (&Private->EfiBc.Mode->StationIp, sizeof (EFI_IP_ADDRESS));
EfiZeroMem (&Private->EfiBc.Mode->SubnetMask, sizeof (EFI_IP_ADDRESS));
Private->EfiBc.Mode->IpFilter.Filters = 0;
Private->EfiBc.Mode->IpFilter.IpCnt = 0;
Private->EfiBc.Mode->ArpCacheEntries = 0;
Private->EfiBc.Mode->RouteTableEntries = 0;
EfiZeroMem (&Private->EfiBc.Mode->IcmpError, sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));
EfiZeroMem (&Private->EfiBc.Mode->TftpError, sizeof (EFI_PXE_BASE_CODE_TFTP_ERROR));
//
// Set to PXE_TRUE by the BC constructor if this BC implementation
// supports IPv6.
//
Private->EfiBc.Mode->Ipv6Supported = SUPPORT_IPV6;
#if SUPPORT_IPV6
Private->EfiBc.Mode->Ipv6Available = Private->NiiPtr->Ipv6Supported;
#else
Private->EfiBc.Mode->Ipv6Available = FALSE;
#endif
//
// Set to TRUE by the BC constructor if this BC implementation
// supports BIS.
//
Private->EfiBc.Mode->BisSupported = TRUE;
Private->EfiBc.Mode->BisDetected = PxebcBisDetect (Private);
//
// This field is set to PXE_TRUE by the BC Start() function. When this
// field is PXE_TRUE, ARP packets are sent as needed to get IP and MAC
// addresses. This can cause unexpected delays in the DHCP(), Discover()
// and MTFTP() functions. Setting this to PXE_FALSE will cause these
// functions to fail if the required IP/MAC information is not in the
// ARP cache. The value of this field can be changed by an application
// at any time.
//
Private->EfiBc.Mode->AutoArp = TRUE;
//
// Unlock the instance data
//
EfiReleaseLock (&Private->Lock);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
BcStop (
IN EFI_PXE_BASE_CODE_PROTOCOL *This
)
/*++
Routine Description:
Stop the BaseCode protocol, Simple Network protocol and UNDI.
Arguments:
Private - Pointer to Pxe BaseCode Protocol
Returns:
0 - Successfully stopped
!0 - Failed
--*/
{
//
// Lock the instance data
//
EFI_PXE_BASE_CODE_MODE *PxebcMode;
EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;
EFI_SIMPLE_NETWORK_MODE *SnpModePtr;
EFI_STATUS StatCode;
PXE_BASECODE_DEVICE *Private;
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);
PxebcMode = Private->EfiBc.Mode;
SnpPtr = Private->SimpleNetwork;
SnpModePtr = SnpPtr->Mode;
//
// Issue BC command
//
StatCode = EFI_NOT_STARTED;
if (SnpModePtr->State == EfiSimpleNetworkInitialized) {
StatCode = (*SnpPtr->Shutdown) (SnpPtr);
}
if (SnpModePtr->State == EfiSimpleNetworkStarted) {
StatCode = (*SnpPtr->Stop) (SnpPtr);
}
if (Private->TransmitBufferPtr != NULL) {
gBS->FreePool (Private->TransmitBufferPtr);
Private->TransmitBufferPtr = NULL;
}
if (Private->ReceiveBufferPtr != NULL) {
gBS->FreePool (Private->ReceiveBufferPtr);
Private->ReceiveBufferPtr = NULL;
}
if (Private->ArpBuffer != NULL) {
gBS->FreePool (Private->ArpBuffer);
Private->ArpBuffer = NULL;
}
if (Private->TftpErrorBuffer != NULL) {
gBS->FreePool (Private->TftpErrorBuffer);
Private->TftpErrorBuffer = NULL;
}
if (Private->TftpAckBuffer != NULL) {
gBS->FreePool (Private->TftpAckBuffer);
Private->TftpAckBuffer = NULL;
}
if (Private->Igmpv1TimeoutEvent != NULL) {
gBS->CloseEvent (Private->Igmpv1TimeoutEvent);
Private->Igmpv1TimeoutEvent = NULL;
}
Private->FileSize = 0;
Private->EfiBc.Mode->Started = FALSE;
//
// Unlock the instance data
//
EfiReleaseLock (&Private->Lock);
return StatCode;
}
const IPV4_ADDR AllSystemsGroup = { 224, 0, 0, 1 };
EFI_STATUS
IpFilter (
IN PXE_BASECODE_DEVICE *Private,
IN EFI_PXE_BASE_CODE_IP_FILTER *Filter
)
/*++
Routine Description:
Set up the IP filter
Arguments:
Private - Pointer to Pxe BaseCode Protocol
Filter - Pointer to the filter
Returns:
0 - Successfully set the filter
!0 - Failed
--*/
{
EFI_STATUS StatCode;
EFI_MAC_ADDRESS MACadds[PXE_IP_FILTER_SIZE];
EFI_PXE_BASE_CODE_MODE *PxebcMode;
EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;
EFI_SIMPLE_NETWORK_MODE *SnpModePtr;
UINT32 Enable;
UINT32 Disable;
UINTN Index;
UINTN Index2;
PxebcMode = Private->EfiBc.Mode;
SnpPtr = Private->SimpleNetwork;
SnpModePtr = SnpPtr->Mode;
//
// validate input parameters
// must have a filter
// must not have any extra filter bits set
//
if (Filter == NULL ||
(Filter->Filters &~FILTER_BITS)
//
// must not have a count which is too large or with no IP list
//
||
(Filter->IpCnt && (!Filter->IpList || Filter->IpCnt > PXE_IP_FILTER_SIZE))
//
// must not have incompatible filters - promiscuous incompatible with anything else
//
||
(
(Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) &&
((Filter->Filters &~EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) || Filter->IpCnt)
)
) {
DEBUG ((EFI_D_INFO, "\nIpFilter() Exit #1"));
return EFI_INVALID_PARAMETER;
}
//
// promiscuous multicast incompatible with multicast in IP list
//
if (Filter->IpCnt && (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST)) {
for (Index = 0; Index < Filter->IpCnt; ++Index) {
if (IS_MULTICAST (&Filter->IpList[Index])) {
DEBUG ((EFI_D_INFO, "\nIpFilter() Exit #2"));
return EFI_INVALID_PARAMETER;
}
}
}
//
// leave groups for all those multicast which are no longer enabled
//
for (Index = 0; Index < PxebcMode->IpFilter.IpCnt; ++Index) {
if (!IS_MULTICAST (&PxebcMode->IpFilter.IpList[Index])) {
continue;
}
for (Index2 = 0; Index2 < Filter->IpCnt; ++Index2) {
if (!EfiCompareMem (&PxebcMode->IpFilter.IpList[Index], &Filter->IpList[Index2], IP_ADDRESS_LENGTH (PxebcMode))) {
//
// still enabled
//
break;
}
}
//
// if we didn't find it, remove from group
//
if (Index2 == Filter->IpCnt) {
IgmpLeaveGroup (Private, &PxebcMode->IpFilter.IpList[Index]);
}
}
//
// set enable bits, convert multicast ip adds, join groups
// allways leave receive broadcast enabled at hardware layer
//
Index2 = 0;
if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) {
Enable = EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
} else {
if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) {
Enable = EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
} else {
Enable = EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
for (Index = 0; Index < Filter->IpCnt; ++Index) {
PxebcMode->IpFilter.IpList[Index] = Filter->IpList[Index];
if (IS_MULTICAST (&Filter->IpList[Index])) {
EFI_IP_ADDRESS *TmpIp;
Enable |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
//
// if this is the first group, add the all systems group to mcast list
//
if (!Index2)
{
#if SUPPORT_IPV6
if (PxebcMode->UsingIpv6) {
//
// TBD
//
} else
#endif
TmpIp = (EFI_IP_ADDRESS *) &AllSystemsGroup;
--Index;
} else {
TmpIp = (EFI_IP_ADDRESS *) &Filter->IpList[Index];
}
//
// get MAC address of IP
//
StatCode = (*SnpPtr->MCastIpToMac) (SnpPtr, PxebcMode->UsingIpv6, TmpIp, &MACadds[Index2++]);
if (EFI_ERROR (StatCode)) {
DEBUG (
(EFI_D_INFO,
"\nIpFilter() Exit #2 %Xh (%r)",
StatCode,
StatCode)
);
return StatCode;
}
} else {
Enable |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
}
}
}
if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) {
Enable |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
}
}
//
// if nothing changed, just return
//
DEBUG (
(EFI_D_INFO,
"\nsnp->ReceiveFilterSetting == %Xh Filter->IpCnt == %Xh",
SnpModePtr->ReceiveFilterSetting,
Filter->IpCnt)
);
if (SnpModePtr->ReceiveFilterSetting == Enable && !Filter->IpCnt) {
DEBUG ((EFI_D_INFO, "\nIpFilter() Exit #4"));
return EFI_SUCCESS;
}
//
// disable those currently set but not set in new filter
//
Disable = SnpModePtr->ReceiveFilterSetting &~Enable;
StatCode = SnpPtr->ReceiveFilters (SnpPtr, Enable, Disable, FALSE, Index2, MACadds);
PxebcMode->IpFilter.IpCnt = Filter->IpCnt;
//
// join groups for all multicast in list
//
for (Index = 0; Index < Filter->IpCnt; ++Index) {
if (IS_MULTICAST (&Filter->IpList[Index])) {
IgmpJoinGroup (Private, &Filter->IpList[Index]);
}
}
DEBUG ((EFI_D_INFO, "\nIpFilter() Exit #5 %Xh (%r)", StatCode, StatCode));
return StatCode;
}
EFI_STATUS
EFIAPI
BcIpFilter (
IN EFI_PXE_BASE_CODE_PROTOCOL *This,
IN EFI_PXE_BASE_CODE_IP_FILTER *Filter
)
/*++
Routine Description:
Call the IP filter
Arguments:
Private - Pointer to Pxe BaseCode Protocol
Filter - Pointer to the filter
Returns:
0 - Successfully set the filter
!0 - Failed
--*/
{
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;
}
if (Filter == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Issue BC command
//
StatCode = IpFilter (Private, Filter);
//
// Unlock the instance data
//
EfiReleaseLock (&Private->Lock);
return StatCode;
}
EFI_STATUS
EFIAPI
BcSetParameters (
EFI_PXE_BASE_CODE_PROTOCOL *This,
BOOLEAN *AutoArpPtr,
BOOLEAN *SendGuidPtr,
UINT8 *TimeToLivePtr,
UINT8 *TypeOfServicePtr,
BOOLEAN *MakeCallbackPtr
)
/*++
Routine Description:
Set the Base Code behavior parameters
Arguments:
This - Pointer to Pxe BaseCode Protocol
AutoArpPtr - Boolean to do ARP stuff
SendGuidPtr - Boolean whether or not to send GUID info
TimeToLivePtr - Value for Total time to live
TypeOfServicePtr - Value for Type of Service
MakeCallbackPtr - Boolean to determine if we make callbacks
Returns:
0 - Successfully set the parameters
!0 - Failed
--*/
{
EFI_PXE_BASE_CODE_MODE *PxebcMode;
EFI_GUID TmpGuid;
UINT8 *SerialNumberPtr;
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, "\nSetParameters() Entry. "));
PxebcMode = Private->EfiBc.Mode;
StatCode = EFI_SUCCESS;
if (SendGuidPtr != NULL) {
if (*SendGuidPtr) {
if (PxeBcLibGetSmbiosSystemGuidAndSerialNumber (&TmpGuid, &SerialNumberPtr) != EFI_SUCCESS) {
return EFI_INVALID_PARAMETER;
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?