--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ ComponentName.c\r
+\r
+Abstract:\r
+\r
+\r
+**/\r
+\r
+\r
+#include "Ip4Config.h"\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+Ip4ConfigComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+Ip4ConfigComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ );\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL gIp4ConfigComponentName = {\r
+ Ip4ConfigComponentNameGetDriverName,\r
+ Ip4ConfigComponentNameGetControllerName,\r
+ "eng"\r
+};\r
+\r
+STATIC\r
+EFI_UNICODE_STRING_TABLE mIp4ConfigDriverNameTable[] = {\r
+ {"eng", L"IP4 CONFIG Network Service Driver"},\r
+ {NULL, NULL}\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+Ip4ConfigComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ Language - A pointer to a three character ISO 639-2 language identifier.\r
+ This is the language of the driver name that that the caller\r
+ is requesting, and it must match one of the languages specified\r
+ in SupportedLanguages. The number of languages supported by a\r
+ driver is up to the driver writer.\r
+ DriverName - A pointer to the Unicode string to return. This Unicode string\r
+ is the name of the driver specified by This in the language\r
+ specified by Language.\r
+\r
+ Returns:\r
+ EFI_SUCCES - The Unicode string for the Driver specified by This\r
+ and the language specified by Language was returned\r
+ in DriverName.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - DriverName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ return LookupUnicodeString (\r
+ Language,\r
+ gIp4ConfigComponentName.SupportedLanguages,\r
+ mIp4ConfigDriverNameTable,\r
+ DriverName\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+Ip4ConfigComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle OPTIONAL,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by an EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ ControllerHandle - The handle of a controller that the driver specified by\r
+ This is managing. This handle specifies the controller\r
+ whose name is to be returned.\r
+ ChildHandle - The handle of the child controller to retrieve the name\r
+ of. This is an optional parameter that may be NULL. It\r
+ will be NULL for device drivers. It will also be NULL\r
+ for a bus drivers that wish to retrieve the name of the\r
+ bus controller. It will not be NULL for a bus driver\r
+ that wishes to retrieve the name of a child controller.\r
+ Language - A pointer to a three character ISO 639-2 language\r
+ identifier. This is the language of the controller name\r
+ that that the caller is requesting, and it must match one\r
+ of the languages specified in SupportedLanguages. The\r
+ number of languages supported by a driver is up to the\r
+ driver writer.\r
+ ControllerName - A pointer to the Unicode string to return. This Unicode\r
+ string is the name of the controller specified by\r
+ ControllerHandle and ChildHandle in the language specified\r
+ by Language from the point of view of the driver specified\r
+ by This.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The Unicode string for the user readable name in the\r
+ language specified by Language for the driver\r
+ specified by This was returned in DriverName.\r
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing\r
+ the controller specified by ControllerHandle and\r
+ ChildHandle.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the\r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ Ip4Config.c\r
+\r
+Abstract:\r
+\r
+ This code implements the IP4Config and NicIp4Config protocols.\r
+\r
+\r
+**/\r
+\r
+#include "Ip4Config.h"\r
+\r
+IP4_CONFIG_INSTANCE *mIp4ConfigNicList[MAX_IP4_CONFIG_IN_VARIABLE];\r
+\r
+VOID\r
+EFIAPI\r
+Ip4ConfigOnDhcp4Complete (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+\r
+/**\r
+ Return the name and MAC address for the NIC. The Name, if not NULL,\r
+ has at least IP4_NIC_NAME_LENGTH bytes.\r
+\r
+ @param This The NIC IP4 CONFIG protocol\r
+ @param Name The buffer to return the name\r
+ @param NicAddr The buffer to return the MAC addr\r
+\r
+ @retval EFI_INVALID_PARAMETER This is NULL\r
+ @retval EFI_SUCCESS The name or address of the NIC are returned.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+EfiNicIp4ConfigGetName (\r
+ IN EFI_NIC_IP4_CONFIG_PROTOCOL *This,\r
+ IN UINT16 *Name, OPTIONAL\r
+ IN NIC_ADDR *NicAddr OPTIONAL\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_NIC_IP4CONFIG (This);\r
+\r
+ if (Name != NULL) {\r
+ NetCopyMem (Name, Instance->NicName, IP4_NIC_NAME_LENGTH);\r
+ }\r
+\r
+ if (NicAddr != NULL) {\r
+ *NicAddr = Instance->NicAddr;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Get the NIC's configure information from the IP4 configure variable.\r
+ It will remove the invalid variable.\r
+\r
+ @param NicAddr The NIC to check\r
+\r
+ @return NULL if no configure for the NIC in the variable, or it is invalid.\r
+ @return Otherwise the NIC's IP configure parameter.\r
+\r
+**/\r
+NIC_IP4_CONFIG_INFO *\r
+Ip4ConfigGetNicInfo (\r
+ IN NIC_ADDR *NicAddr\r
+ )\r
+{\r
+ IP4_CONFIG_VARIABLE *Variable;\r
+ IP4_CONFIG_VARIABLE *NewVariable;\r
+ NIC_IP4_CONFIG_INFO *Config;\r
+\r
+ //\r
+ // Read the configuration parameter for this NicAddr from\r
+ // the EFI variable\r
+ //\r
+ Variable = Ip4ConfigReadVariable ();\r
+\r
+ if (Variable == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ Config = Ip4ConfigFindNicVariable (Variable, NicAddr);\r
+\r
+ if (Config == NULL) {\r
+ NetFreePool (Variable);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Validate the configuration, if the configuration is invalid,\r
+ // remove it from the variable.\r
+ //\r
+ if (!Ip4ConfigIsValid (Config)) {\r
+ NewVariable = Ip4ConfigModifyVariable (Variable, &Config->NicAddr, NULL);\r
+ Ip4ConfigWriteVariable (NewVariable);\r
+\r
+ if (NewVariable != NULL) {\r
+ NetFreePool (NewVariable);\r
+ };\r
+\r
+ NetFreePool (Config);\r
+ Config = NULL;\r
+ }\r
+\r
+ NetFreePool (Variable);\r
+ return Config;\r
+}\r
+\r
+\r
+/**\r
+ Get the configure parameter for this NIC.\r
+\r
+ @param This The NIC IP4 CONFIG protocol\r
+ @param ConfigLen The length of the NicConfig buffer.\r
+ @param NicConfig The buffer to receive the NIC's configure\r
+ parameter.\r
+\r
+ @retval EFI_INVALID_PARAMETER This or ConfigLen is NULL\r
+ @retval EFI_NOT_FOUND There is no configure parameter for the NIC in\r
+ NVRam.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiNicIp4ConfigGetInfo (\r
+ IN EFI_NIC_IP4_CONFIG_PROTOCOL *This,\r
+ IN OUT UINTN *ConfigLen,\r
+ OUT NIC_IP4_CONFIG_INFO *NicConfig\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ NIC_IP4_CONFIG_INFO *Config;\r
+ EFI_STATUS Status;\r
+ UINTN Len;\r
+\r
+ if ((This == NULL) || (ConfigLen == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Read the Nic's configuration parameter from variable\r
+ //\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_NIC_IP4CONFIG (This);\r
+ Config = Ip4ConfigGetNicInfo (&Instance->NicAddr);\r
+\r
+ if (Config == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Copy the data to user's buffer\r
+ //\r
+ Len = SIZEOF_NIC_IP4_CONFIG_INFO (Config);\r
+\r
+ if ((*ConfigLen < Len) || (NicConfig == NULL)) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ } else {\r
+ Status = EFI_SUCCESS;\r
+ NetCopyMem (NicConfig, Config, Len);\r
+ }\r
+\r
+ *ConfigLen = Len;\r
+\r
+ NetFreePool (Config);\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Set the IP configure parameters for this NIC. If Reconfig is TRUE,\r
+ the IP driver will be informed to discard current auto configure\r
+ parameter and restart the auto configuration process. If current\r
+ there is a pending auto configuration, EFI_ALREADY_STARTED is\r
+ returned. You can only change the configure setting when either\r
+ the configure has finished or not started yet. If NicConfig, the\r
+ NIC's configure parameter is removed from the variable.\r
+\r
+ @param This The NIC IP4 CONFIG protocol\r
+ @param NicConfig The new NIC IP4 configure parameter\r
+ @param Reconfig Inform the IP4 driver to restart the auto\r
+ configuration\r
+\r
+ @retval EFI_INVALID_PARAMETER This is NULL or the configure parameter is\r
+ invalid.\r
+ @retval EFI_ALREADY_STARTED There is a pending auto configuration.\r
+ @retval EFI_NOT_FOUND No auto configure parameter is found\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiNicIp4ConfigSetInfo (\r
+ IN EFI_NIC_IP4_CONFIG_PROTOCOL *This,\r
+ IN NIC_IP4_CONFIG_INFO *NicConfig, OPTIONAL\r
+ IN BOOLEAN Reconfig\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ IP4_CONFIG_VARIABLE *Variable;\r
+ IP4_CONFIG_VARIABLE *NewVariable;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Validate the parameters\r
+ //\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_NIC_IP4CONFIG (This);\r
+\r
+ if ((NicConfig != NULL) && (!Ip4ConfigIsValid (NicConfig) ||\r
+ !NIC_ADDR_EQUAL (&NicConfig->NicAddr, &Instance->NicAddr))) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Instance->State == IP4_CONFIG_STATE_STARTED) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ //\r
+ // Update the parameter in the configure variable\r
+ //\r
+ Variable = Ip4ConfigReadVariable ();\r
+\r
+ if ((Variable == NULL) && (NicConfig == NULL)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NicConfig);\r
+ Status = Ip4ConfigWriteVariable (NewVariable);\r
+\r
+ if (NewVariable != NULL) {\r
+ NetFreePool (NewVariable);\r
+ }\r
+\r
+ //\r
+ // Variable is NULL when saving the first configure parameter\r
+ //\r
+ if (Variable != NULL) {\r
+ NetFreePool (Variable);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Signal the IP4 to run the auto configuration again\r
+ //\r
+ if (Reconfig && (Instance->ReconfigEvent != NULL)) {\r
+ Status = gBS->SignalEvent (Instance->ReconfigEvent);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Start the auto configuration process.\r
+\r
+ @param This The IP4 configure protocol\r
+ @param DoneEvent The event to signal when auto configure is done\r
+ @param ReconfigEvent The event to signal when reconfigure is necessary.\r
+\r
+ @retval EFI_INVALID_PARAMETER One of the function parameters is NULL.\r
+ @retval EFI_ALREADY_STARTED The auto configuration has already started.\r
+ @retval EFI_SUCCESS The auto configure is successfully started.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiIp4ConfigStart (\r
+ IN EFI_IP4_CONFIG_PROTOCOL *This,\r
+ IN EFI_EVENT DoneEvent,\r
+ IN EFI_EVENT ReconfigEvent\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ EFI_DHCP4_PROTOCOL *Dhcp4;\r
+ EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
+ EFI_DHCP4_PACKET_OPTION *OptionList[1];\r
+ IP4_CONFIG_DHCP4_OPTION ParaList;\r
+ EFI_STATUS Status;\r
+ UINT32 Source;\r
+ EFI_TPL OldTpl;\r
+\r
+ if ((This == NULL) || (DoneEvent == NULL) || (ReconfigEvent == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
+\r
+ OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+\r
+ if (Instance->State != IP4_CONFIG_STATE_IDLE) {\r
+ Status = EFI_ALREADY_STARTED;\r
+\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ Instance->DoneEvent = DoneEvent;\r
+ Instance->ReconfigEvent = ReconfigEvent;\r
+\r
+ Instance->NicConfig = Ip4ConfigGetNicInfo (&Instance->NicAddr);\r
+\r
+ if (Instance->NicConfig == NULL) {\r
+ Source = IP4_CONFIG_SOURCE_DHCP;\r
+ } else {\r
+ Source = Instance->NicConfig->Source;\r
+ }\r
+\r
+ //\r
+ // If the source is static, the auto configuration is done.\r
+ // return now.\r
+ //\r
+ if (Source == IP4_CONFIG_SOURCE_STATIC) {\r
+ Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
+ Instance->Result = EFI_SUCCESS;\r
+\r
+ gBS->SignalEvent (Instance->DoneEvent);\r
+ Status = EFI_SUCCESS;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Start the dhcp process\r
+ //\r
+ ASSERT ((Source == IP4_CONFIG_SOURCE_DHCP) && (Instance->Dhcp4 == NULL));\r
+\r
+ Status = NetLibCreateServiceChild (\r
+ Instance->Controller,\r
+ Instance->Image,\r
+ &gEfiDhcp4ServiceBindingProtocolGuid,\r
+ &Instance->Dhcp4Handle\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ Instance->Dhcp4Handle,\r
+ &gEfiDhcp4ProtocolGuid,\r
+ (VOID **) &Instance->Dhcp4,\r
+ Instance->Image,\r
+ Instance->Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Check the current DHCP status, if the DHCP process has\r
+ // already finished, return now.\r
+ //\r
+ Dhcp4 = Instance->Dhcp4;\r
+ Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ if (Dhcp4Mode.State == Dhcp4Bound) {\r
+ Ip4ConfigOnDhcp4Complete (NULL, Instance);\r
+\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Try to start the DHCP process. Use most of the current\r
+ // DHCP configuration to avoid problems if some DHCP client\r
+ // yields the control of this DHCP service to us.\r
+ //\r
+ ParaList.Head.OpCode = DHCP_TAG_PARA_LIST;\r
+ ParaList.Head.Length = 2;\r
+ ParaList.Head.Data[0] = DHCP_TAG_NETMASK;\r
+ ParaList.Route = DHCP_TAG_ROUTER;\r
+ OptionList[0] = &ParaList.Head;\r
+ Dhcp4Mode.ConfigData.OptionCount = 1;\r
+ Dhcp4Mode.ConfigData.OptionList = OptionList;\r
+\r
+ Status = Dhcp4->Configure (Dhcp4, &Dhcp4Mode.ConfigData);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Start the DHCP process\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ NET_TPL_EVENT,\r
+ Ip4ConfigOnDhcp4Complete,\r
+ Instance,\r
+ &Instance->Dhcp4Event\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Status = Dhcp4->Start (Dhcp4, Instance->Dhcp4Event);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Instance->State = IP4_CONFIG_STATE_STARTED;\r
+ Instance->Result = EFI_NOT_READY;\r
+\r
+ON_ERROR:\r
+ if (EFI_ERROR (Status)) {\r
+ Ip4ConfigCleanConfig (Instance);\r
+ }\r
+\r
+ON_EXIT:\r
+ NET_RESTORE_TPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Stop the current auto configuration\r
+\r
+ @param This The IP4 CONFIG protocol\r
+\r
+ @retval EFI_INVALID_PARAMETER This is NULL.\r
+ @retval EFI_NOT_STARTED The auto configuration hasn't been started.\r
+ @retval EFI_SUCCESS The auto configuration has been stopped.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiIp4ConfigStop (\r
+ IN EFI_IP4_CONFIG_PROTOCOL *This\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
+\r
+ Status = EFI_SUCCESS;\r
+ OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+\r
+ if (Instance->State == IP4_CONFIG_STATE_IDLE) {\r
+ Status = EFI_NOT_STARTED;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Release all the configure parameters. Don't signal the user\r
+ // event. The user wants to abort the configuration, this isn't\r
+ // the configuration done or reconfiguration.\r
+ //\r
+ Ip4ConfigCleanConfig (Instance);\r
+\r
+ON_EXIT:\r
+ NET_RESTORE_TPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Get the current outcome of the auto configuration process\r
+\r
+ @param This The IP4 CONFIG protocol\r
+ @param ConfigDataSize The size of the configure data\r
+ @param ConfigData The buffer to save the configure data\r
+\r
+ @retval EFI_INVALID_PARAMETER This or ConfigDataSize is NULL\r
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small. The needed size is\r
+ returned in the ConfigDataSize.\r
+ @retval EFI_SUCCESS The configure data is put in the buffer\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiIp4ConfigGetData (\r
+ IN EFI_IP4_CONFIG_PROTOCOL *This,\r
+ IN OUT UINTN *ConfigDataSize,\r
+ OUT EFI_IP4_IPCONFIG_DATA *ConfigData OPTIONAL\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ NIC_IP4_CONFIG_INFO *NicConfig;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+ UINTN Len;\r
+\r
+ if ((This == NULL) || (ConfigDataSize == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (This);\r
+\r
+ Status = EFI_SUCCESS;\r
+ OldTpl = NET_RAISE_TPL (NET_TPL_LOCK);\r
+\r
+ if (Instance->State == IP4_CONFIG_STATE_IDLE) {\r
+ Status = EFI_NOT_STARTED;\r
+ } else if (Instance->State == IP4_CONFIG_STATE_STARTED) {\r
+ Status = EFI_NOT_READY;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Copy the configure data if auto configuration succeeds.\r
+ //\r
+ Status = Instance->Result;\r
+\r
+ if (Status == EFI_SUCCESS) {\r
+ ASSERT (Instance->NicConfig != NULL);\r
+\r
+ NicConfig = Instance->NicConfig;\r
+ Len = SIZEOF_IP4_CONFIG_INFO (&NicConfig->Ip4Info);\r
+\r
+ if ((*ConfigDataSize < Len) || (ConfigData == NULL)) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ } else {\r
+ NetCopyMem (ConfigData, &NicConfig->Ip4Info, Len);\r
+ }\r
+\r
+ *ConfigDataSize = Len;\r
+ }\r
+\r
+ON_EXIT:\r
+ NET_RESTORE_TPL (OldTpl);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Callback function when DHCP process finished. It will save the\r
+ retrieved IP configure parameter from DHCP to the NVRam.\r
+\r
+ @param Event The callback event\r
+ @param Context Opaque context to the callback\r
+\r
+ @return None\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ip4ConfigOnDhcp4Complete (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
+ EFI_IP4_IPCONFIG_DATA *Ip4Config;\r
+ EFI_STATUS Status;\r
+ BOOLEAN Perment;\r
+ IP4_ADDR Subnet;\r
+\r
+ Instance = (IP4_CONFIG_INSTANCE *) Context;\r
+ ASSERT (Instance->Dhcp4 != NULL);\r
+\r
+ Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
+ Instance->Result = EFI_TIMEOUT;\r
+\r
+ //\r
+ // Get the DHCP retrieved parameters\r
+ //\r
+ Status = Instance->Dhcp4->GetModeData (Instance->Dhcp4, &Dhcp4Mode);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ if (Dhcp4Mode.State == Dhcp4Bound) {\r
+ //\r
+ // Save the new configuration retrieved by DHCP both in\r
+ // the instance and to NVRam. So, both the IP4 driver and\r
+ // other user can get that address.\r
+ //\r
+ Perment = FALSE;\r
+\r
+ if (Instance->NicConfig != NULL) {\r
+ ASSERT (Instance->NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);\r
+ Perment = Instance->NicConfig->Perment;\r
+ NetFreePool (Instance->NicConfig);\r
+ }\r
+\r
+ Instance->NicConfig = NetAllocatePool (sizeof (NIC_IP4_CONFIG_INFO) +\r
+ sizeof (EFI_IP4_ROUTE_TABLE));\r
+\r
+ if (Instance->NicConfig == NULL) {\r
+ Instance->Result = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ Instance->NicConfig->NicAddr = Instance->NicAddr;\r
+ Instance->NicConfig->Source = IP4_CONFIG_SOURCE_DHCP;\r
+ Instance->NicConfig->Perment = Perment;\r
+\r
+ Ip4Config = &Instance->NicConfig->Ip4Info;\r
+ Ip4Config->StationAddress = Dhcp4Mode.ClientAddress;\r
+ Ip4Config->SubnetMask = Dhcp4Mode.SubnetMask;\r
+\r
+ //\r
+ // Create a route for the connected network\r
+ //\r
+ Ip4Config->RouteTableSize = 1;\r
+\r
+ Subnet = EFI_NTOHL (Dhcp4Mode.ClientAddress) & EFI_NTOHL (Dhcp4Mode.SubnetMask);\r
+\r
+ EFI_IP4 (Ip4Config->RouteTable[0].SubnetAddress) = HTONL (Subnet);\r
+ Ip4Config->RouteTable[0].SubnetMask = Dhcp4Mode.SubnetMask;\r
+ EFI_IP4 (Ip4Config->RouteTable[0].GatewayAddress) = 0;\r
+\r
+ //\r
+ // Create a route if there is a default router.\r
+ //\r
+ if (EFI_IP4 (Dhcp4Mode.RouterAddress) != 0) {\r
+ Ip4Config->RouteTableSize = 2;\r
+ EFI_IP4 (Ip4Config->RouteTable[1].SubnetAddress) = 0;\r
+ EFI_IP4 (Ip4Config->RouteTable[1].SubnetMask) = 0;\r
+ Ip4Config->RouteTable[1].GatewayAddress = Dhcp4Mode.RouterAddress;\r
+ }\r
+\r
+ Instance->Result = EFI_SUCCESS;\r
+\r
+ //\r
+ // ignore the return status of EfiNicIp4ConfigSetInfo. Network\r
+ // stack can operate even that failed.\r
+ //\r
+ EfiNicIp4ConfigSetInfo (&Instance->NicIp4Protocol, Instance->NicConfig, FALSE);\r
+ }\r
+\r
+ON_EXIT:\r
+ gBS->SignalEvent (Instance->DoneEvent);\r
+ Ip4ConfigCleanDhcp4 (Instance);\r
+ return ;\r
+}\r
+\r
+\r
+/**\r
+ Release all the DHCP related resources.\r
+\r
+ @param This The IP4 configure instance\r
+\r
+ @return None\r
+\r
+**/\r
+VOID\r
+Ip4ConfigCleanDhcp4 (\r
+ IN IP4_CONFIG_INSTANCE *This\r
+ )\r
+{\r
+ if (This->Dhcp4 != NULL) {\r
+ This->Dhcp4->Stop (This->Dhcp4);\r
+\r
+ gBS->CloseProtocol (\r
+ This->Dhcp4Handle,\r
+ &gEfiDhcp4ProtocolGuid,\r
+ This->Image,\r
+ This->Controller\r
+ );\r
+\r
+ This->Dhcp4 = NULL;\r
+ }\r
+\r
+ if (This->Dhcp4Handle != NULL) {\r
+ NetLibDestroyServiceChild (\r
+ This->Controller,\r
+ This->Image,\r
+ &gEfiDhcp4ServiceBindingProtocolGuid,\r
+ This->Dhcp4Handle\r
+ );\r
+\r
+ This->Dhcp4Handle = NULL;\r
+ }\r
+\r
+ if (This->Dhcp4Event == NULL) {\r
+ gBS->CloseEvent (This->Dhcp4Event);\r
+ This->Dhcp4Event = NULL;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Clean up all the configuration parameters\r
+\r
+ @param Instance The IP4 configure instance\r
+\r
+ @return None\r
+\r
+**/\r
+VOID\r
+Ip4ConfigCleanConfig (\r
+ IN IP4_CONFIG_INSTANCE *Instance\r
+ )\r
+{\r
+ if (Instance->NicConfig != NULL) {\r
+ NetFreePool (Instance->NicConfig);\r
+ Instance->NicConfig = NULL;\r
+ }\r
+\r
+ Instance->State = IP4_CONFIG_STATE_IDLE;\r
+ Instance->DoneEvent = NULL;\r
+ Instance->ReconfigEvent = NULL;\r
+\r
+ Ip4ConfigCleanDhcp4 (Instance);\r
+}\r
+\r
+EFI_IP4_CONFIG_PROTOCOL mIp4ConfigProtocolTemplate = {\r
+ EfiIp4ConfigStart,\r
+ EfiIp4ConfigStop,\r
+ EfiIp4ConfigGetData\r
+};\r
+\r
+EFI_NIC_IP4_CONFIG_PROTOCOL mNicIp4ConfigProtocolTemplate = {\r
+ EfiNicIp4ConfigGetName,\r
+ EfiNicIp4ConfigGetInfo,\r
+ EfiNicIp4ConfigSetInfo\r
+};\r
--- /dev/null
+/** @file
+
+Copyright (c) 2006 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ip4Config.h
+
+Abstract:
+
+ Header file for IP4Config driver.
+
+
+**/
+
+#ifndef __EFI_IP4CONFIG_H__
+#define __EFI_IP4CONFIG_H__
+
+#include <PiDxe.h>\r
+\r
+#include <Protocol/Dhcp4.h>\r
+#include <Protocol/IP4Config.h>\r
+#include <Protocol/ManagedNetwork.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/NetLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>
+
+#include "NicIp4Variable.h"
+
+typedef struct _IP4_CONFIG_INSTANCE IP4_CONFIG_INSTANCE;
+
+enum {
+ IP4_CONFIG_STATE_IDLE = 0,
+ IP4_CONFIG_STATE_STARTED,
+ IP4_CONFIG_STATE_CONFIGURED,
+
+ IP4_PROTO_ICMP = 0x01,
+ IP4_CONFIG_INSTANCE_SIGNATURE = EFI_SIGNATURE_32 ('I', 'P', '4', 'C'),
+
+ DHCP_TAG_PARA_LIST = 55,
+ DHCP_TAG_NETMASK = 1,
+ DHCP_TAG_ROUTER = 3,
+};
+
+//
+// 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_CONFIG_DHCP4_OPTION;
+#pragma pack()
+
+typedef struct _IP4_CONFIG_INSTANCE {
+ UINT32 Signature;
+ EFI_HANDLE Controller;
+ EFI_HANDLE Image;
+
+ EFI_IP4_CONFIG_PROTOCOL Ip4ConfigProtocol;
+ EFI_NIC_IP4_CONFIG_PROTOCOL NicIp4Protocol;
+
+ //
+ // NicConfig's state, such as IP4_CONFIG_STATE_IDLE
+ //
+ INTN State;
+
+ //
+ // Mnp child to keep the connection with MNP.
+ //
+ EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
+ EFI_HANDLE MnpHandle;
+
+ //
+ // User's requests data
+ //
+ EFI_EVENT DoneEvent;
+ EFI_EVENT ReconfigEvent;
+ EFI_STATUS Result;
+
+ //
+ // Identity of this interface and some configuration info.
+ //
+ NIC_ADDR NicAddr;
+ UINT16 NicName[IP4_NIC_NAME_LENGTH];
+ UINT32 NicIndex;
+ NIC_IP4_CONFIG_INFO *NicConfig;
+
+ //
+ // DHCP handles to access DHCP
+ //
+ EFI_DHCP4_PROTOCOL *Dhcp4;
+ EFI_HANDLE Dhcp4Handle;
+ EFI_EVENT Dhcp4Event;
+};
+
+#define IP4_CONFIG_INSTANCE_FROM_IP4CONFIG(this) \
+ CR (this, IP4_CONFIG_INSTANCE, Ip4ConfigProtocol, IP4_CONFIG_INSTANCE_SIGNATURE)
+
+#define IP4_CONFIG_INSTANCE_FROM_NIC_IP4CONFIG(this) \
+ CR (this, IP4_CONFIG_INSTANCE, NicIp4Protocol, IP4_CONFIG_INSTANCE_SIGNATURE)
+
+extern EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gIp4ConfigComponentName;
+extern IP4_CONFIG_INSTANCE *mIp4ConfigNicList[MAX_IP4_CONFIG_IN_VARIABLE];
+extern EFI_IP4_CONFIG_PROTOCOL mIp4ConfigProtocolTemplate;
+extern EFI_NIC_IP4_CONFIG_PROTOCOL mNicIp4ConfigProtocolTemplate;
+
+VOID
+Ip4ConfigCleanDhcp4 (
+ IN IP4_CONFIG_INSTANCE *This
+ );
+
+VOID
+Ip4ConfigCleanConfig (
+ IN IP4_CONFIG_INSTANCE *Instance
+ );
+#endif
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ Ip4ConfigDriver.c\r
+\r
+Abstract:\r
+\r
+ The driver binding for IP4 CONFIG protocol.\r
+\r
+\r
+**/\r
+\r
+\r
+#include "Ip4Config.h"\r
+\r
+\r
+/**\r
+ Stop all the auto configuration when the IP4 configure driver is\r
+ being unloaded.\r
+\r
+ @param ImageHandle The driver that is being unloaded\r
+\r
+ @retval EFI_SUCCESS The driver has been ready for unload.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiIp4ConfigUnload (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ UINT32 Index;\r
+\r
+ //\r
+ // Stop all the IP4_CONFIG instances\r
+ //\r
+ for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {\r
+ if (mIp4ConfigNicList[Index] == NULL) {\r
+ continue;\r
+ }\r
+\r
+ gIp4ConfigDriverBinding.Stop (\r
+ &gIp4ConfigDriverBinding,\r
+ mIp4ConfigNicList[Index]->MnpHandle,\r
+ 0,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ return NetLibDefaultUnload (ImageHandle);\r
+}\r
+\r
+//@MT: EFI_DRIVER_ENTRY_POINT (Ip4ConfigDriverEntryPoint)\r
+\r
+EFI_STATUS\r
+Ip4ConfigDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ The entry point for IP4 config driver which install the driver\r
+ binding and component name protocol on its image.\r
+\r
+Arguments:\r
+\r
+ ImageHandle - The Image handle of the driver\r
+ SystemTable - The system table\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - All the related protocols are installed on the driver\r
+ Others - Failed to install the protocol\r
+\r
+--*/\r
+{\r
+ return NetLibInstallAllDriverProtocolsWithUnload (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gIp4ConfigDriverBinding,\r
+ ImageHandle,\r
+ &gIp4ConfigComponentName,\r
+ NULL,\r
+ NULL,\r
+ EfiIp4ConfigUnload\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Test to see if this driver supports ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver supports this device\r
+ @retval EFI_ALREADY_STARTED This driver is already running on this device\r
+ @retval other This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Ip4ConfigDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Start this driver on ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver is added to ControllerHandle\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
+ @retval other This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Ip4ConfigDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ EFI_IP4_CONFIG_PROTOCOL *Ip4Config;\r
+ EFI_MANAGED_NETWORK_PROTOCOL *Mnp;\r
+ EFI_HANDLE MnpHandle;\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ EFI_SIMPLE_NETWORK_MODE SnpMode;\r
+ IP4_CONFIG_VARIABLE *Variable;\r
+ NIC_IP4_CONFIG_INFO *NicConfig;\r
+ IP4_CONFIG_VARIABLE *NewVariable;\r
+ EFI_STATUS Status;\r
+ UINT32 Index;\r
+\r
+ //\r
+ // Check for multiple start.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiIp4ConfigProtocolGuid,\r
+ &Ip4Config,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ //\r
+ // Create a MNP child\r
+ //\r
+ Mnp = NULL;\r
+ MnpHandle = NULL;\r
+ Instance = NULL;\r
+\r
+ Status = NetLibCreateServiceChild (\r
+ ControllerHandle,\r
+ This->DriverBindingHandle,\r
+ &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ &MnpHandle\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ MnpHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ (VOID **) &Mnp,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Allocate an instance then initialize it\r
+ //\r
+ Instance = NetAllocatePool (sizeof (IP4_CONFIG_INSTANCE));\r
+\r
+ if (Instance == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Instance->Signature = IP4_CONFIG_INSTANCE_SIGNATURE;\r
+ Instance->Controller = ControllerHandle;\r
+ Instance->Image = This->DriverBindingHandle;\r
+\r
+ Instance->Ip4ConfigProtocol = mIp4ConfigProtocolTemplate;\r
+ Instance->NicIp4Protocol = mNicIp4ConfigProtocolTemplate;\r
+\r
+ Instance->State = IP4_CONFIG_STATE_IDLE;\r
+ Instance->Mnp = Mnp;\r
+ Instance->MnpHandle = MnpHandle;\r
+\r
+ Instance->DoneEvent = NULL;\r
+ Instance->ReconfigEvent = NULL;\r
+ Instance->Result = EFI_NOT_READY;\r
+ Instance->NicConfig = NULL;\r
+\r
+ Instance->Dhcp4 = NULL;\r
+ Instance->Dhcp4Handle = NULL;\r
+ Instance->Dhcp4Event = NULL;\r
+\r
+ Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);\r
+\r
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ Instance->NicAddr.Type = (UINT16) SnpMode.IfType;\r
+ Instance->NicAddr.Len = (UINT8) SnpMode.HwAddressSize;\r
+ Instance->NicAddr.MacAddr = SnpMode.CurrentAddress;\r
+\r
+ //\r
+ // Add it to the global list, and compose the name\r
+ //\r
+ for (Index = 0; Index < MAX_IP4_CONFIG_IN_VARIABLE; Index++) {\r
+ if (mIp4ConfigNicList[Index] == NULL) {\r
+ mIp4ConfigNicList[Index] = Instance;\r
+ Instance->NicIndex = Index;\r
+\r
+ if (Instance->NicAddr.Type == NET_IFTYPE_ETHERNET) {\r
+ Instance->NicName[0] = 'e';\r
+ Instance->NicName[1] = 't';\r
+ Instance->NicName[2] = 'h';\r
+ Instance->NicName[3] = (UINT16) ('0' + Index);\r
+ Instance->NicName[4] = 0;\r
+ } else {\r
+ Instance->NicName[0] = 'u';\r
+ Instance->NicName[1] = 'n';\r
+ Instance->NicName[2] = 'k';\r
+ Instance->NicName[3] = (UINT16) ('0' + Index);\r
+ Instance->NicName[4] = 0;\r
+ }\r
+\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Index == MAX_IP4_CONFIG_IN_VARIABLE) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Install the IP4_CONFIG and NIC_IP4CONFIG protocols\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &ControllerHandle,\r
+ &gEfiIp4ConfigProtocolGuid,\r
+ &Instance->Ip4ConfigProtocol,\r
+ &gEfiNicIp4ConfigProtocolGuid,\r
+ &Instance->NicIp4Protocol,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ mIp4ConfigNicList[Index] = NULL;\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Get the previous configure parameters. If an error happend here,\r
+ // just ignore it because the driver should be able to operate.\r
+ //\r
+ Variable = Ip4ConfigReadVariable ();\r
+\r
+ if (Variable == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ NicConfig = Ip4ConfigFindNicVariable (Variable, &Instance->NicAddr);\r
+\r
+ if (NicConfig == NULL) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Don't modify the permant static configuration\r
+ //\r
+ if (NicConfig->Perment && (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Delete the non-permant configuration and remove the previous\r
+ // acquired DHCP parameters. Only doing DHCP itself is permant\r
+ //\r
+ NewVariable = NULL;\r
+\r
+ if (!NicConfig->Perment) {\r
+ NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NULL);\r
+\r
+ } else if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {\r
+ NetZeroMem (&NicConfig->Ip4Info, sizeof (EFI_IP4_IPCONFIG_DATA));\r
+ NewVariable = Ip4ConfigModifyVariable (Variable, &Instance->NicAddr, NicConfig);\r
+\r
+ }\r
+\r
+ Ip4ConfigWriteVariable (NewVariable);\r
+\r
+ if (NewVariable != NULL) {\r
+ NetFreePool (NewVariable);\r
+ }\r
+\r
+ON_EXIT:\r
+ NetFreePool (Variable);\r
+\r
+ if (NicConfig != NULL) {\r
+ NetFreePool (NicConfig);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+ if (Instance != NULL) {\r
+ NetFreePool (Instance);\r
+ }\r
+\r
+ if (Mnp != NULL) {\r
+ gBS->CloseProtocol (\r
+ MnpHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle\r
+ );\r
+ }\r
+\r
+ NetLibDestroyServiceChild (\r
+ ControllerHandle,\r
+ This->DriverBindingHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ MnpHandle\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Stop this driver on ControllerHandle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCES This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Ip4ConfigDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+{\r
+ IP4_CONFIG_INSTANCE *Instance;\r
+ EFI_IP4_CONFIG_PROTOCOL *Ip4Config;\r
+ EFI_HANDLE NicHandle;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // IP4_CONFIG instance opens an MNP child. It may also create and open\r
+ // a DHCP child. If this is the DHCP handle, stop the DHCP process. If\r
+ // it is the MNP child, stop the whole driver.\r
+ //\r
+ //\r
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);\r
+\r
+ if (NicHandle != NULL) {\r
+ //\r
+ // Get our context back then clean the DHCP up. Notify the user if necessary.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ NicHandle,\r
+ &gEfiIp4ConfigProtocolGuid,\r
+ (VOID **) &Ip4Config,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);\r
+ ASSERT (ControllerHandle == Instance->Dhcp4Handle);\r
+\r
+ Ip4ConfigCleanDhcp4 (Instance);\r
+\r
+ Instance->State = IP4_CONFIG_STATE_CONFIGURED;\r
+ Instance->Result = EFI_DEVICE_ERROR;\r
+\r
+ if (Instance->DoneEvent != NULL) {\r
+ gBS->SignalEvent (Instance->DoneEvent);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // This is a MNP handle, stop the whole driver\r
+ //\r
+ NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);\r
+\r
+ if (NicHandle == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Get our context back.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ NicHandle,\r
+ &gEfiIp4ConfigProtocolGuid,\r
+ (VOID **) &Ip4Config,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Instance = IP4_CONFIG_INSTANCE_FROM_IP4CONFIG (Ip4Config);\r
+\r
+ //\r
+ // Unload the protocols first to inform the top drivers\r
+ //\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ NicHandle,\r
+ &gEfiIp4ConfigProtocolGuid,\r
+ &Instance->Ip4ConfigProtocol,\r
+ &gEfiNicIp4ConfigProtocolGuid,\r
+ &Instance->NicIp4Protocol,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Release all the resources\r
+ //\r
+ if (Instance->MnpHandle != NULL) {\r
+ gBS->CloseProtocol (\r
+ Instance->MnpHandle,\r
+ &gEfiManagedNetworkProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ NicHandle\r
+ );\r
+\r
+ NetLibDestroyServiceChild (\r
+ NicHandle,\r
+ Instance->Image,\r
+ &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+ Instance->MnpHandle\r
+ );\r
+\r
+ Instance->Mnp = NULL;\r
+ Instance->MnpHandle = NULL;\r
+ }\r
+\r
+ Ip4ConfigCleanConfig (Instance);\r
+ mIp4ConfigNicList[Instance->NicIndex] = NULL;\r
+ NetFreePool (Instance);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gIp4ConfigDriverBinding = {\r
+ Ip4ConfigDriverBindingSupported,\r
+ Ip4ConfigDriverBindingStart,\r
+ Ip4ConfigDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
--- /dev/null
+#/** @file\r
+# Component name for module Ip4Config\r
+#\r
+# FIX ME!\r
+# Copyright (c) 2006, Intel Corporation. All right reserved.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = Ip4ConfigDxe\r
+ FILE_GUID = 26841BDE-920A-4e7a-9FBE-637F477143A6\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ EDK_RELEASE_VERSION = 0x00020000\r
+ EFI_SPECIFICATION_VERSION = 0x00020000\r
+\r
+ ENTRY_POINT = Ip4ConfigDriverEntryPoint\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+ ComponentName.c\r
+ NicIp4Variable.c\r
+ Ip4ConfigDriver.c\r
+ Ip4Config.h\r
+ NicIp4Variable.h\r
+ Ip4Config.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+ UefiLib\r
+ UefiBootServicesTableLib\r
+ UefiDriverEntryPoint\r
+ UefiRuntimeServicesTableLib\r
+ DebugLib\r
+ NetLib\r
+\r
+\r
+[Protocols]\r
+ gEfiDhcp4ServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
+ gEfiManagedNetworkServiceBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
+ gEfiIp4ConfigProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
+ gEfiManagedNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
+ gEfiDhcp4ProtocolGuid # PROTOCOL ALWAYS_CONSUMED\r
+ gEfiNicIp4ConfigVariableGuid # PROTOCOL ALWAYS_CONSUMED\r
+ gEfiNicIp4ConfigProtocolGuid # PROTOCOL ALWAYS_CONSUMED
\ No newline at end of file
--- /dev/null
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <MsaHeader>\r
+ <ModuleName>Ip4Config</ModuleName>\r
+ <ModuleType>DXE_DRIVER</ModuleType>\r
+ <GuidValue>26841BDE-920A-4e7a-9FBE-637F477143A6</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>Component name for module Ip4Config</Abstract>\r
+ <Description>FIX ME!</Description>\r
+ <Copyright>Copyright (c) 2006, Intel Corporation. All right reserved.</Copyright>\r
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>Ip4Config</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverEntryPoint</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>Ip4Config.c</Filename>\r
+ <Filename>NicIp4Variable.h</Filename>\r
+ <Filename>Ip4Config.h</Filename>\r
+ <Filename>Ip4ConfigDriver.c</Filename>\r
+ <Filename>NicIp4Variable.c</Filename>\r
+ <Filename>ComponentName.c</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+ </PackageDependencies>\r
+ <Protocols>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiDhcp4ProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiManagedNetworkProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiIp4ConfigProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiManagedNetworkServiceBindingProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiDhcp4ServiceBindingProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+ <Extern>\r
+ <ModuleEntryPoint>Ip4ConfigDriverEntryPoint</ModuleEntryPoint>\r
+ </Extern>\r
+ </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ NicIp4Variable.c\r
+\r
+Abstract:\r
+\r
+ Routines used to operate the Ip4 configure variable\r
+\r
+\r
+**/\r
+\r
+\r
+#include <Library/NetLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+\r
+#include "NicIp4Variable.h"\r
+\r
+\r
+/**\r
+ Check whether the configure parameter is valid.\r
+\r
+ @param NicConfig The configure parameter to check\r
+\r
+ @return TRUE if the parameter is valid for the interface, otherwise FALSE.\r
+\r
+**/\r
+BOOLEAN\r
+Ip4ConfigIsValid (\r
+ IN NIC_IP4_CONFIG_INFO *NicConfig\r
+ )\r
+{\r
+ EFI_IP4_IPCONFIG_DATA *IpConfig;\r
+ IP4_ADDR Station;\r
+ IP4_ADDR Netmask;\r
+ IP4_ADDR Gateway;\r
+ UINT32 Index;\r
+\r
+ IpConfig = &NicConfig->Ip4Info;\r
+\r
+ if (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC) {\r
+ //\r
+ // Validate that the addresses are unicast and mask\r
+ // is properly formated\r
+ //\r
+ Station = EFI_NTOHL (IpConfig->StationAddress);\r
+ Netmask = EFI_NTOHL (IpConfig->SubnetMask);\r
+\r
+ if ((Netmask == 0) || !IP4_IS_VALID_NETMASK (Netmask) ||\r
+ (Station == 0) || !Ip4IsUnicast (Station, Netmask)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Validate that the next hops are on the connected network\r
+ // or that is a direct route (Gateway == 0).\r
+ //\r
+ for (Index = 0; Index < IpConfig->RouteTableSize; Index++) {\r
+ Gateway = EFI_NTOHL (IpConfig->RouteTable[Index].GatewayAddress);\r
+\r
+ if ((Gateway != 0) && (!IP4_NET_EQUAL (Station, Gateway, Netmask) ||\r
+ !Ip4IsUnicast (Gateway, Netmask))) {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+ }\r
+\r
+ //\r
+ // return false if it is an unkown configure source. Valid\r
+ // sources are static and dhcp.\r
+ //\r
+ return (BOOLEAN) (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);\r
+}\r
+\r
+\r
+\r
+/**\r
+ Read the ip4 configure variable from the EFI variable\r
+\r
+ None\r
+\r
+ @return The IP4 configure read if it is there and is valid, otherwise NULL\r
+\r
+**/\r
+IP4_CONFIG_VARIABLE *\r
+Ip4ConfigReadVariable (\r
+ VOID\r
+ )\r
+{\r
+ IP4_CONFIG_VARIABLE *Variable;\r
+ EFI_STATUS Status;\r
+ UINTN Size;\r
+ UINT16 CheckSum;\r
+\r
+ //\r
+ // Get the size of variable, then allocate a buffer to read the variable.\r
+ //\r
+ Size = 0;\r
+ Variable = NULL;\r
+ Status = gRT->GetVariable (\r
+ EFI_NIC_IP4_CONFIG_VARIABLE,\r
+ &gEfiNicIp4ConfigVariableGuid,\r
+ NULL,\r
+ &Size,\r
+ NULL\r
+ );\r
+\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ return NULL;\r
+ }\r
+\r
+ if (Size < sizeof (IP4_CONFIG_VARIABLE)) {\r
+ goto REMOVE_VARIABLE;\r
+ }\r
+\r
+ Variable = NetAllocatePool (Size);\r
+\r
+ if (Variable == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ Status = gRT->GetVariable (\r
+ EFI_NIC_IP4_CONFIG_VARIABLE,\r
+ &gEfiNicIp4ConfigVariableGuid,\r
+ NULL,\r
+ &Size,\r
+ Variable\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Verify the checksum, variable size and count\r
+ //\r
+ CheckSum = ~NetblockChecksum ((UINT8 *) Variable, (UINT32)Size);\r
+\r
+ if ((CheckSum != 0) || (Size != Variable->Len)) {\r
+ goto REMOVE_VARIABLE;\r
+ }\r
+\r
+ if ((Variable->Count < 1) || (Variable->Count > MAX_IP4_CONFIG_IN_VARIABLE)) {\r
+ goto REMOVE_VARIABLE;\r
+ }\r
+\r
+ return Variable;\r
+\r
+REMOVE_VARIABLE:\r
+ Ip4ConfigWriteVariable (NULL);\r
+\r
+ON_ERROR:\r
+ if (Variable != NULL) {\r
+ NetFreePool (Variable);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+\r
+/**\r
+ Write the IP4 configure variable to the NVRAM. If Config\r
+ is NULL, remove the variable.\r
+\r
+ @param Config The IP4 configure data to write\r
+\r
+ @retval EFI_SUCCESS The variable is written to the NVRam\r
+ @retval Others Failed to write the variable.\r
+\r
+**/\r
+EFI_STATUS\r
+Ip4ConfigWriteVariable (\r
+ IN IP4_CONFIG_VARIABLE * Config OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = gRT->SetVariable (\r
+ EFI_NIC_IP4_CONFIG_VARIABLE,\r
+ &gEfiNicIp4ConfigVariableGuid,\r
+ IP4_CONFIG_VARIABLE_ATTRIBUTES,\r
+ (Config == NULL) ? 0 : Config->Len,\r
+ Config\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Locate the IP4 configure parameters from the variable.If a\r
+ configuration is found, copy it to a newly allocated block\r
+ of memory to avoid the alignment problem. Caller should\r
+ release the memory after use.\r
+\r
+ @param Variable The IP4 configure variable to search in\r
+ @param NicAddr The interface address to check\r
+\r
+ @return The point to the NIC's IP4 configure info if it is found\r
+ @return in the IP4 variable, otherwise NULL.\r
+\r
+**/\r
+NIC_IP4_CONFIG_INFO *\r
+Ip4ConfigFindNicVariable (\r
+ IN IP4_CONFIG_VARIABLE *Variable,\r
+ IN NIC_ADDR *NicAddr\r
+ )\r
+{\r
+ NIC_IP4_CONFIG_INFO Temp;\r
+ NIC_IP4_CONFIG_INFO *Config;\r
+ UINT32 Index;\r
+ UINT8 *Cur;\r
+ UINT32 Len;\r
+\r
+ Cur = (UINT8*)&Variable->ConfigInfo;\r
+\r
+ for (Index = 0; Index < Variable->Count; Index++) {\r
+ //\r
+ // Copy the data to Temp to avoid the alignment problems\r
+ //\r
+ NetCopyMem (&Temp, Cur, sizeof (NIC_IP4_CONFIG_INFO));\r
+ Len = SIZEOF_NIC_IP4_CONFIG_INFO (&Temp);\r
+\r
+ //\r
+ // Found the matching configuration parameters, allocate\r
+ // a block of memory then copy it out.\r
+ //\r
+ if (NIC_ADDR_EQUAL (&Temp.NicAddr, NicAddr)) {\r
+ Config = NetAllocatePool (Len);\r
+\r
+ if (Config == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ NetCopyMem (Config, Cur, Len);\r
+ return Config;\r
+ }\r
+\r
+ Cur += Len;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+\r
+/**\r
+ Modify the configuration parameter for the NIC in the variable.\r
+ If Config is NULL, old configuration will be remove from the new\r
+ variable. Otherwise, append it or replace the old one.\r
+\r
+ @param Variable The IP4 variable to change\r
+ @param NicAddr The interface to search\r
+ @param Config The new configuration parameter (NULL to remove the old)\r
+\r
+ @return The new IP4_CONFIG_VARIABLE variable if the new variable has at\r
+ @return least one NIC configure and no EFI_OUT_OF_RESOURCES failure.\r
+ @return Return NULL either because failed to locate memory for new variable\r
+ @return or the only NIC configure is removed from the Variable.\r
+\r
+**/\r
+IP4_CONFIG_VARIABLE *\r
+Ip4ConfigModifyVariable (\r
+ IN IP4_CONFIG_VARIABLE *Variable, OPTIONAL\r
+ IN NIC_ADDR *NicAddr,\r
+ IN NIC_IP4_CONFIG_INFO *Config OPTIONAL\r
+ )\r
+{\r
+ NIC_IP4_CONFIG_INFO Temp;\r
+ NIC_IP4_CONFIG_INFO *Old;\r
+ IP4_CONFIG_VARIABLE *NewVar;\r
+ UINT32 Len;\r
+ UINT32 TotalLen;\r
+ UINT32 Count;\r
+ UINT8 *Next;\r
+ UINT8 *Cur;\r
+ UINT32 Index;\r
+\r
+ ASSERT ((Variable != NULL) || (Config != NULL));\r
+\r
+ //\r
+ // Compute the total length\r
+ //\r
+ if (Variable != NULL) {\r
+ //\r
+ // Variable != NULL, then Config can be NULL or not. and so is\r
+ // the Old. If old configure exists, it is removed from the\r
+ // Variable. New configure is append to the variable.\r
+ //\r
+ //\r
+ Count = Variable->Count;\r
+ Cur = (UINT8 *)&Variable->ConfigInfo;\r
+ TotalLen = Variable->Len;\r
+\r
+ Old = Ip4ConfigFindNicVariable (Variable, NicAddr);\r
+\r
+ if (Old != NULL) {\r
+ TotalLen -= SIZEOF_NIC_IP4_CONFIG_INFO (Old);\r
+ NetFreePool (Old);\r
+ }\r
+\r
+ if (Config != NULL) {\r
+ TotalLen += SIZEOF_NIC_IP4_CONFIG_INFO (Config);\r
+ }\r
+\r
+ //\r
+ // Return NULL if the only NIC_IP4_CONFIG_INFO is being removed.\r
+ //\r
+ if (TotalLen < sizeof (IP4_CONFIG_VARIABLE)) {\r
+ return NULL;\r
+ }\r
+\r
+ } else {\r
+ //\r
+ // Variable == NULL and Config != NULL, Create a new variable with\r
+ // this NIC configure.\r
+ //\r
+ Count = 0;\r
+ Cur = NULL;\r
+ TotalLen = sizeof (IP4_CONFIG_VARIABLE) - sizeof (NIC_IP4_CONFIG_INFO)\r
+ + SIZEOF_NIC_IP4_CONFIG_INFO (Config);\r
+ }\r
+\r
+ ASSERT (TotalLen >= sizeof (IP4_CONFIG_VARIABLE));\r
+\r
+ NewVar = NetAllocateZeroPool (TotalLen);\r
+\r
+ if (NewVar == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ NewVar->Len = TotalLen;\r
+\r
+ //\r
+ // Copy the other configure parameters from the old variable\r
+ //\r
+ Next = (UINT8 *)&NewVar->ConfigInfo;\r
+\r
+ for (Index = 0; Index < Count; Index++) {\r
+ NetCopyMem (&Temp, Cur, sizeof (NIC_IP4_CONFIG_INFO));\r
+ Len = SIZEOF_NIC_IP4_CONFIG_INFO (&Temp);\r
+\r
+ if (!NIC_ADDR_EQUAL (&Temp.NicAddr, NicAddr)) {\r
+ NetCopyMem (Next, Cur, Len);\r
+ Next += Len;\r
+ NewVar->Count++;\r
+ }\r
+\r
+ Cur += Len;\r
+ }\r
+\r
+ //\r
+ // Append the new configure if it isn't NULL.\r
+ //\r
+ Len = 0;\r
+\r
+ if (Config != NULL) {\r
+ Len = SIZEOF_NIC_IP4_CONFIG_INFO (Config);\r
+\r
+ NetCopyMem (Next, Config, Len);\r
+ NewVar->Count++;\r
+ }\r
+\r
+ ASSERT (Next + Len == (UINT8 *) NewVar + TotalLen);\r
+\r
+ NewVar->CheckSum = ~NetblockChecksum ((UINT8 *) NewVar, TotalLen);\r
+ return NewVar;\r
+}\r
--- /dev/null
+/** @file
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ NicIp4Variable.h
+
+Abstract:
+
+ Routines used to operate the Ip4 configure variable
+
+
+**/
+
+#ifndef _NIC_IP4_VARIABLE_H_
+#define _NIC_IP4_VARIABLE_H_
+
+
+#include <Protocol/NicIp4Config.h>
+
+//
+// Return the size of NIC_IP4_CONFIG_INFO and EFI_IP4_IPCONFIG_DATA.
+// They are of variable size
+//
+#define SIZEOF_IP4_CONFIG_INFO(Ip4Config) \
+ (sizeof (EFI_IP4_IPCONFIG_DATA) + \
+ sizeof (EFI_IP4_ROUTE_TABLE) * (NET_MAX (1, (Ip4Config)->RouteTableSize) - 1))
+
+#define SIZEOF_NIC_IP4_CONFIG_INFO(NicConfig) \
+ (sizeof (NIC_IP4_CONFIG_INFO) + \
+ sizeof (EFI_IP4_ROUTE_TABLE) * (NET_MAX (1, (NicConfig)->Ip4Info.RouteTableSize) - 1))
+
+//
+// Compare whether two NIC address are equal includes their type and length.
+//
+#define NIC_ADDR_EQUAL(Nic1, Nic2) \
+ (((Nic1)->Type == (Nic2)->Type) && ((Nic1)->Len == (Nic2)->Len) && \
+ NET_MAC_EQUAL (&(Nic1)->MacAddr, &(Nic2)->MacAddr, (Nic1)->Len))
+
+BOOLEAN
+Ip4ConfigIsValid (
+ IN NIC_IP4_CONFIG_INFO *NicConfig
+ );
+
+IP4_CONFIG_VARIABLE *
+Ip4ConfigReadVariable (
+ VOID
+ );
+
+EFI_STATUS
+Ip4ConfigWriteVariable (
+ IN IP4_CONFIG_VARIABLE *Config OPTIONAL
+ );
+
+NIC_IP4_CONFIG_INFO *
+Ip4ConfigFindNicVariable (
+ IN IP4_CONFIG_VARIABLE *Variable,
+ IN NIC_ADDR *NicAddr
+ );
+
+IP4_CONFIG_VARIABLE *
+Ip4ConfigModifyVariable (
+ IN IP4_CONFIG_VARIABLE *Variable, OPTIONAL
+ IN NIC_ADDR *NicAddr,
+ IN NIC_IP4_CONFIG_INFO *Config OPTIONAL
+ );
+#endif