ip4config.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 778 行 · 第 1/2 页
C
778 行
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Check the current DHCP status, if the DHCP process has
// already finished, return now.
//
Dhcp4 = Instance->Dhcp4;
Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
if (Dhcp4Mode.State == Dhcp4Bound) {
Ip4ConfigOnDhcp4Complete (NULL, Instance);
return EFI_SUCCESS;
}
//
// Try to start the DHCP process. Use most of the current
// DHCP configuration to avoid problems if some DHCP client
// yields the control of this DHCP service to us.
//
ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;
ParaList.Head.Length = 2;
ParaList.Head.Data[0] = DHCP_TAG_NETMASK;
ParaList.Route = DHCP_TAG_ROUTER;
OptionList[0] = &ParaList.Head;
Dhcp4Mode.ConfigData.OptionCount = 1;
Dhcp4Mode.ConfigData.OptionList = OptionList;
Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Start the DHCP process
//
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL,
NET_TPL_EVENT,
Ip4ConfigOnDhcp4Complete,
Instance,
&Instance->Dhcp4Event
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Instance->State = IP4_CONFIG_STATE_STARTED;
Instance->Result = EFI_NOT_READY;
return EFI_SUCCESS;
ON_ERROR:
Ip4ConfigCleanConfig (Instance);
return Status;
}
EFI_STATUS
EFIAPI
EfiIp4ConfigStop (
IN EFI_IP4_CONFIG_PROTOCOL *This
)
/*++
Routine Description:
Stop the current auto configuration
Arguments:
This - The IP4 CONFIG protocol
Returns:
EFI_INVALID_PARAMETER - This is NULL.
EFI_NOT_STARTED - The auto configuration hasn't been started.
EFI_SUCCESS - The auto configuration has been stopped.
--*/
{
IP4_CONFIG_INSTANCE *Instance;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);
if (Instance->State == IP4_CONFIG_STATE_IDLE) {
return EFI_NOT_STARTED;
}
//
// Release all the configure parameters. Don't signal the user
// event. The user wants to abort the configuration, this isn't
// the configuration done or reconfiguration.
//
Ip4ConfigCleanConfig (Instance);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
EfiIp4ConfigGetData (
IN EFI_IP4_CONFIG_PROTOCOL *This,
IN OUT UINTN *ConfigDataSize,
OUT EFI_IP4_IPCONFIG_DATA *ConfigData OPTIONAL
)
/*++
Routine Description:
Get the current outcome of the auto configuration process
Arguments:
This - The IP4 CONFIG protocol
ConfigDataSize - The size of the configure data
ConfigData - The buffer to save the configure data
Returns:
EFI_INVALID_PARAMETER - This or ConfigDataSize is NULL
EFI_BUFFER_TOO_SMALL - The buffer is too small. The needed size is
returned in the ConfigDataSize.
EFI_SUCCESS - The configure data is put in the buffer
--*/
{
IP4_CONFIG_INSTANCE *Instance;
NIC_IP4_CONFIG_INFO *NicConfig;
EFI_STATUS Status;
UINTN Len;
if ((This == NULL) || (ConfigDataSize == NULL)) {
return EFI_INVALID_PARAMETER;
}
Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);
if (Instance->State == IP4_CONFIG_STATE_IDLE) {
return EFI_NOT_STARTED;
} else if (Instance->State == IP4_CONFIG_STATE_STARTED) {
return EFI_NOT_READY;
}
//
// Copy the configure data if auto configuration succeeds.
//
Status = Instance->Result;
if (Status == EFI_SUCCESS) {
ASSERT (Instance->NicConfig != NULL);
NicConfig = Instance->NicConfig;
Len = SIZEOF_IP4_CONFIG_INFO (&NicConfig->Ip4Info);
if ((*ConfigDataSize < Len) || (ConfigData == NULL)) {
Status = EFI_BUFFER_TOO_SMALL;
} else {
NetCopyMem (ConfigData, &NicConfig->Ip4Info, Len);
}
*ConfigDataSize = Len;
}
return Status;
}
VOID
EFIAPI
Ip4ConfigOnDhcp4Complete (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Callback function when DHCP process finished. It will save the
retrieved IP configure parameter from DHCP to the NVRam.
Arguments:
Event - The callback event
Context - Opaque context to the callback
Returns:
None
--*/
{
IP4_CONFIG_INSTANCE *Instance;
EFI_DHCP4_MODE_DATA Dhcp4Mode;
EFI_IP4_IPCONFIG_DATA *Ip4Config;
EFI_STATUS Status;
BOOLEAN Perment;
IP4_ADDR Subnet;
Instance = (IP4_CONFIG_INSTANCE *) Context;
ASSERT (Instance->Dhcp4 != NULL);
Instance->State = IP4_CONFIG_STATE_CONFIGURED;
Instance->Result = EFI_TIMEOUT;
//
// Get the DHCP retrieved parameters
//
Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
if (Dhcp4Mode.State == Dhcp4Bound) {
//
// Save the new configuration retrieved by DHCP both in
// the instance and to NVRam. So, both the IP4 driver and
// other user can get that address.
//
Perment = FALSE;
if (Instance->NicConfig != NULL) {
ASSERT (Instance->NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);
Perment = Instance->NicConfig->Perment;
NetFreePool (Instance->NicConfig);
}
Instance->NicConfig = NetAllocatePool (sizeof (NIC_IP4_CONFIG_INFO) +
sizeof (EFI_IP4_ROUTE_TABLE));
if (Instance->NicConfig == NULL) {
Instance->Result = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Instance->NicConfig->NicAddr = Instance->NicAddr;
Instance->NicConfig->Source = IP4_CONFIG_SOURCE_DHCP;
Instance->NicConfig->Perment = Perment;
Ip4Config = &Instance->NicConfig->Ip4Info;
Ip4Config->StationAddress = Dhcp4Mode.ClientAddress;
Ip4Config->SubnetMask = Dhcp4Mode.SubnetMask;
//
// Create a route for the connected network
//
Ip4Config->RouteTableSize = 1;
Subnet = EFI_NTOHL (Dhcp4Mode.ClientAddress) & EFI_NTOHL (Dhcp4Mode.SubnetMask);
EFI_IP4 (Ip4Config->RouteTable[0].SubnetAddress) = HTONL (Subnet);
Ip4Config->RouteTable[0].SubnetMask = Dhcp4Mode.SubnetMask;
EFI_IP4 (Ip4Config->RouteTable[0].GatewayAddress) = 0;
//
// Create a route if there is a default router.
//
if (EFI_IP4 (Dhcp4Mode.RouterAddress) != 0) {
Ip4Config->RouteTableSize = 2;
EFI_IP4 (Ip4Config->RouteTable[1].SubnetAddress) = 0;
EFI_IP4 (Ip4Config->RouteTable[1].SubnetMask) = 0;
Ip4Config->RouteTable[1].GatewayAddress = Dhcp4Mode.RouterAddress;
}
Instance->Result = EFI_SUCCESS;
//
// ignore the return status of EfiNicIp4ConfigSetInfo. Network
// stack can operate even that failed.
//
EfiNicIp4ConfigSetInfo (&Instance->NicIp4Protocol, Instance->NicConfig, FALSE);
}
ON_EXIT:
gBS->SignalEvent (Instance->DoneEvent);
Ip4ConfigCleanDhcp4 (Instance);
return ;
}
VOID
Ip4ConfigCleanDhcp4 (
IN IP4_CONFIG_INSTANCE *This
)
/*++
Routine Description:
Release all the DHCP related resources.
Arguments:
This - The IP4 configure instance
Returns:
None
--*/
{
if (This->Dhcp4 != NULL) {
This->Dhcp4->Stop (This->Dhcp4);
gBS->CloseProtocol (
This->Dhcp4Handle,
&gEfiDhcp4ProtocolGuid,
This->Image,
This->Controller
);
This->Dhcp4 = NULL;
}
if (This->Dhcp4Handle != NULL) {
NetLibDestroyServiceChild (
This->Controller,
This->Image,
&gEfiDhcp4ServiceBindingProtocolGuid,
This->Dhcp4Handle
);
This->Dhcp4Handle = NULL;
}
if (This->Dhcp4Event == NULL) {
gBS->CloseEvent (This->Dhcp4Event);
This->Dhcp4Event = NULL;
}
}
VOID
Ip4ConfigCleanConfig (
IN IP4_CONFIG_INSTANCE *Instance
)
/*++
Routine Description:
Clean up all the configuration parameters
Arguments:
Instance - The IP4 configure instance
Returns:
None
--*/
{
if (Instance->NicConfig != NULL) {
NetFreePool (Instance->NicConfig);
Instance->NicConfig = NULL;
}
Instance->State = IP4_CONFIG_STATE_IDLE;
Instance->DoneEvent = NULL;
Instance->ReconfigEvent = NULL;
Ip4ConfigCleanDhcp4 (Instance);
}
EFI_IP4_CONFIG_PROTOCOL mIp4ConfigProtocolTemplate = {
EfiIp4ConfigStart,
EfiIp4ConfigStop,
EfiIp4ConfigGetData
};
EFI_NIC_IP4_CONFIG_PROTOCOL mNicIp4ConfigProtocolTemplate = {
EfiNicIp4ConfigGetName,
EfiNicIp4ConfigGetInfo,
EfiNicIp4ConfigSetInfo
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?