Revision: 17853
http://sourceforge.net/p/edk2/code/17853
Author: jiaxinwu
Date: 2015-07-07 08:19:55 +0000 (Tue, 07 Jul 2015)
Log Message:
-----------
MdeModulePkg: Update Ip4Dxe driver to support Ip4Config2 protocol,
and also add new UI configuration support in Ip4Dxe driver.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: jiaxinwu <[email protected]>
Reviewed-by: Ye Ting <[email protected]>
Modified Paths:
--------------
trunk/edk2/MdeModulePkg/MdeModulePkg.dec
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.h
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.h
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.c
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.h
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
Added Paths:
-----------
trunk/edk2/MdeModulePkg/Include/Guid/Ip4Config2Hii.h
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2.vfr
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Nv.c
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Nv.h
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4DxeStrings.uni
trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4NvData.h
Added: trunk/edk2/MdeModulePkg/Include/Guid/Ip4Config2Hii.h
===================================================================
--- trunk/edk2/MdeModulePkg/Include/Guid/Ip4Config2Hii.h
(rev 0)
+++ trunk/edk2/MdeModulePkg/Include/Guid/Ip4Config2Hii.h 2015-07-07
08:19:55 UTC (rev 17853)
@@ -0,0 +1,25 @@
+/** @file
+ GUIDs used as HII FormSet and HII Package list GUID in Ip4Dxe driver.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available
under
+the terms and conditions of the BSD License that 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.
+
+**/
+
+#ifndef __IP4_CONFIG2_HII_GUID_H__
+#define __IP4_CONFIG2_HII_GUID_H__
+
+#define IP4_CONFIG2_NVDATA_GUID \
+ { \
+ 0x9b942747, 0x154e, 0x4d29, { 0xa4, 0x36, 0xbf, 0x71, 0x0, 0xc8, 0xb5,
0x3b } \
+ }
+
+extern EFI_GUID gIp4Config2NvDataGuid;
+
+#endif
Modified: trunk/edk2/MdeModulePkg/MdeModulePkg.dec
===================================================================
--- trunk/edk2/MdeModulePkg/MdeModulePkg.dec 2015-07-07 08:17:28 UTC (rev
17852)
+++ trunk/edk2/MdeModulePkg/MdeModulePkg.dec 2015-07-07 08:19:55 UTC (rev
17853)
@@ -267,6 +267,9 @@
## Include/Guid/Ip4ConfigHii.h
gNicIp4ConfigNvDataGuid = { 0x9d5b53f, 0xf4b0, 0x4f59, { 0xa0,
0xb1, 0x7b, 0x57, 0xd3, 0x5c, 0xe, 0x5 }}
+ ## Include/Guid/Ip4Config2Hii.h
+ gIp4Config2NvDataGuid = { 0x9b942747, 0x154e, 0x4d29, { 0xa4,
0x36, 0xbf, 0x71, 0x0, 0xc8, 0xb5, 0x3b }}
+
## Include/Guid/VlanConfigHii.h
gVlanConfigFormSetGuid = { 0xd79df6b0, 0xef44, 0x43bd, { 0x97,
0x97, 0x43, 0xe9, 0x3b, 0xcf, 0x5f, 0xa8 }}
Added: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2.vfr
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2.vfr
(rev 0)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2.vfr
2015-07-07 08:19:55 UTC (rev 17853)
@@ -0,0 +1,100 @@
+/** @file
+ Vfr file for IP4Dxe.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+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.
+
+**/
+#include "Ip4NvData.h"
+
+#define EFI_NETWORK_DEVICE_CLASS 0x04
+
+formset
+ guid = IP4_CONFIG2_NVDATA_GUID,
+ title = STRING_TOKEN(STR_IP4_CONFIG2_FORM_TITLE),
+ help = STRING_TOKEN(STR_IP4_CONFIG2_FORM_HELP),
+ class = EFI_NETWORK_DEVICE_CLASS,
+ subclass = 0x03,
+
+ varstore IP4_CONFIG2_IFR_NVDATA,
+ name = IP4_CONFIG2_IFR_NVDATA,
+ guid = IP4_CONFIG2_NVDATA_GUID;
+
+ form formid = FORMID_MAIN_FORM,
+ title = STRING_TOKEN(STR_IP4_DEVICE_FORM_TITLE);
+
+ checkbox varid = IP4_CONFIG2_IFR_NVDATA.Configure,
+ prompt = STRING_TOKEN(STR_IP4_CONFIGURE),
+ help = STRING_TOKEN(STR_IP4_CONFIGURE),
+ flags = INTERACTIVE,
+ key = KEY_ENABLE,
+ endcheckbox;
+
+ suppressif ideqval IP4_CONFIG2_IFR_NVDATA.Configure == 0x00;
+
+ checkbox varid = IP4_CONFIG2_IFR_NVDATA.DhcpEnable,
+ prompt = STRING_TOKEN(STR_IP4_ENABLE_DHCP),
+ help = STRING_TOKEN(STR_IP4_ENABLE_DHCP),
+ flags = INTERACTIVE,
+ key = KEY_DHCP_ENABLE,
+ endcheckbox;
+ endif;
+
+ suppressif ideqval IP4_CONFIG2_IFR_NVDATA.DhcpEnable == 0x01 OR ideqval
IP4_CONFIG2_IFR_NVDATA.Configure == 0x00;
+
+ string varid = IP4_CONFIG2_IFR_NVDATA.StationAddress,
+ prompt = STRING_TOKEN(STR_IP4_LOCAL_IP_ADDRESS),
+ help = STRING_TOKEN(STR_IP4_IP_ADDRESS_HELP),
+ flags = INTERACTIVE,
+ key = KEY_LOCAL_IP,
+ minsize = IP_MIN_SIZE,
+ maxsize = IP_MAX_SIZE,
+ endstring;
+
+ string varid = IP4_CONFIG2_IFR_NVDATA.SubnetMask,
+ prompt = STRING_TOKEN(STR_IP4_LOCAL_MASK),
+ help = STRING_TOKEN(STR_IP4_MASK_HELP),
+ flags = INTERACTIVE,
+ key = KEY_SUBNET_MASK,
+ minsize = IP_MIN_SIZE,
+ maxsize = IP_MAX_SIZE,
+ endstring;
+
+ string varid = IP4_CONFIG2_IFR_NVDATA.GatewayAddress,
+ prompt = STRING_TOKEN(STR_IP4_LOCAL_GATEWAY),
+ help = STRING_TOKEN(STR_IP4_GATEWAY_HELP),
+ flags = INTERACTIVE,
+ key = KEY_GATE_WAY,
+ minsize = IP_MIN_SIZE,
+ maxsize = IP_MAX_SIZE,
+ endstring;
+
+ string varid = IP4_CONFIG2_IFR_NVDATA.DnsAddress,
+ prompt = STRING_TOKEN(STR_IP4_LOCAL_DNS),
+ help = STRING_TOKEN(STR_IP4_DNS_HELP),
+ flags = INTERACTIVE,
+ key = KEY_DNS,
+ minsize = IP_MIN_SIZE,
+ maxsize = ADDRESS_STR_MAX_SIZE,
+ endstring;
+
+ endif;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ text
+ help = STRING_TOKEN(STR_SAVE_CHANGES),
+ text = STRING_TOKEN(STR_SAVE_CHANGES),
+ flags = INTERACTIVE,
+ key = KEY_SAVE_CHANGES;
+
+ endform;
+
+endformset;
+
Added: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
(rev 0)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
2015-07-07 08:19:55 UTC (rev 17853)
@@ -0,0 +1,1969 @@
+/** @file
+ The implementation of EFI IPv4 Configuration II Protocol.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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.
+
+**/
+
+#include "Ip4Impl.h"
+
+LIST_ENTRY mIp4Config2InstanceList = {&mIp4Config2InstanceList,
&mIp4Config2InstanceList};
+
+/**
+ The event process routine when the DHCPv4 service binding protocol is
installed
+ in the system.
+
+ @param[in] Event Not used.
+ @param[in] Context Pointer to the IP4 config2 instance data.
+
+**/
+VOID
+EFIAPI
+Ip4Config2OnDhcp4SbInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources.
+
+ @param[in, out] Instance The buffer of IP4 config2 instance to be freed.
+
+ @retval EFI_SUCCESS The child was successfully destroyed.
+ @retval Others Failed to destroy the child.
+
+**/
+EFI_STATUS
+Ip4Config2DestroyDhcp4 (
+ IN OUT IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ IP4_SERVICE *IpSb;
+ EFI_STATUS Status;
+ EFI_DHCP4_PROTOCOL *Dhcp4;
+
+ Dhcp4 = Instance->Dhcp4;
+ ASSERT (Dhcp4 != NULL);
+
+ Dhcp4->Stop (Dhcp4);
+ Dhcp4->Configure (Dhcp4, NULL);
+ Instance->Dhcp4 = NULL;
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+
+ //
+ // Close DHCPv4 protocol and destroy the child.
+ //
+ Status = gBS->CloseProtocol (
+ Instance->Dhcp4Handle,
+ &gEfiDhcp4ProtocolGuid,
+ IpSb->Image,
+ IpSb->Controller
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = NetLibDestroyServiceChild (
+ IpSb->Controller,
+ IpSb->Image,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ Instance->Dhcp4Handle
+ );
+
+ Instance->Dhcp4Handle = NULL;
+
+ return Status;
+}
+
+/**
+ Start the DHCP configuration for this IP service instance.
+ It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the
+ DHCP configuration.
+
+ @param[in] Instance The IP4 config2 instance to configure.
+
+ @retval EFI_SUCCESS The auto configuration is successfull started.
+ @retval Others Failed to start auto configuration.
+
+**/
+EFI_STATUS
+Ip4StartAutoConfig (
+ IN IP4_CONFIG2_INSTANCE *Instance
+ );
+
+/**
+ Update the current policy to NewPolicy. During the transition
+ period, the default router list
+ and address list in all interfaces will be released.
+
+ @param[in] IpSb The IP4 service binding instance.
+ @param[in] NewPolicy The new policy to be updated to.
+
+**/
+VOID
+Ip4Config2OnPolicyChanged (
+ IN IP4_SERVICE *IpSb,
+ IN EFI_IP4_CONFIG2_POLICY NewPolicy
+ )
+{
+ IP4_INTERFACE *IpIf;
+ IP4_ROUTE_TABLE *RouteTable;
+
+ //
+ // Currently there are only two policies: static and dhcp. Regardless of
+ // what transition is going on, i.e., static -> dhcp and dhcp ->
+ // static, we have to free default router table and all addresses.
+ //
+
+ if (IpSb->DefaultInterface != NULL) {
+ if (IpSb->DefaultRouteTable != NULL) {
+ Ip4FreeRouteTable (IpSb->DefaultRouteTable);
+ IpSb->DefaultRouteTable = NULL;
+ }
+
+ Ip4CancelReceive (IpSb->DefaultInterface);
+
+ Ip4FreeInterface (IpSb->DefaultInterface, NULL);
+ IpSb->DefaultInterface = NULL;
+ }
+
+ Ip4CleanAssembleTable (&IpSb->Assemble);
+
+ //
+ // Create new default interface and route table.
+ //
+ IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
+ if (IpIf == NULL) {
+ return ;
+ }
+
+ RouteTable = Ip4CreateRouteTable ();
+ if (RouteTable == NULL) {
+ Ip4FreeInterface (IpIf, NULL);
+ return ;
+ }
+
+ IpSb->DefaultInterface = IpIf;
+ InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
+ IpSb->DefaultRouteTable = RouteTable;
+ Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
+
+ if (IpSb->State == IP4_SERVICE_CONFIGED) {
+ IpSb->State = IP4_SERVICE_UNSTARTED;
+ }
+
+ //
+ // Start the dhcp configuration.
+ //
+ if (NewPolicy == Ip4Config2PolicyDhcp) {
+ Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);
+ }
+
+}
+
+/**
+ Signal the registered event. It is the callback routine for NetMapIterate.
+
+ @param[in] Map Points to the list of registered event.
+ @param[in] Item The registered event.
+ @param[in] Arg Not used.
+
+ @retval EFI_SUCCESS The event was signaled successfully.
+**/
+EFI_STATUS
+EFIAPI
+Ip4Config2SignalEvent (
+ IN NET_MAP *Map,
+ IN NET_MAP_ITEM *Item,
+ IN VOID *Arg
+ )
+{
+ gBS->SignalEvent ((EFI_EVENT) Item->Key);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Read the configuration data from variable storage according to the VarName
and
+ gEfiIp4Config2ProtocolGuid. It checks the integrity of variable data. If the
+ data is corrupted, it clears the variable data to ZERO. Othewise, it outputs
the
+ configuration data to IP4_CONFIG2_INSTANCE.
+
+ @param[in] VarName The pointer to the variable name
+ @param[in, out] Instance The pointer to the IP4 config2 instance data.
+
+ @retval EFI_NOT_FOUND The variable can not be found or already
corrupted.
+ @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the
operation.
+ @retval EFI_SUCCESS The configuration data was retrieved
successfully.
+
+**/
+EFI_STATUS
+Ip4Config2ReadConfigData (
+ IN CHAR16 *VarName,
+ IN OUT IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ EFI_STATUS Status;
+ UINTN VarSize;
+ IP4_CONFIG2_VARIABLE *Variable;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+ UINTN Index;
+ IP4_CONFIG2_DATA_RECORD DataRecord;
+ CHAR8 *Data;
+
+ //
+ // Try to read the configuration variable.
+ //
+ VarSize = 0;
+ Status = gRT->GetVariable (
+ VarName,
+ &gEfiIp4Config2ProtocolGuid,
+ NULL,
+ &VarSize,
+ NULL
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // Allocate buffer and read the config variable.
+ //
+ Variable = AllocatePool (VarSize);
+ if (Variable == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable (
+ VarName,
+ &gEfiIp4Config2ProtocolGuid,
+ NULL,
+ &VarSize,
+ Variable
+ );
+ if (EFI_ERROR (Status) || (UINT16) (~NetblockChecksum ((UINT8 *) Variable,
(UINT32) VarSize)) != 0) {
+ //
+ // GetVariable still error or the variable is corrupted.
+ // Fall back to the default value.
+ //
+ FreePool (Variable);
+
+ //
+ // Remove the problematic variable and return EFI_NOT_FOUND, a new
+ // variable will be set again.
+ //
+ gRT->SetVariable (
+ VarName,
+ &gEfiIp4Config2ProtocolGuid,
+ IP4_CONFIG2_VARIABLE_ATTRIBUTE,
+ 0,
+ NULL
+ );
+
+ return EFI_NOT_FOUND;
+ }
+
+
+ for (Index = 0; Index < Variable->DataRecordCount; Index++) {
+
+ CopyMem (&DataRecord, &Variable->DataRecord[Index], sizeof (DataRecord));
+
+ DataItem = &Instance->DataItem[DataRecord.DataType];
+ if (DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED) &&
+ (DataItem->DataSize != DataRecord.DataSize)
+ ) {
+ //
+ // Perhaps a corrupted data record...
+ //
+ continue;
+ }
+
+ if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) {
+ //
+ // This data item has variable length data.
+ //
+ DataItem->Data.Ptr = AllocatePool (DataRecord.DataSize);
+ if (DataItem->Data.Ptr == NULL) {
+ //
+ // no memory resource
+ //
+ continue;
+ }
+ }
+
+ Data = (CHAR8 *) Variable + DataRecord.Offset;
+ CopyMem (DataItem->Data.Ptr, Data, DataRecord.DataSize);
+
+ DataItem->DataSize = DataRecord.DataSize;
+ DataItem->Status = EFI_SUCCESS;
+ }
+
+ FreePool (Variable);
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+/**
+ Write the configuration data from IP4_CONFIG2_INSTANCE to variable storage.
+
+ @param[in] VarName The pointer to the variable name.
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+
+ @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the
operation.
+ @retval EFI_SUCCESS The configuration data is written successfully.
+
+**/
+EFI_STATUS
+Ip4Config2WriteConfigData (
+ IN CHAR16 *VarName,
+ IN IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ UINTN Index;
+ UINTN VarSize;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+ IP4_CONFIG2_VARIABLE *Variable;
+ IP4_CONFIG2_DATA_RECORD *DataRecord;
+ CHAR8 *Heap;
+ EFI_STATUS Status;
+
+ VarSize = sizeof (IP4_CONFIG2_VARIABLE) - sizeof (IP4_CONFIG2_DATA_RECORD);
+
+ for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {
+
+ DataItem = &Instance->DataItem[Index];
+ if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) &&
!EFI_ERROR (DataItem->Status)) {
+
+ VarSize += sizeof (IP4_CONFIG2_DATA_RECORD) + DataItem->DataSize;
+ }
+ }
+
+ Variable = AllocatePool (VarSize);
+ if (Variable == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Heap = (CHAR8 *) Variable + VarSize;
+ Variable->DataRecordCount = 0;
+
+ for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {
+
+ DataItem = &Instance->DataItem[Index];
+ if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) &&
!EFI_ERROR (DataItem->Status)) {
+
+ Heap -= DataItem->DataSize;
+ CopyMem (Heap, DataItem->Data.Ptr, DataItem->DataSize);
+
+ DataRecord = &Variable->DataRecord[Variable->DataRecordCount];
+ DataRecord->DataType = (EFI_IP4_CONFIG2_DATA_TYPE) Index;
+ DataRecord->DataSize = (UINT32) DataItem->DataSize;
+ DataRecord->Offset = (UINT16) (Heap - (CHAR8 *) Variable);
+
+ Variable->DataRecordCount++;
+ }
+ }
+
+ Variable->Checksum = 0;
+ Variable->Checksum = (UINT16) ~NetblockChecksum ((UINT8 *) Variable,
(UINT32) VarSize);
+
+ Status = gRT->SetVariable (
+ VarName,
+ &gEfiIp4Config2ProtocolGuid,
+ IP4_CONFIG2_VARIABLE_ATTRIBUTE,
+ VarSize,
+ Variable
+ );
+
+ FreePool (Variable);
+
+ return Status;
+}
+
+
+/**
+ Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of GetModeData.
+ The EFI_IP4_ROUTE_TABLE is clumsy to use in the internal operation of the
+ IP4 driver.
+
+ @param[in] IpSb The IP4 service binding instance.
+ @param[out] Table The built IP4 route table.
+
+ @retval EFI_SUCCESS The route table is successfully build
+ @retval EFI_NOT_FOUND Failed to allocate the memory for the rotue
table.
+
+**/
+EFI_STATUS
+Ip4Config2BuildDefaultRouteTable (
+ IN IP4_SERVICE *IpSb,
+ OUT EFI_IP4_ROUTE_TABLE *Table
+ )
+{
+ LIST_ENTRY *Entry;
+ IP4_ROUTE_ENTRY *RtEntry;
+ UINT32 Count;
+ INT32 Index;
+
+ if (IpSb->DefaultRouteTable == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Count = IpSb->DefaultRouteTable->TotalNum;
+
+ if (Count == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Copy the route entry to EFI route table. Keep the order of
+ // route entry copied from most specific to default route. That
+ // is, interlevel the route entry from the instance's route area
+ // and those from the default route table's route area.
+ //
+ Count = 0;
+
+ for (Index = IP4_MASK_NUM - 1; Index >= 0; Index--) {
+
+ NET_LIST_FOR_EACH (Entry, &(IpSb->DefaultRouteTable->RouteArea[Index])) {
+ RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);
+
+ EFI_IP4 (Table[Count].SubnetAddress) = HTONL (RtEntry->Dest &
RtEntry->Netmask);
+ EFI_IP4 (Table[Count].SubnetMask) = HTONL (RtEntry->Netmask);
+ EFI_IP4 (Table[Count].GatewayAddress) = HTONL (RtEntry->NextHop);
+
+ Count++;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The event process routine when the DHCPv4 service binding protocol is
installed
+ in the system.
+
+ @param[in] Event Not used.
+ @param[in] Context The pointer to the IP4 config2 instance data.
+
+**/
+VOID
+EFIAPI
+Ip4Config2OnDhcp4SbInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ IP4_CONFIG2_INSTANCE *Instance;
+
+ Instance = (IP4_CONFIG2_INSTANCE *) Context;
+
+ if ((Instance->Dhcp4Handle != NULL) || (Instance->Policy !=
Ip4Config2PolicyDhcp)) {
+ //
+ // The DHCP4 child is already created or the policy is no longer DHCP.
+ //
+ return ;
+ }
+
+ Ip4StartAutoConfig (Instance);
+}
+
+/**
+ Set the station address and subnetmask for the default interface.
+
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in] StationAddress Ip address to be set.
+ @param[in] SubnetMask Subnet to be set.
+
+ @retval EFI_SUCCESS Set default address successful.
+ @retval Others Some errors occur in setting.
+
+**/
+EFI_STATUS
+Ip4Config2SetDefaultAddr (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN IP4_ADDR StationAddress,
+ IN IP4_ADDR SubnetMask
+ )
+{
+ EFI_STATUS Status;
+ IP4_SERVICE *IpSb;
+ IP4_INTERFACE *IpIf;
+ IP4_PROTOCOL *Ip4Instance;
+ EFI_ARP_PROTOCOL *Arp;
+ LIST_ENTRY *Entry;
+ IP4_ADDR Subnet;
+ IP4_ROUTE_TABLE *RouteTable;
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+ IpIf = IpSb->DefaultInterface;
+ ASSERT (IpIf != NULL);
+
+ if ((IpIf->Ip == StationAddress) && (IpIf->SubnetMask == SubnetMask)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // The default address is changed, free the previous interface first.
+ //
+ if (IpSb->DefaultRouteTable != NULL) {
+ Ip4FreeRouteTable (IpSb->DefaultRouteTable);
+ IpSb->DefaultRouteTable = NULL;
+ }
+
+ Ip4CancelReceive (IpSb->DefaultInterface);
+ Ip4FreeInterface (IpSb->DefaultInterface, NULL);
+ IpSb->DefaultInterface = NULL;
+ //
+ // Create new default interface and route table.
+ //
+ IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image);
+ if (IpIf == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RouteTable = Ip4CreateRouteTable ();
+ if (RouteTable == NULL) {
+ Ip4FreeInterface (IpIf, NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ IpSb->DefaultInterface = IpIf;
+ InsertHeadList (&IpSb->Interfaces, &IpIf->Link);
+ IpSb->DefaultRouteTable = RouteTable;
+ Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb);
+
+ if (IpSb->State == IP4_SERVICE_CONFIGED) {
+ IpSb->State = IP4_SERVICE_UNSTARTED;
+ }
+
+ Status = Ip4SetAddress (IpIf, StationAddress, SubnetMask);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (IpIf->Arp != NULL) {
+ //
+ // A non-NULL IpIf->Arp here means a new ARP child is created when setting
default address,
+ // but some IP children may have referenced the default interface before
it is configured,
+ // these IP instances also consume this ARP protocol so they need to open
it BY_CHILD_CONTROLLER.
+ //
+ Arp = NULL;
+ NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
+ Ip4Instance = NET_LIST_USER_STRUCT_S (Entry, IP4_PROTOCOL, AddrLink,
IP4_PROTOCOL_SIGNATURE);
+ Status = gBS->OpenProtocol (
+ IpIf->ArpHandle,
+ &gEfiArpProtocolGuid,
+ (VOID **) &Arp,
+ gIp4DriverBinding.DriverBindingHandle,
+ Ip4Instance->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ }
+
+ Ip4AddRoute (
+ IpSb->DefaultRouteTable,
+ StationAddress,
+ SubnetMask,
+ IP4_ALLZERO_ADDRESS
+ );
+
+ //
+ // Add a route for the connected network.
+ //
+ Subnet = StationAddress & SubnetMask;
+
+ Ip4AddRoute (
+ IpSb->DefaultRouteTable,
+ Subnet,
+ SubnetMask,
+ IP4_ALLZERO_ADDRESS
+ );
+
+ IpSb->State = IP4_SERVICE_CONFIGED;
+ return EFI_SUCCESS;
+}
+
+/**
+ Set the station address, subnetmask and gateway address for the default
interface.
+
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in] StationAddress Ip address to be set.
+ @param[in] SubnetMask Subnet to be set.
+ @param[in] GatewayAddress Gateway to be set.
+
+ @retval EFI_SUCCESS Set default If successful.
+ @retval Others Errors occur as indicated.
+
+**/
+EFI_STATUS
+Ip4Config2SetDefaultIf (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN IP4_ADDR StationAddress,
+ IN IP4_ADDR SubnetMask,
+ IN IP4_ADDR GatewayAddress
+ )
+{
+ EFI_STATUS Status;
+ IP4_SERVICE *IpSb;
+
+ Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Create a route if there is a default router.
+ //
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+ if (GatewayAddress != IP4_ALLZERO_ADDRESS) {
+ Ip4AddRoute (
+ IpSb->DefaultRouteTable,
+ IP4_ALLZERO_ADDRESS,
+ IP4_ALLZERO_ADDRESS,
+ GatewayAddress
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Release all the DHCP related resources.
+
+ @param Instance The IP4 config2 instance.
+
+ @return None
+
+**/
+VOID
+Ip4Config2CleanDhcp4 (
+ IN IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ IP4_SERVICE *IpSb;
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+
+ if (Instance->Dhcp4 != NULL) {
+ Instance->Dhcp4->Stop (Instance->Dhcp4);
+
+ gBS->CloseProtocol (
+ Instance->Dhcp4Handle,
+ &gEfiDhcp4ProtocolGuid,
+ IpSb->Image,
+ IpSb->Controller
+ );
+
+ Instance->Dhcp4 = NULL;
+ }
+
+ if (Instance->Dhcp4Handle != NULL) {
+ NetLibDestroyServiceChild (
+ IpSb->Controller,
+ IpSb->Image,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ Instance->Dhcp4Handle
+ );
+
+ Instance->Dhcp4Handle = NULL;
+ }
+
+ if (Instance->Dhcp4Event != NULL) {
+ gBS->CloseEvent (Instance->Dhcp4Event);
+ Instance->Dhcp4Event = NULL;
+ }
+}
+
+
+/**
+ Callback function when DHCP process finished. It will save the
+ retrieved IP configure parameter from DHCP to the NVRam.
+
+ @param Event The callback event
+ @param Context Opaque context to the callback
+
+ @return None
+
+**/
+VOID
+EFIAPI
+Ip4Config2OnDhcp4Complete (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ IP4_CONFIG2_INSTANCE *Instance;
+ EFI_DHCP4_MODE_DATA Dhcp4Mode;
+ EFI_STATUS Status;
+ IP4_ADDR StationAddress;
+ IP4_ADDR SubnetMask;
+ IP4_ADDR GatewayAddress;
+
+ Instance = (IP4_CONFIG2_INSTANCE *) Context;
+ ASSERT (Instance->Dhcp4 != NULL);
+
+ //
+ // Get the DHCP retrieved parameters
+ //
+ Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);
+
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ if (Dhcp4Mode.State == Dhcp4Bound) {
+ StationAddress = EFI_NTOHL (Dhcp4Mode.ClientAddress);
+ SubnetMask = EFI_NTOHL (Dhcp4Mode.SubnetMask);
+ GatewayAddress = EFI_NTOHL (Dhcp4Mode.RouterAddress);
+
+ Status = Ip4Config2SetDefaultIf (Instance, StationAddress, SubnetMask,
GatewayAddress);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Instance->DhcpSuccess = TRUE;
+ }
+
+Exit:
+ Ip4Config2CleanDhcp4 (Instance);
+ DispatchDpc ();
+}
+
+
+/**
+ Start the DHCP configuration for this IP service instance.
+ It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the
+ DHCP configuration.
+
+ @param[in] Instance The IP4 config2 instance to configure
+
+ @retval EFI_SUCCESS The auto configuration is successfull started
+ @retval Others Failed to start auto configuration.
+
+**/
+EFI_STATUS
+Ip4StartAutoConfig (
+ IN IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ IP4_SERVICE *IpSb;
+ EFI_DHCP4_PROTOCOL *Dhcp4;
+ EFI_DHCP4_MODE_DATA Dhcp4Mode;
+ EFI_DHCP4_PACKET_OPTION *OptionList[1];
+ IP4_CONFIG2_DHCP4_OPTION ParaList;
+ EFI_STATUS Status;
+
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+
+ if (IpSb->State > IP4_SERVICE_UNSTARTED) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // A host must not invoke DHCP configuration if it is already
+ // participating in the DHCP configuraiton process.
+ //
+ if (Instance->Dhcp4Handle != NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = NetLibCreateServiceChild (
+ IpSb->Controller,
+ IpSb->Image,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ &Instance->Dhcp4Handle
+ );
+
+ if (Status == EFI_UNSUPPORTED) {
+ //
+ // No DHCPv4 Service Binding protocol, register a notify.
+ //
+ if (Instance->Dhcp4SbNotifyEvent == NULL) {
+ Instance->Dhcp4SbNotifyEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ TPL_CALLBACK,
+ Ip4Config2OnDhcp4SbInstalled,
+ (VOID *) Instance,
+ &Instance->Registration
+ );
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Instance->Dhcp4SbNotifyEvent != NULL) {
+ gBS->CloseEvent (Instance->Dhcp4SbNotifyEvent);
+ }
+
+ Status = gBS->OpenProtocol (
+ Instance->Dhcp4Handle,
+ &gEfiDhcp4ProtocolGuid,
+ (VOID **) &Instance->Dhcp4,
+ IpSb->Image,
+ IpSb->Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Check the current DHCP status, if the DHCP process has
+ // already finished, return now.
+ //
+ Dhcp4 = Instance->Dhcp4;
+ Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);
+
+ if (Dhcp4Mode.State == Dhcp4Bound) {
+ Ip4Config2OnDhcp4Complete (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)) {
+ return Status;
+ }
+
+ //
+ // Start the DHCP process
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ Ip4Config2OnDhcp4Complete,
+ Instance,
+ &Instance->Dhcp4Event
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ IpSb->State = IP4_SERVICE_STARTED;
+ DispatchDpc ();
+ return EFI_SUCCESS;
+
+}
+
+
+
+/**
+ The work function is to get the interface information of the communication
+ device this IP4_CONFIG2_INSTANCE manages.
+
+ @param[in] Instance Pointer to the IP4 config2 instance data.
+ @param[in, out] DataSize On input, in bytes, the size of Data. On output, in
+ bytes, the size of buffer required to store the
specified
+ configuration data.
+ @param[in] Data The data buffer in which the configuration data is
returned.
+ Ignored if DataSize is ZERO.
+
+ @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified
+ configuration data, and the required size is
+ returned in DataSize.
+ @retval EFI_SUCCESS The specified configuration data was obtained.
+
+**/
+EFI_STATUS
+Ip4Config2GetIfInfo (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN OUT UINTN *DataSize,
+ IN VOID *Data OPTIONAL
+ )
+{
+
+ IP4_SERVICE *IpSb;
+ UINTN Length;
+ IP4_CONFIG2_DATA_ITEM *Item;
+ EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;
+ IP4_ADDR Address;
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+ Length = sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO);
+
+ if (IpSb->DefaultRouteTable != NULL) {
+ Length += IpSb->DefaultRouteTable->TotalNum * sizeof (EFI_IP4_ROUTE_TABLE);
+ }
+
+ if (*DataSize < Length) {
+ *DataSize = Length;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Copy the fixed size part of the interface info.
+ //
+ Item = &Instance->DataItem[Ip4Config2DataTypeInterfaceInfo];
+ IfInfo = (EFI_IP4_CONFIG2_INTERFACE_INFO *) Data;
+ CopyMem (IfInfo, Item->Data.Ptr, sizeof (EFI_IP4_CONFIG2_INTERFACE_INFO));
+
+ //
+ // Update the address info.
+ //
+ if (IpSb->DefaultInterface != NULL) {
+ Address = HTONL (IpSb->DefaultInterface->Ip);
+ CopyMem (&IfInfo->StationAddress, &Address, sizeof (EFI_IPv4_ADDRESS));
+ Address = HTONL (IpSb->DefaultInterface->SubnetMask);
+ CopyMem (&IfInfo->SubnetMask, &Address, sizeof (EFI_IPv4_ADDRESS));
+ }
+
+ if (IpSb->DefaultRouteTable != NULL) {
+ IfInfo->RouteTableSize = IpSb->DefaultRouteTable->TotalNum;
+ IfInfo->RouteTable = (EFI_IP4_ROUTE_TABLE *) ((UINT8 *) Data + sizeof
(EFI_IP4_CONFIG2_INTERFACE_INFO));
+
+ Ip4Config2BuildDefaultRouteTable (IpSb, IfInfo->RouteTable);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The work function is to set the general configuration policy for the EFI
IPv4 network
+ stack that is running on the communication device managed by this
IP4_CONFIG2_INSTANCE.
+ The policy will affect other configuration settings.
+
+ @param[in] Instance Pointer to the IP4 config2 instance data.
+ @param[in] DataSize Size of the buffer pointed to by Data in bytes.
+ @param[in] Data The data buffer to set.
+
+ @retval EFI_INVALID_PARAMETER The to be set policy is invalid.
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the
type.
+ @retval EFI_ABORTED The new policy equals the current policy.
+ @retval EFI_SUCCESS The specified configuration data for the EFI
IPv6
+ network stack was set.
+
+**/
+EFI_STATUS
+Ip4Config2SetPolicy (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_IP4_CONFIG2_POLICY NewPolicy;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+ IP4_SERVICE *IpSb;
+
+ if (DataSize != sizeof (EFI_IP4_CONFIG2_POLICY)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NewPolicy = *((EFI_IP4_CONFIG2_POLICY *) Data);
+
+ if (NewPolicy >= Ip4Config2PolicyMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (NewPolicy == Instance->Policy) {
+ if (NewPolicy != Ip4Config2PolicyDhcp || Instance->DhcpSuccess) {
+ return EFI_ABORTED;
+ }
+
+ } else {
+ if (NewPolicy == Ip4Config2PolicyDhcp) {
+ //
+ // The policy is changed from static to dhcp:
+ // Clean the ManualAddress, Gateway and DnsServers, shrink the variable
+ // data size, and fire up all the related events.
+ //
+ DataItem =
&Instance->DataItem[Ip4Config2DataTypeManualAddress];
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ DataItem->Status = EFI_NOT_FOUND;
+ NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
+
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ DataItem->Status = EFI_NOT_FOUND;
+ NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
+
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ DataItem->Status = EFI_NOT_FOUND;
+ NetMapIterate (&DataItem->EventMap, Ip4Config2SignalEvent, NULL);
+ } else {
+ //
+ // The policy is changed from dhcp to static. Stop the DHCPv4 process
+ // and destroy the DHCPv4 child.
+ //
+ if (Instance->Dhcp4Handle != NULL) {
+ Ip4Config2DestroyDhcp4 (Instance);
+ }
+
+ //
+ // Close the event.
+ //
+ if (Instance->Dhcp4Event != NULL) {
+ gBS->CloseEvent (Instance->Dhcp4Event);
+ }
+ }
+ }
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+ Ip4Config2OnPolicyChanged (IpSb, NewPolicy);
+
+ Instance->Policy = NewPolicy;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The work function is to set the station addresses manually for the EFI IPv4
+ network stack. It is only configurable when the policy is
Ip4Config2PolicyStatic.
+
+ @param[in] Instance Pointer to the IP4 config2 instance data.
+ @param[in] DataSize Size of the buffer pointed to by Data in bytes.
+ @param[in] Data The data buffer to set.
+
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the
type.
+ @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
+ under the current policy.
+ @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
+ @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the
operation.
+ @retval EFI_NOT_READY An asynchrous process is invoked to set the
specified
+ configuration data, and the process is not
finished.
+ @retval EFI_ABORTED The manual addresses to be set equal current
+ configuration.
+ @retval EFI_SUCCESS The specified configuration data for the EFI
IPv6
+ network stack was set.
+
+**/
+EFI_STATUS
+Ip4Config2SetMaunualAddress (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_IP4_CONFIG2_MANUAL_ADDRESS NewAddress;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+ EFI_STATUS Status;
+ IP4_ADDR StationAddress;
+ IP4_ADDR SubnetMask;
+ VOID *Ptr;
+
+ ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status !=
EFI_NOT_READY);
+
+ if (((DataSize % sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS)) != 0) || (DataSize
== 0)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (Instance->Policy != Ip4Config2PolicyStatic) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+ NewAddress = *((EFI_IP4_CONFIG2_MANUAL_ADDRESS *) Data);
+
+ //
+ // Store the new data, and init the DataItem status to EFI_NOT_READY because
+ // we may have an asynchronous configuration process.
+ //
+ Ptr = AllocateCopyPool (DataSize, Data);
+ if (Ptr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+
+ DataItem->Data.Ptr = Ptr;
+ DataItem->DataSize = DataSize;
+ DataItem->Status = EFI_NOT_READY;
+
+ StationAddress = EFI_NTOHL (NewAddress.Address);
+ SubnetMask = EFI_NTOHL (NewAddress.SubnetMask);
+
+ Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ DataItem->Status = EFI_SUCCESS;
+
+ON_EXIT:
+ if (EFI_ERROR (DataItem->Status)) {
+ if (Ptr != NULL) {
+ FreePool (Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The work function is to set the gateway addresses manually for the EFI IPv4
+ network stack that is running on the communication device that this EFI IPv4
+ Configuration Protocol manages. It is not configurable when the policy is
+ Ip4Config2PolicyDhcp. The gateway addresses must be unicast IPv4 addresses.
+
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in] DataSize The size of the buffer pointed to by Data in bytes.
+ @param[in] Data The data buffer to set. This points to an array of
+ EFI_IPv6_ADDRESS instances.
+
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the
type.
+ @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
+ under the current policy.
+ @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to complete the
operation.
+ @retval EFI_ABORTED The manual gateway addresses to be set equal
the
+ current configuration.
+ @retval EFI_SUCCESS The specified configuration data for the EFI
IPv6
+ network stack was set.
+
+**/
+EFI_STATUS
+Ip4Config2SetGateway (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ IP4_SERVICE *IpSb;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+ IP4_ADDR Gateway;
+
+ UINTN Index1;
+ UINTN Index2;
+ EFI_IPv4_ADDRESS *OldGateway;
+ EFI_IPv4_ADDRESS *NewGateway;
+ UINTN OldGatewayCount;
+ UINTN NewGatewayCount;
+ BOOLEAN OneRemoved;
+ BOOLEAN OneAdded;
+ VOID *Tmp;
+
+ if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (Instance->Policy != Ip4Config2PolicyStatic) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+
+ NewGateway = (EFI_IPv4_ADDRESS *) Data;
+ NewGatewayCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
+ for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+ CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
+
+ if (!NetIp4IsUnicast (NTOHL (Gateway), 0)) {
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) {
+ if (EFI_IP4_EQUAL (NewGateway + Index1, NewGateway + Index2)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
+ OldGateway = DataItem->Data.Gateway;
+ OldGatewayCount = DataItem->DataSize / sizeof (EFI_IPv4_ADDRESS);
+ OneRemoved = FALSE;
+ OneAdded = FALSE;
+
+ if (NewGatewayCount != OldGatewayCount) {
+ Tmp = AllocatePool (DataSize);
+ if (Tmp == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ Tmp = NULL;
+ }
+
+ for (Index1 = 0; Index1 < OldGatewayCount; Index1++) {
+ //
+ // Remove this route entry.
+ //
+ CopyMem (&Gateway, OldGateway + Index1, sizeof (IP4_ADDR));
+ Ip4DelRoute (
+ IpSb->DefaultRouteTable,
+ IP4_ALLZERO_ADDRESS,
+ IP4_ALLZERO_ADDRESS,
+ NTOHL (Gateway)
+ );
+ OneRemoved = TRUE;
+
+ }
+
+ for (Index1 = 0; Index1 < NewGatewayCount; Index1++) {
+ CopyMem (&Gateway, NewGateway + Index1, sizeof (IP4_ADDR));
+ Ip4AddRoute (
+ IpSb->DefaultRouteTable,
+ IP4_ALLZERO_ADDRESS,
+ IP4_ALLZERO_ADDRESS,
+ NTOHL (Gateway)
+ );
+
+ OneAdded = TRUE;
+ }
+
+
+ if (!OneRemoved && !OneAdded) {
+ DataItem->Status = EFI_SUCCESS;
+ return EFI_ABORTED;
+ } else {
+
+ if (Tmp != NULL) {
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = Tmp;
+ }
+
+ CopyMem (DataItem->Data.Ptr, Data, DataSize);
+ DataItem->DataSize = DataSize;
+ DataItem->Status = EFI_SUCCESS;
+ return EFI_SUCCESS;
+ }
+
+}
+
+/**
+ The work function is to set the DNS server list for the EFI IPv4 network
+ stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL
+ manages. It is not configurable when the policy is Ip4Config2PolicyDhcp.
+ The DNS server addresses must be unicast IPv4 addresses.
+
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in] DataSize The size of the buffer pointed to by Data in bytes.
+ @param[in] Data The data buffer to set, points to an array of
+ EFI_IPv4_ADDRESS instances.
+
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the
type.
+ @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set
+ under the current policy.
+ @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the
operation.
+ @retval EFI_ABORTED The DNS server addresses to be set equal the
current
+ configuration.
+ @retval EFI_SUCCESS The specified configuration data for the EFI
IPv4
+ network stack was set.
+
+**/
+EFI_STATUS
+Ip4Config2SetDnsServer (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ UINTN OldIndex;
+ UINTN NewIndex;
+ UINTN Index1;
+ EFI_IPv4_ADDRESS *OldDns;
+ EFI_IPv4_ADDRESS *NewDns;
+ UINTN OldDnsCount;
+ UINTN NewDnsCount;
+ IP4_CONFIG2_DATA_ITEM *Item;
+ BOOLEAN OneAdded;
+ VOID *Tmp;
+ IP4_ADDR DnsAddress;
+
+ if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (Instance->Policy != Ip4Config2PolicyStatic) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+ Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
+ NewDns = (EFI_IPv4_ADDRESS *) Data;
+ OldDns = Item->Data.DnsServers;
+ NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
+ OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);
+ OneAdded = FALSE;
+
+ if (NewDnsCount != OldDnsCount) {
+ Tmp = AllocatePool (DataSize);
+ if (Tmp == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ Tmp = NULL;
+ }
+
+ for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {
+ CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));
+
+ if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {
+ //
+ // The dns server address must be unicast.
+ //
+ FreePool (Tmp);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {
+ if (EFI_IP4_EQUAL (NewDns + NewIndex, NewDns + Index1)) {
+ FreePool (Tmp);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (OneAdded) {
+ //
+ // If any address in the new setting is not in the old settings, skip the
+ // comparision below.
+ //
+ continue;
+ }
+
+ for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {
+ if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {
+ //
+ // If found break out.
+ //
+ break;
+ }
+ }
+
+ if (OldIndex == OldDnsCount) {
+ OneAdded = TRUE;
+ }
+ }
+
+ if (!OneAdded && (DataSize == Item->DataSize)) {
+ //
+ // No new item is added and the size is the same.
+ //
+ Item->Status = EFI_SUCCESS;
+ return EFI_ABORTED;
+ } else {
+ if (Tmp != NULL) {
+ if (Item->Data.Ptr != NULL) {
+ FreePool (Item->Data.Ptr);
+ }
+ Item->Data.Ptr = Tmp;
+ }
+
+ CopyMem (Item->Data.Ptr, Data, DataSize);
+ Item->DataSize = DataSize;
+ Item->Status = EFI_SUCCESS;
+ return EFI_SUCCESS;
+ }
+
+}
+
+/**
+ Generate the operational state of the interface this IP4 config2 instance
manages
+ and output in EFI_IP4_CONFIG2_INTERFACE_INFO.
+
+ @param[in] IpSb The pointer to the IP4 service binding instance.
+ @param[out] IfInfo The pointer to the IP4 config2 interface
information structure.
+
+**/
+VOID
+Ip4Config2InitIfInfo (
+ IN IP4_SERVICE *IpSb,
+ OUT EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo
+ )
+{
+ IfInfo->Name[0] = L'e';
+ IfInfo->Name[1] = L't';
+ IfInfo->Name[2] = L'h';
+ IfInfo->Name[3] = (CHAR16) (L'0' + IpSb->Ip4Config2Instance.IfIndex);
+ IfInfo->Name[4] = 0;
+
+ IfInfo->IfType = IpSb->SnpMode.IfType;
+ IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize;
+ CopyMem (&IfInfo->HwAddress, &IpSb->SnpMode.CurrentAddress,
IfInfo->HwAddressSize);
+}
+
+/**
+ The event handle routine when DHCPv4 process is finished or is updated.
+
+ @param[in] Event Not used.
+ @param[in] Context The pointer to the IP4 configuration instance
data.
+
+**/
+VOID
+EFIAPI
+Ip4Config2OnDhcp4Event (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return ;
+}
+
+
+/**
+ Set the configuration for the EFI IPv4 network stack running on the
communication
+ device this EFI_IP4_CONFIG2_PROTOCOL instance manages.
+
+ This function is used to set the configuration data of type DataType for the
EFI
+ IPv4 network stack that is running on the communication device that this EFI
IPv4
+ Configuration Protocol instance manages.
+
+ DataSize is used to calculate the count of structure instances in the Data
for
+ a DataType in which multiple structure instances are allowed.
+
+ This function is always non-blocking. When setting some type of
configuration data,
+ an asynchronous process is invoked to check the correctness of the data,
such as
+ performing Duplicate Address Detection on the manually set local IPv4
addresses.
+ EFI_NOT_READY is returned immediately to indicate that such an asynchronous
process
+ is invoked, and the process is not finished yet. The caller wanting to get
the result
+ of the asynchronous process is required to call RegisterDataNotify() to
register an
+ event on the specified configuration data. Once the event is signaled, the
caller
+ can call GetData() to obtain the configuration data and know the result.
+ For other types of configuration data that do not require an asynchronous
configuration
+ process, the result of the operation is immediately returned.
+
+ @param[in] This The pointer to the EFI_IP4_CONFIG2_PROTOCOL
instance.
+ @param[in] DataType The type of data to set.
+ @param[in] DataSize Size of the buffer pointed to by Data in bytes.
+ @param[in] Data The data buffer to set. The type of the data
buffer is
+ associated with the DataType.
+
+ @retval EFI_SUCCESS The specified configuration data for the EFI
IPv6
+ network stack was set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
+ - This is NULL.
+ - Data is NULL.
+ - One or more fields in Data do not match the
requirement of the
+ data type indicated by DataType.
+ @retval EFI_WRITE_PROTECTED The specified configuration data is read-only
or the specified
+ configuration data cannot be set under the
current policy.
+ @retval EFI_ACCESS_DENIED Another set operation on the specified
configuration
+ data is already in process.
+ @retval EFI_NOT_READY An asynchronous process was invoked to set the
specified
+ configuration data, and the process is not
finished yet.
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the
type
+ indicated by DataType.
+ @retval EFI_UNSUPPORTED This DataType is not supported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be
allocated.
+ @retval EFI_DEVICE_ERROR An unexpected system error or network error
occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+EfiIp4Config2SetData (
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ IP4_CONFIG2_INSTANCE *Instance;
+ IP4_SERVICE *IpSb;
+
+ if ((This == NULL) || (Data == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DataType >= Ip4Config2DataTypeMaximum) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+ NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);
+
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Status = Instance->DataItem[DataType].Status;
+ if (Status != EFI_NOT_READY) {
+
+ if (Instance->DataItem[DataType].SetData == NULL) {
+ //
+ // This type of data is readonly.
+ //
+ Status = EFI_WRITE_PROTECTED;
+ } else {
+
+ Status = Instance->DataItem[DataType].SetData (Instance, DataSize, Data);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Fire up the events registered with this type of data.
+ //
+ NetMapIterate (&Instance->DataItem[DataType].EventMap,
Ip4Config2SignalEvent, NULL);
+ Ip4Config2WriteConfigData (IpSb->MacString, Instance);
+ } else if (Status == EFI_ABORTED) {
+ //
+ // The SetData is aborted because the data to set is the same with
+ // the one maintained.
+ //
+ Status = EFI_SUCCESS;
+ NetMapIterate (&Instance->DataItem[DataType].EventMap,
Ip4Config2SignalEvent, NULL);
+ }
+ }
+ } else {
+ //
+ // Another asynchornous process is on the way.
+ //
+ Status = EFI_ACCESS_DENIED;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Get the configuration data for the EFI IPv4 network stack running on the
communication
+ device that this EFI_IP4_CONFIG2_PROTOCOL instance manages.
+
+ This function returns the configuration data of type DataType for the EFI
IPv4 network
+ stack running on the communication device that this EFI IPv4 Configuration
Protocol instance
+ manages.
+
+ The caller is responsible for allocating the buffer used to return the
specified
+ configuration data. The required size will be returned to the caller if the
size of
+ the buffer is too small.
+
+ EFI_NOT_READY is returned if the specified configuration data is not ready
due to an
+ asynchronous configuration process already in progress. The caller can call
RegisterDataNotify()
+ to register an event on the specified configuration data. Once the
asynchronous configuration
+ process is finished, the event will be signaled, and a subsequent GetData()
call will return
+ the specified configuration data.
+
+ @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL
instance.
+ @param[in] DataType The type of data to get.
+ @param[in, out] DataSize On input, in bytes, the size of Data. On
output, in bytes, the
+ size of buffer required to store the
specified configuration data.
+ @param[in] Data The data buffer in which the configuration
data is returned. The
+ type of the data buffer is associated with
the DataType.
+ This is an optional parameter that may be
NULL.
+
+ @retval EFI_SUCCESS The specified configuration data was obtained
successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
+ - This is NULL.
+ - DataSize is NULL.
+ - Data is NULL if *DataSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the
specified configuration data,
+ and the required size is returned in DataSize.
+ @retval EFI_NOT_READY The specified configuration data is not ready
due to an
+ asynchronous configuration process already in
progress.
+ @retval EFI_NOT_FOUND The specified configuration data is not found.
+
+**/
+EFI_STATUS
+EFIAPI
+EfiIp4Config2GetData (
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN VOID *Data OPTIONAL
+ )
+{
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ IP4_CONFIG2_INSTANCE *Instance;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+
+ if ((This == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data ==
NULL))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DataType >= Ip4Config2DataTypeMaximum) {
+ return EFI_NOT_FOUND;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);
+ DataItem = &Instance->DataItem[DataType];
+
+ Status = Instance->DataItem[DataType].Status;
+ if (!EFI_ERROR (Status)) {
+
+ if (DataItem->GetData != NULL) {
+
+ Status = DataItem->GetData (Instance, DataSize, Data);
+ } else if (*DataSize < Instance->DataItem[DataType].DataSize) {
+ //
+ // Update the buffer length.
+ //
+ *DataSize = Instance->DataItem[DataType].DataSize;
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+
+ *DataSize = Instance->DataItem[DataType].DataSize;
+ CopyMem (Data, Instance->DataItem[DataType].Data.Ptr, *DataSize);
+ }
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Register an event that is signaled whenever a configuration process on the
specified
+ configuration data is done.
+
+ This function registers an event that is to be signaled whenever a
configuration
+ process on the specified configuration data is performed. An event can be
registered
+ for a different DataType simultaneously. The caller is responsible for
determining
+ which type of configuration data causes the signaling of the event in such
an event.
+
+ @param[in] This Pointer to the EFI_IP4_CONFIG2_PROTOCOL
instance.
+ @param[in] DataType The type of data to unregister the event for.
+ @param[in] Event The event to register.
+
+ @retval EFI_SUCCESS The notification event for the specified
configuration data is
+ registered.
+ @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
+ @retval EFI_UNSUPPORTED The configuration data type specified by
DataType is not
+ supported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be
allocated.
+ @retval EFI_ACCESS_DENIED The Event is already registered for the
DataType.
+
+**/
+EFI_STATUS
+EFIAPI
+EfiIp4Config2RegisterDataNotify (
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
+ IN EFI_EVENT Event
+ )
+{
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ IP4_CONFIG2_INSTANCE *Instance;
+ NET_MAP *EventMap;
+ NET_MAP_ITEM *Item;
+
+ if ((This == NULL) || (Event == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DataType >= Ip4Config2DataTypeMaximum) {
+ return EFI_UNSUPPORTED;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);
+ EventMap = &Instance->DataItem[DataType].EventMap;
+
+ //
+ // Check whether this event is already registered for this DataType.
+ //
+ Item = NetMapFindKey (EventMap, Event);
+ if (Item == NULL) {
+
+ Status = NetMapInsertTail (EventMap, Event, NULL);
+
+ if (EFI_ERROR (Status)) {
+
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ } else {
+
+ Status = EFI_ACCESS_DENIED;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Remove a previously registered event for the specified configuration data.
+
+ @param This The pointer to the EFI_IP4_CONFIG2_PROTOCOL
instance.
+ @param DataType The type of data to remove from the previously
+ registered event.
+ @param Event The event to be unregistered.
+
+ @retval EFI_SUCCESS The event registered for the specified
+ configuration data was removed.
+ @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
+ @retval EFI_NOT_FOUND The Event has not been registered for the
+ specified DataType.
+
+**/
+EFI_STATUS
+EFIAPI
+EfiIp4Config2UnregisterDataNotify (
+ IN EFI_IP4_CONFIG2_PROTOCOL *This,
+ IN EFI_IP4_CONFIG2_DATA_TYPE DataType,
+ IN EFI_EVENT Event
+ )
+{
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ IP4_CONFIG2_INSTANCE *Instance;
+ NET_MAP_ITEM *Item;
+
+ if ((This == NULL) || (Event == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DataType >= Ip4Config2DataTypeMaximum) {
+ return EFI_NOT_FOUND;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = IP4_CONFIG2_INSTANCE_FROM_PROTOCOL (This);
+
+ Item = NetMapFindKey (&Instance->DataItem[DataType].EventMap, Event);
+ if (Item != NULL) {
+
+ NetMapRemoveItem (&Instance->DataItem[DataType].EventMap, Item, NULL);
+ Status = EFI_SUCCESS;
+ } else {
+
+ Status = EFI_NOT_FOUND;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Initialize an IP4_CONFIG2_INSTANCE.
+
+ @param[out] Instance The buffer of IP4_CONFIG2_INSTANCE to be
initialized.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the
operation.
+ @retval EFI_SUCCESS The IP4_CONFIG2_INSTANCE initialized
successfully.
+
+**/
+EFI_STATUS
+Ip4Config2InitInstance (
+ OUT IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ IP4_SERVICE *IpSb;
+ IP4_CONFIG2_INSTANCE *TmpInstance;
+ LIST_ENTRY *Entry;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT16 IfIndex;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+
+ Instance->Signature = IP4_CONFIG2_INSTANCE_SIGNATURE;
+
+
+ //
+ // Determine the index of this interface.
+ //
+ IfIndex = 0;
+ NET_LIST_FOR_EACH (Entry, &mIp4Config2InstanceList) {
+ TmpInstance = NET_LIST_USER_STRUCT_S (Entry, IP4_CONFIG2_INSTANCE, Link,
IP4_CONFIG2_INSTANCE_SIGNATURE);
+
+ if (TmpInstance->IfIndex > IfIndex) {
+ //
+ // There is a sequence hole because some interface is down.
+ //
+ break;
+ }
+
+ IfIndex++;
+ }
+
+ Instance->IfIndex = IfIndex;
+ NetListInsertBefore (Entry, &Instance->Link);
+
+ for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {
+ //
+ // Initialize the event map for each data item.
+ //
+ NetMapInit (&Instance->DataItem[Index].EventMap);
+ }
+
+
+ //
+ // Initialize each data type: associate storage and set data size for the
+ // fixed size data types, hook the SetData function, set the data attribute.
+ //
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeInterfaceInfo];
+ DataItem->GetData = Ip4Config2GetIfInfo;
+ DataItem->Data.Ptr = &Instance->InterfaceInfo;
+ DataItem->DataSize = sizeof (Instance->InterfaceInfo);
+ SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED |
DATA_ATTRIB_VOLATILE);
+ Ip4Config2InitIfInfo (IpSb, &Instance->InterfaceInfo);
+
+ DataItem = &Instance->DataItem[Ip4Config2DataTypePolicy];
+ DataItem->SetData = Ip4Config2SetPolicy;
+ DataItem->Data.Ptr = &Instance->Policy;
+ DataItem->DataSize = sizeof (Instance->Policy);
+ Instance->Policy = Ip4Config2PolicyDhcp;
+ SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);
+
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
+ DataItem->SetData = Ip4Config2SetMaunualAddress;
+ DataItem->Status = EFI_NOT_FOUND;
+
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeGateway];
+ DataItem->SetData = Ip4Config2SetGateway;
+ DataItem->Status = EFI_NOT_FOUND;
+
+ DataItem = &Instance->DataItem[Ip4Config2DataTypeDnsServer];
+ DataItem->SetData = Ip4Config2SetDnsServer;
+ DataItem->Status = EFI_NOT_FOUND;
+
+ //
+ // Create the event used for DHCP.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ Ip4Config2OnDhcp4Event,
+ Instance,
+ &Instance->Dhcp4Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Instance->Configured = TRUE;
+
+ //
+ // Try to read the config data from NV variable.
+ //
+ Status = Ip4Config2ReadConfigData (IpSb->MacString, Instance);
+ if (Status == EFI_NOT_FOUND) {
+ Status = Ip4Config2WriteConfigData (IpSb->MacString, Instance);
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Try to set the configured parameter.
+ //
+ for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum;
Index++) {
+ DataItem = &IpSb->Ip4Config2Instance.DataItem[Index];
+ if (DataItem->Data.Ptr != NULL) {
+ DataItem->SetData (
+ &IpSb->Ip4Config2Instance,
+ DataItem->DataSize,
+ DataItem->Data.Ptr
+ );
+ }
+ }
+
+ Instance->Ip4Config2.SetData = EfiIp4Config2SetData;
+ Instance->Ip4Config2.GetData = EfiIp4Config2GetData;
+ Instance->Ip4Config2.RegisterDataNotify = EfiIp4Config2RegisterDataNotify;
+ Instance->Ip4Config2.UnregisterDataNotify =
EfiIp4Config2UnregisterDataNotify;
+
+ //
+ // Publish the IP4 configuration form
+ //
+ return Ip4Config2FormInit (Instance);
+}
+
+
+/**
+ Release an IP4_CONFIG2_INSTANCE.
+
+ @param[in, out] Instance The buffer of IP4_CONFIG2_INSTANCE to be freed.
+
+**/
+VOID
+Ip4Config2CleanInstance (
+ IN OUT IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ UINTN Index;
+ IP4_CONFIG2_DATA_ITEM *DataItem;
+
+ if (Instance->DeclineAddress != NULL) {
+ FreePool (Instance->DeclineAddress);
+ }
+
+ if (!Instance->Configured) {
+ return ;
+ }
+
+ if (Instance->Dhcp4Handle != NULL) {
+
+ Ip4Config2DestroyDhcp4 (Instance);
+ }
+
+ //
+ // Close the event.
+ //
+ if (Instance->Dhcp4Event != NULL) {
+ gBS->CloseEvent (Instance->Dhcp4Event);
+ }
+
+ for (Index = 0; Index < Ip4Config2DataTypeMaximum; Index++) {
+
+ DataItem = &Instance->DataItem[Index];
+
+ if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) {
+ if (DataItem->Data.Ptr != NULL) {
+ FreePool (DataItem->Data.Ptr);
+ }
+ DataItem->Data.Ptr = NULL;
+ DataItem->DataSize = 0;
+ }
+
+ NetMapClean (&Instance->DataItem[Index].EventMap);
+ }
+
+ Ip4Config2FormUnload (Instance);
+
+ RemoveEntryList (&Instance->Link);
+}
+
Added: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h
(rev 0)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h
2015-07-07 08:19:55 UTC (rev 17853)
@@ -0,0 +1,252 @@
+/** @file
+ Definitions for EFI IPv4 Configuration II Protocol implementation.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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.
+
+**/
+
+#ifndef __IP4_CONFIG2_IMPL_H__
+#define __IP4_CONFIG2_IMPL_H__
+
+#define IP4_CONFIG2_INSTANCE_SIGNATURE SIGNATURE_32 ('I', 'P', 'C', '2')
+#define IP4_FORM_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('I', 'F', 'C', 'I')
+
+#define IP4_CONFIG2_VARIABLE_ATTRIBUTE (EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS)
+
+#define DATA_ATTRIB_SIZE_FIXED 0x1
+#define DATA_ATTRIB_VOLATILE 0x2
+
+#define DHCP_TAG_PARA_LIST 55
+#define DHCP_TAG_NETMASK 1
+#define DHCP_TAG_ROUTER 3
+
+
+#define DATA_ATTRIB_SET(Attrib, Bits) (BOOLEAN)((Attrib) & (Bits))
+#define SET_DATA_ATTRIB(Attrib, Bits) ((Attrib) |= (Bits))
+
+typedef struct _IP4_CONFIG2_INSTANCE IP4_CONFIG2_INSTANCE;
+
+#define IP4_CONFIG2_INSTANCE_FROM_PROTOCOL(Proto) \
+ CR ((Proto), \
+ IP4_CONFIG2_INSTANCE, \
+ Ip4Config2, \
+ IP4_CONFIG2_INSTANCE_SIGNATURE \
+ )
+
+#define IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE(Instance) \
+ CR ((Instance), \
+ IP4_SERVICE, \
+ Ip4Config2Instance, \
+ IP4_SERVICE_SIGNATURE \
+ )
+
+#define IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Callback) \
+ CR ((Callback), \
+ IP4_CONFIG2_INSTANCE, \
+ CallbackInfo, \
+ IP4_CONFIG2_INSTANCE_SIGNATURE \
+ )
+
+#define IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(ConfigAccess) \
+ CR ((ConfigAccess), \
+ IP4_FORM_CALLBACK_INFO, \
+ HiiConfigAccessProtocol, \
+ IP4_FORM_CALLBACK_INFO_SIGNATURE \
+ )
+
+/**
+ The prototype of work function for EfiIp4Config2SetData().
+
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in] DataSize In bytes, the size of the buffer pointed to by Data.
+ @param[in] Data The data buffer to set.
+
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the
type,
+ 8 bytes.
+ @retval EFI_SUCCESS The specified configuration data for the EFI
IPv4
+ network stack was set successfully.
+
+**/
+typedef
+EFI_STATUS
+(*IP4_CONFIG2_SET_DATA) (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+/**
+ The prototype of work function for EfiIp4Config2GetData().
+
+ @param[in] Instance The pointer to the IP4 config2 instance data.
+ @param[in, out] DataSize On input, in bytes, the size of Data. On output, in
+ bytes, the size of buffer required to store the
specified
+ configuration data.
+ @param[in] Data The data buffer in which the configuration data is
returned.
+ Ignored if DataSize is ZERO.
+
+ @retval EFI_BUFFER_TOO_SMALL The size of Data is too small for the specified
+ configuration data, and the required size is
+ returned in DataSize.
+ @retval EFI_SUCCESS The specified configuration data was obtained
successfully.
+
+**/
+typedef
+EFI_STATUS
+(*IP4_CONFIG2_GET_DATA) (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN OUT UINTN *DataSize,
+ IN VOID *Data OPTIONAL
+ );
+
+typedef union {
+ VOID *Ptr;
+ EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;
+ EFI_IP4_CONFIG2_POLICY *Policy;
+ EFI_IP4_CONFIG2_MANUAL_ADDRESS *ManualAddress;
+ EFI_IPv4_ADDRESS *Gateway;
+ EFI_IPv4_ADDRESS *DnsServers;
+} IP4_CONFIG2_DATA;
+
+typedef struct {
+ IP4_CONFIG2_SET_DATA SetData;
+ IP4_CONFIG2_GET_DATA GetData;
+ EFI_STATUS Status;
+ UINT8 Attribute;
+ NET_MAP EventMap;
+ IP4_CONFIG2_DATA Data;
+ UINTN DataSize;
+} IP4_CONFIG2_DATA_ITEM;
+
+typedef struct {
+ UINT16 Offset;
+ UINT32 DataSize;
+ EFI_IP4_CONFIG2_DATA_TYPE DataType;
+} IP4_CONFIG2_DATA_RECORD;
+
+#pragma pack(1)
+
+//
+// heap data that contains the data for each data record.
+//
+// EFI_IP4_CONFIG2_POLICY Policy;
+// UINT32 ManualaddressCount;
+// UINT32 GatewayCount;
+// UINT32 DnsServersCount;
+// EFI_IP4_CONFIG2_MANUAL_ADDRESS ManualAddress[];
+// EFI_IPv4_ADDRESS Gateway[];
+// EFI_IPv4_ADDRESS DnsServers[];
+//
+typedef struct {
+ UINT16 Checksum;
+ UINT16 DataRecordCount;
+ IP4_CONFIG2_DATA_RECORD DataRecord[1];
+} IP4_CONFIG2_VARIABLE;
+
+#pragma pack()
+
+typedef struct {
+ EFI_IP4_CONFIG2_POLICY Policy; ///< manual
or automatic
+ EFI_IP4_CONFIG2_MANUAL_ADDRESS *ManualAddress; ///< IP
addresses
+ UINT32 ManualAddressCount; ///< IP
addresses count
+ EFI_IPv4_ADDRESS *GatewayAddress; ///< Gateway
address
+ UINT32 GatewayAddressCount; ///< Gateway
address count
+ EFI_IPv4_ADDRESS *DnsAddress; ///< DNS
server address
+ UINT32 DnsAddressCount; ///< DNS
server address count
+} IP4_CONFIG2_NVDATA;
+
+typedef struct _IP4_FORM_CALLBACK_INFO {
+ UINT32 Signature;
+ EFI_HANDLE ChildHandle;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL HiiConfigAccessProtocol;
+ EFI_DEVICE_PATH_PROTOCOL *HiiVendorDevicePath;
+ EFI_HII_HANDLE RegisteredHandle;
+} IP4_FORM_CALLBACK_INFO;
+
+struct _IP4_CONFIG2_INSTANCE {
+ UINT32 Signature;
+ BOOLEAN Configured;
+ LIST_ENTRY Link;
+ UINT16 IfIndex;
+
+ EFI_IP4_CONFIG2_PROTOCOL Ip4Config2;
+
+ EFI_IP4_CONFIG2_INTERFACE_INFO InterfaceInfo;
+ EFI_IP4_CONFIG2_POLICY Policy;
+ IP4_CONFIG2_DATA_ITEM
DataItem[Ip4Config2DataTypeMaximum];
+
+ EFI_EVENT Dhcp4SbNotifyEvent;
+ VOID *Registration;
+ EFI_HANDLE Dhcp4Handle;
+ EFI_DHCP4_PROTOCOL *Dhcp4;
+ BOOLEAN DhcpSuccess;
+ BOOLEAN OtherInfoOnly;
+ EFI_EVENT Dhcp4Event;
+ UINT32 FailedIaAddressCount;
+ EFI_IPv4_ADDRESS *DeclineAddress;
+ UINT32 DeclineAddressCount;
+
+ IP4_FORM_CALLBACK_INFO CallbackInfo;
+
+ IP4_CONFIG2_NVDATA Ip4NvData;
+};
+
+//
+// Configure the DHCP to request the routers and netmask
+// from server. The DHCP_TAG_NETMASK is included in Head.
+//
+#pragma pack(1)
+typedef struct {
+ EFI_DHCP4_PACKET_OPTION Head;
+ UINT8 Route;
+} IP4_CONFIG2_DHCP4_OPTION;
+#pragma pack()
+
+/**
+ Initialize an IP4_CONFIG2_INSTANCE.
+
+ @param[out] Instance The buffer of IP4_CONFIG2_INSTANCE to be
initialized.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the
operation.
+ @retval EFI_SUCCESS The IP4_CONFIG2_INSTANCE initialized
successfully.
+
+**/
+EFI_STATUS
+Ip4Config2InitInstance (
+ OUT IP4_CONFIG2_INSTANCE *Instance
+ );
+
+/**
+ Release an IP4_CONFIG2_INSTANCE.
+
+ @param[in, out] Instance The buffer of IP4_CONFIG2_INSTANCE to be freed.
+
+**/
+VOID
+Ip4Config2CleanInstance (
+ IN OUT IP4_CONFIG2_INSTANCE *Instance
+ );
+
+/**
+ Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources.
+
+ @param[in, out] Instance The buffer of IP4 config2 instance to be freed.
+
+ @retval EFI_SUCCESS The child was successfully destroyed.
+ @retval Others Failed to destroy the child.
+
+**/
+EFI_STATUS
+Ip4Config2DestroyDhcp4 (
+ IN OUT IP4_CONFIG2_INSTANCE *Instance
+ );
+
+#endif
Added: trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Nv.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Nv.c
(rev 0)
+++ trunk/edk2/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Nv.c
2015-07-07 08:19:55 UTC (rev 17853)
@@ -0,0 +1,1436 @@
+/** @file
+ Helper functions for configuring or getting the parameters relating to Ip4.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+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.
+
+**/
+
+#include "Ip4Impl.h"
+
+CHAR16 mIp4Config2StorageName[] = L"IP4_CONFIG2_IFR_NVDATA";
+
+/**
+ Calculate the prefix length of the IPv4 subnet mask.
+
+ @param[in] SubnetMask The IPv4 subnet mask.
+
+ @return The prefix length of the subnet mask.
+ @retval 0 Other errors as indicated.
+
+**/
+UINT8
+GetSubnetMaskPrefixLength (
+ IN EFI_IPv4_ADDRESS *SubnetMask
+ )
+{
+ UINT8 Len;
+ UINT32 ReverseMask;
+
+ //
+ // The SubnetMask is in network byte order.
+ //
+ ReverseMask = SwapBytes32 (*(UINT32 *)&SubnetMask[0]);
+
+ //
+ // Reverse it.
+ //
+ ReverseMask = ~ReverseMask;
+
+ if ((ReverseMask & (ReverseMask + 1)) != 0) {
+ return 0;
+ }
+
+ Len = 0;
+
+ while (ReverseMask != 0) {
+ ReverseMask = ReverseMask >> 1;
+ Len++;
+ }
+
+ return (UINT8) (32 - Len);
+}
+
+/**
+ Convert the decimal dotted IPv4 address into the binary IPv4 address.
+
+ @param[in] Str The UNICODE string.
+ @param[out] Ip The storage to return the IPv4 address.
+
+ @retval EFI_SUCCESS The binary IP address is returned in Ip.
+ @retval EFI_INVALID_PARAMETER The IP string is malformatted.
+
+**/
+EFI_STATUS
+Ip4Config2StrToIp (
+ IN CHAR16 *Str,
+ OUT EFI_IPv4_ADDRESS *Ip
+ )
+{
+ UINTN Index;
+ UINTN Number;
+
+ Index = 0;
+
+ while (*Str != L'\0') {
+
+ if (Index > 3) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Number = 0;
+ while ((*Str >= L'0') && (*Str <= L'9')) {
+ Number = Number * 10 + (*Str - L'0');
+ Str++;
+ }
+
+ if (Number > 0xFF) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ip->Addr[Index] = (UINT8) Number;
+
+ if ((*Str != L'\0') && (*Str != L'.')) {
+ //
+ // The current character should be either the NULL terminator or
+ // the dot delimiter.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*Str == L'.') {
+ //
+ // Skip the delimiter.
+ //
+ Str++;
+ }
+
+ Index++;
+ }
+
+ if (Index != 4) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Convert the decimal dotted IPv4 addresses separated by space into the binary
IPv4 address list.
+
+ @param[in] Str The UNICODE string contains IPv4 addresses.
+ @param[out] PtrIpList The storage to return the IPv4 address list.
+ @param[out] IpCount The size of the IPv4 address list.
+
+ @retval EFI_SUCCESS The binary IP address list is returned in
PtrIpList.
+ @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.
+ @retval EFI_INVALID_PARAMETER The IP string is malformatted.
+
+**/
+EFI_STATUS
+Ip4Config2StrToIpList (
+ IN CHAR16 *Str,
+ OUT EFI_IPv4_ADDRESS **PtrIpList,
+ OUT UINTN *IpCount
+ )
+{
+ UINTN BeginIndex;
+ UINTN EndIndex;
+ UINTN Index;
+ UINTN IpIndex;
+ CHAR16 *StrTemp;
+ BOOLEAN SpaceTag;
+
+ BeginIndex = 0;
+ EndIndex = BeginIndex;
+ Index = 0;
+ IpIndex = 0;
+ StrTemp = NULL;
+ SpaceTag = TRUE;
+
+ *PtrIpList = NULL;
+ *IpCount = 0;
+
+ if (Str == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Get the number of Ip.
+ //
+ while (*(Str + Index) != L'\0') {
+ if (*(Str + Index) == L' ') {
+ SpaceTag = TRUE;
+ } else {
+ if (SpaceTag) {
+ (*IpCount)++;
+ SpaceTag = FALSE;
+ }
+ }
+
+ Index++;
+ }
+
+ if (*IpCount == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Allocate buffer for IpList.
+ //
+ *PtrIpList = AllocateZeroPool(*IpCount * sizeof(EFI_IPv4_ADDRESS));
+ if (*PtrIpList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Get IpList from Str.
+ //
+ Index = 0;
+ while (*(Str + Index) != L'\0') {
+ if (*(Str + Index) == L' ') {
+ if(!SpaceTag) {
+ StrTemp = AllocateZeroPool((EndIndex - BeginIndex + 1) *
sizeof(CHAR16));
+ if (StrTemp == NULL) {
+ FreePool(*PtrIpList);
+ *PtrIpList = NULL;
+ *IpCount = 0;
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) *
sizeof(CHAR16));
+ *(StrTemp + (EndIndex - BeginIndex)) = L'\0';
+
+ if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) !=
EFI_SUCCESS) {
+ FreePool(StrTemp);
+ FreePool(*PtrIpList);
+ *PtrIpList = NULL;
+ *IpCount = 0;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BeginIndex = EndIndex;
+ IpIndex++;
+
+ FreePool(StrTemp);
+ }
+
+ BeginIndex++;
+ EndIndex++;
+ SpaceTag = TRUE;
+ } else {
+ EndIndex++;
+ SpaceTag = FALSE;
+ }
+
+ Index++;
+
+ if (*(Str + Index) == L'\0') {
+ if (!SpaceTag) {
+ StrTemp = AllocateZeroPool((EndIndex - BeginIndex + 1) *
sizeof(CHAR16));
+ if (StrTemp == NULL) {
+ FreePool(*PtrIpList);
+ *PtrIpList = NULL;
+ *IpCount = 0;
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) *
sizeof(CHAR16));
+ *(StrTemp + (EndIndex - BeginIndex)) = L'\0';
+
+ if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) !=
EFI_SUCCESS) {
+ FreePool(StrTemp);
+ FreePool(*PtrIpList);
+ *PtrIpList = NULL;
+ *IpCount = 0;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FreePool(StrTemp);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Convert the IPv4 address into a dotted string.
+
+ @param[in] Ip The IPv4 address.
+ @param[out] Str The dotted IP string.
+
+**/
+VOID
+Ip4Config2IpToStr (
+ IN EFI_IPv4_ADDRESS *Ip,
+ OUT CHAR16 *Str
+ )
+{
+ UnicodeSPrint (
+ Str,
+ 2 * IP4_STR_MAX_SIZE,
+ L"%d.%d.%d.%d",
+ Ip->Addr[0],
+ Ip->Addr[1],
+ Ip->Addr[2],
+ Ip->Addr[3]
+ );
+}
+
+
+/**
+ Convert the IPv4 address list into string consists of several decimal
+ dotted IPv4 addresses separated by space.
+
+ @param[in] Ip The IPv4 address list.
+ @param[in] IpCount The size of IPv4 address list.
+ @param[out] Str The string contains several decimal dotted
+ IPv4 addresses separated by space.
+**/
+VOID
+Ip4Config2IpListToStr (
+ IN EFI_IPv4_ADDRESS *Ip,
+ IN UINTN IpCount,
+ OUT CHAR16 *Str
+ )
+{
+ UINTN Index;
+ UINTN TemIndex;
+ UINTN StrIndex;
+ CHAR16 *TempStr;
+ EFI_IPv4_ADDRESS *TempIp;
+
+ Index = 0;
+ TemIndex = 0;
+ StrIndex = 0;
+ TempStr = NULL;
+ TempIp = NULL;
+
+ for (Index = 0; Index < IpCount; Index ++) {
+ TempIp = Ip + Index;
+ if (TempStr == NULL) {
+ TempStr = AllocateZeroPool(2 * IP4_STR_MAX_SIZE);
+ ASSERT(TempStr != NULL);
+ }
+
+ UnicodeSPrint (
+ TempStr,
+ 2 * IP4_STR_MAX_SIZE,
+ L"%d.%d.%d.%d",
+ TempIp->Addr[0],
+ TempIp->Addr[1],
+ TempIp->Addr[2],
+ TempIp->Addr[3]
+ );
+
+ for (TemIndex = 0; TemIndex < IP4_STR_MAX_SIZE; TemIndex ++) {
+ if (*(TempStr + TemIndex) == L'\0') {
+ if (Index == IpCount - 1) {
+ Str[StrIndex++] = L'\0';
+ } else {
+ Str[StrIndex++] = L' ';
+ }
+ break;
+ } else {
+ Str[StrIndex++] = *(TempStr + TemIndex);
+ }
+ }
+ }
+
+ if (TempStr != NULL) {
+ FreePool(TempStr);
+ }
+}
+
+/**
+ The notify function of create event when performing a manual configuration.
+
+ @param[in] Event The pointer of Event.
+ @param[in] Context The pointer of Context.
+
+**/
+VOID
+EFIAPI
+Ip4Config2ManualAddressNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ *((BOOLEAN *) Context) = TRUE;
+}
+
+/**
+ Convert the network configuration data into the IFR data.
+
+ @param[in] Instance The IP4 config2 instance.
+ @param[in, out] IfrNvData The IFR nv data.
+
+ @retval EFI_SUCCESS The configure parameter to IFR data was
+ set successfully.
+ @retval EFI_INVALID_PARAMETER Source instance or target IFR data is not
available.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+Ip4Config2ConvertConfigNvDataToIfrNvData (
+ IN IP4_CONFIG2_INSTANCE *Instance,
+ IN OUT IP4_CONFIG2_IFR_NVDATA *IfrNvData
+ )
+{
+ IP4_SERVICE *IpSb;
+ EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
+ EFI_IP4_CONFIG2_INTERFACE_INFO *Ip4Info;
+ EFI_IP4_CONFIG2_POLICY Policy;
+ UINTN DataSize;
+ UINTN GatewaySize;
+ EFI_IPv4_ADDRESS GatewayAddress;
+ EFI_STATUS Status;
+ UINTN DnsSize;
+ UINTN DnsCount;
+ EFI_IPv4_ADDRESS *DnsAddress;
+
+ Status = EFI_SUCCESS;
+ Ip4Config2 = &Instance->Ip4Config2;
+ Ip4Info = NULL;
+ DnsAddress = NULL;
+ GatewaySize = sizeof (EFI_IPv4_ADDRESS);
+
+ if ((IfrNvData == NULL) || (Instance == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NET_CHECK_SIGNATURE (Instance, IP4_CONFIG2_INSTANCE_SIGNATURE);
+
+ IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
+
+ if (IpSb->DefaultInterface->Configured) {
+ IfrNvData->Configure = 1;
+ } else {
+ IfrNvData->Configure = 0;
+ goto Exit;
+ }
+
+ //
+ // Get the Policy info.
+ //
+ DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);
+ Status = Ip4Config2->GetData (
+ Ip4Config2,
+ Ip4Config2DataTypePolicy,
+ &DataSize,
+ &Policy
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ if (Policy == Ip4Config2PolicyStatic) {
+ IfrNvData->DhcpEnable = FALSE;
+ } else if (Policy == Ip4Config2PolicyDhcp) {
+ IfrNvData->DhcpEnable = TRUE;
+ goto Exit;
+ }
+
+ //
+ // Get the interface info.
+ //
+ DataSize = 0;
+ Status = Ip4Config2->GetData (
+ Ip4Config2,
+ Ip4Config2DataTypeInterfaceInfo,
+ &DataSize,
+ NULL
+ );
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
+ }
+
+ Ip4Info = AllocateZeroPool (DataSize);
+ if (Ip4Info == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = Ip4Config2->GetData (
+ Ip4Config2,
+ Ip4Config2DataTypeInterfaceInfo,
+ &DataSize,
+ Ip4Info
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Get the Gateway info.
+ //
+ Status = Ip4Config2->GetData (
+ Ip4Config2,
+ Ip4Config2DataTypeGateway,
+ &GatewaySize,
+ &GatewayAddress
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Get the Dns info.
+ //
+ DnsSize = 0;
+ Status = Ip4Config2->GetData (
+ Ip4Config2,
+ Ip4Config2DataTypeDnsServer,
+ &DnsSize,
+ NULL
+ );
+ if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {
+ goto Exit;
+ }
+
+ DnsCount = (UINT32) (DnsSize / sizeof (EFI_IPv4_ADDRESS));
+
+ if (DnsSize > 0) {
+ DnsAddress = AllocateZeroPool(DnsSize);
+ if (DnsAddress == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ Status = Ip4Config2->GetData (
+ Ip4Config2,
+ Ip4Config2DataTypeDnsServer,
+ &DnsSize,
+ DnsAddress
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ }
+
+ Ip4Config2IpToStr (&Ip4Info->StationAddress, IfrNvData->StationAddress);
+ Ip4Config2IpToStr (&Ip4Info->SubnetMask, IfrNvData->SubnetMask);
+ Ip4Config2IpToStr (&GatewayAddress, IfrNvData->GatewayAddress);
+ Ip4Config2IpListToStr (DnsAddress, DnsCount, IfrNvData->DnsAddress);
+
+Exit:
+
+ if (DnsAddress != NULL) {
+ FreePool(DnsAddress);
+ }
+
+ if (Ip4Info != NULL) {
+ FreePool(Ip4Info);
+ }
+
+ return Status;
+}
+
+/**
+ Convert the IFR data into the network configuration data and set the IP
+ configure parameters for the NIC.
+
+ @param[in] IfrFormNvData The IFR NV data.
+ @param[in, out] Instance The IP4 config2 instance.
+
+ @retval EFI_SUCCESS The configure parameter for this NIC was
+ set successfully.
+ @retval EFI_INVALID_PARAMETER The address information for setting is
invalid.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+Ip4Config2ConvertIfrNvDataToConfigNvData (
+ IN IP4_CONFIG2_IFR_NVDATA *IfrFormNvData,
+ IN OUT IP4_CONFIG2_INSTANCE *Instance
+ )
+{
+ EFI_STATUS Status;
+ EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;
+ IP4_CONFIG2_NVDATA *Ip4NvData;
+
+ EFI_IP_ADDRESS StationAddress;
+ EFI_IP_ADDRESS SubnetMask;
+ EFI_IP_ADDRESS Gateway;
+ IP4_ADDR Ip;
+ EFI_IPv4_ADDRESS *DnsAddress;
+ UINTN DnsCount;
+ UINTN Index;
+
+ EFI_EVENT TimeoutEvent;
+ EFI_EVENT SetAddressEvent;
+ BOOLEAN IsAddressOk;
+ UINTN DataSize;
+ EFI_INPUT_KEY Key;
+
+ Status = EFI_SUCCESS;
+ Ip4Cfg2 = &Instance->Ip4Config2;
+ Ip4NvData = &Instance->Ip4NvData;
+
+ DnsCount = 0;
+ DnsAddress = NULL;
+
+ TimeoutEvent = NULL;
+ SetAddressEvent = NULL;
+
+
+
+ if (Instance == NULL || IfrFormNvData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IfrFormNvData->Configure != TRUE) {
+ return EFI_SUCCESS;
+ }
+
+ if (IfrFormNvData->DhcpEnable == TRUE) {
+ Ip4NvData->Policy = Ip4Config2PolicyDhcp;
+
+ Status = Ip4Cfg2->SetData (
+ Ip4Cfg2,
+ Ip4Config2DataTypePolicy,
+ sizeof (EFI_IP4_CONFIG2_POLICY),
+ &Ip4NvData->Policy
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ } else {
+ //
+ // Get Ip4NvData from IfrFormNvData if it is valid.
+ //
+ Ip4NvData->Policy = Ip4Config2PolicyStatic;
+
+ Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress,
&StationAddress.v4);
+ if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL
(StationAddress.Addr[0]), 0)) {
+ CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP
address!", NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);
+ if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) &&
(GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
+ CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet
Mask!", NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);
+ if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast
(NTOHL (Gateway.Addr[0]), 0))) {
+ CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid
Gateway!", NULL);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress,
&DnsCount);
+ if (!EFI_ERROR (Status) && DnsCount > 0) {
+ for (Index = 0; Index < DnsCount; Index ++) {
+ CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));
+ if (!NetIp4IsUnicast (NTOHL (Ip), 0)) {
+ CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid
Dns Server!", NULL);
+ FreePool(DnsAddress);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ } else {
+ if (EFI_ERROR (Status)) {
+ CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns
Server!", NULL);
+ }
+ }
+
+ if (Ip4NvData->ManualAddress != NULL) {
+ FreePool(Ip4NvData->ManualAddress);
+ }
+ Ip4NvData->ManualAddressCount = 1;
+ Ip4NvData->ManualAddress =
AllocateZeroPool(sizeof(EFI_IP4_CONFIG2_MANUAL_ADDRESS));
+ if (Ip4NvData->ManualAddress == NULL) {
+ if (DnsAddress != NULL) {
+ FreePool(DnsAddress);
+ }
+
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem(&Ip4NvData->ManualAddress->Address, &StationAddress.v4,
sizeof(EFI_IPv4_ADDRESS));
+ CopyMem(&Ip4NvData->ManualAddress->SubnetMask, &SubnetMask.v4,
sizeof(EFI_IPv4_ADDRESS));
+
+ if (Ip4NvData->GatewayAddress != NULL) {
+ FreePool(Ip4NvData->GatewayAddress);
+ }
+ Ip4NvData->GatewayAddressCount = 1;
+ Ip4NvData->GatewayAddress = AllocateZeroPool(sizeof(EFI_IPv4_ADDRESS));
+ if (Ip4NvData->GatewayAddress == NULL) {
+ if (DnsAddress != NULL) {
+ FreePool(DnsAddress);
+ }
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem(Ip4NvData->GatewayAddress, &Gateway.v4, sizeof(EFI_IPv4_ADDRESS));
+
+ if (Ip4NvData->DnsAddress != NULL) {
+ FreePool(Ip4NvData->DnsAddress);
+ }
+ Ip4NvData->DnsAddressCount = (UINT32) DnsCount;
+ Ip4NvData->DnsAddress = DnsAddress;
+
+ //
+ // Setting Ip4NvData.
+ //
+ Status = Ip4Cfg2->SetData (
+ Ip4Cfg2,
+ Ip4Config2DataTypePolicy,
+ sizeof (EFI_IP4_CONFIG2_POLICY),
+ &Ip4NvData->Policy
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Create events & timers for asynchronous settings.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ Ip4Config2ManualAddressNotify,
+ &IsAddressOk,
+ &SetAddressEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ IsAddressOk = FALSE;
+
+ Status = Ip4Cfg2->RegisterDataNotify (
+ Ip4Cfg2,
+ Ip4Config2DataTypeManualAddress,
+ SetAddressEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Set ManualAddress.
+ //
+ DataSize = Ip4NvData->ManualAddressCount * sizeof
(EFI_IP4_CONFIG2_MANUAL_ADDRESS);
+ Status = Ip4Cfg2->SetData (
+ Ip4Cfg2,
+ Ip4Config2DataTypeManualAddress,
+ DataSize,
+ (VOID *) Ip4NvData->ManualAddress
+ );
+
+ if (Status == EFI_NOT_READY) {
+ gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);
+ while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
+ if (IsAddressOk) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ Ip4Cfg2->UnregisterDataNotify (
+ Ip4Cfg2,
+ Ip4Config2DataTypeManualAddress,
+ SetAddressEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Set gateway.
+ //
+ DataSize = Ip4NvData->GatewayAddressCount * sizeof (EFI_IPv4_ADDRESS);
+ Status = Ip4Cfg2->SetData (
+ Ip4Cfg2,
+ Ip4Config2DataTypeGateway,
+ DataSize,
+ Ip4NvData->GatewayAddress
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Set DNS addresses.
+ //
+ if (Ip4NvData->DnsAddressCount > 0 && Ip4NvData->DnsAddress != NULL) {
+ DataSize = Ip4NvData->DnsAddressCount * sizeof (EFI_IPv4_ADDRESS);
+ Status = Ip4Cfg2->SetData (
+ Ip4Cfg2,
+ Ip4Config2DataTypeDnsServer,
+ DataSize,
+ Ip4NvData->DnsAddress
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+ }
+ }
+
+Exit:
+ if (SetAddressEvent != NULL) {
+ gBS->CloseEvent (SetAddressEvent);
+ }
+
+ if (TimeoutEvent != NULL) {
+ gBS->CloseEvent (TimeoutEvent);
+ }
+
+ return Status;
+}
+
+/**
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Any and all alternative
+ configuration strings shall also be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param[in] Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+ @param[out] Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not
+ successful.
+ @param[out] Results A null-terminated Unicode string in
+ <ConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent & before the
+ error or the beginning of the
+ string.
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.Currently not implemented.
+**/
+EFI_STATUS
+EFIAPI
+Ip4FormExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ IP4_CONFIG2_INSTANCE *Ip4Config2Instance;
+ IP4_FORM_CALLBACK_INFO *Private;
+ IP4_CONFIG2_IFR_NVDATA *IfrFormNvData;
+ EFI_STRING ConfigRequestHdr;
+ EFI_STRING ConfigRequest;
+ BOOLEAN AllocatedRequest;
+ EFI_STRING FormResult;
+ UINTN Size;
+ UINTN BufferSize;
+
+ Status = EFI_SUCCESS;
+ IfrFormNvData = NULL;
+ ConfigRequest = NULL;
+ FormResult = NULL;
+ Size = 0;
+ AllocatedRequest = FALSE;
+ ConfigRequest = Request;
+ Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(This);
+ Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK(Private);
+ BufferSize = sizeof (IP4_CONFIG2_IFR_NVDATA);
+ *Progress = Request;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check Request data in <ConfigHdr>.
+ //
@@ Diff output truncated at 100000 characters. @@
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits