The implementation of EFI IPv4 Configuration II Protocol.\r
\r
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
}\r
}\r
\r
+/**\r
+ This worker function sets the DNS server list for the EFI IPv4 network\r
+ stack running on the communication device that this EFI_IP4_CONFIG2_PROTOCOL\r
+ manages. The DNS server addresses must be unicast IPv4 addresses. \r
+\r
+ @param[in] Instance The pointer to the IP4 config2 instance data.\r
+ @param[in] DataSize The size of the buffer pointed to by Data in bytes.\r
+ @param[in] Data The data buffer to set, points to an array of\r
+ EFI_IPv4_ADDRESS instances.\r
+\r
+ @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type.\r
+ @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid.\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation.\r
+ @retval EFI_ABORTED The DNS server addresses to be set equal the current\r
+ configuration.\r
+ @retval EFI_SUCCESS The specified configuration data for the EFI IPv4\r
+ network stack was set.\r
+\r
+**/\r
+EFI_STATUS\r
+Ip4Config2SetDnsServerWorker (\r
+ IN IP4_CONFIG2_INSTANCE *Instance,\r
+ IN UINTN DataSize,\r
+ IN VOID *Data\r
+ )\r
+{\r
+ UINTN OldIndex;\r
+ UINTN NewIndex;\r
+ UINTN Index1;\r
+ EFI_IPv4_ADDRESS *OldDns;\r
+ EFI_IPv4_ADDRESS *NewDns;\r
+ UINTN OldDnsCount;\r
+ UINTN NewDnsCount;\r
+ IP4_CONFIG2_DATA_ITEM *Item;\r
+ BOOLEAN OneAdded;\r
+ VOID *Tmp;\r
+ IP4_ADDR DnsAddress;\r
+\r
+ if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
+ NewDns = (EFI_IPv4_ADDRESS *) Data;\r
+ OldDns = Item->Data.DnsServers;\r
+ NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS); \r
+ OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
+ OneAdded = FALSE;\r
+\r
+ if (NewDnsCount != OldDnsCount) {\r
+ Tmp = AllocatePool (DataSize);\r
+ if (Tmp == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ } else {\r
+ Tmp = NULL;\r
+ }\r
+\r
+ for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {\r
+ CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));\r
+\r
+ if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {\r
+ //\r
+ // The dns server address must be unicast.\r
+ //\r
+ FreePool (Tmp);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {\r
+ if (EFI_IP4_EQUAL (NewDns + NewIndex, NewDns + Index1)) {\r
+ FreePool (Tmp);\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+\r
+ if (OneAdded) {\r
+ //\r
+ // If any address in the new setting is not in the old settings, skip the\r
+ // comparision below.\r
+ //\r
+ continue;\r
+ }\r
+\r
+ for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {\r
+ if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {\r
+ //\r
+ // If found break out.\r
+ //\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (OldIndex == OldDnsCount) {\r
+ OneAdded = TRUE;\r
+ }\r
+ }\r
+\r
+ if (!OneAdded && (DataSize == Item->DataSize)) {\r
+ //\r
+ // No new item is added and the size is the same.\r
+ //\r
+ Item->Status = EFI_SUCCESS;\r
+ return EFI_ABORTED;\r
+ } else {\r
+ if (Tmp != NULL) {\r
+ if (Item->Data.Ptr != NULL) {\r
+ FreePool (Item->Data.Ptr);\r
+ } \r
+ Item->Data.Ptr = Tmp;\r
+ }\r
+\r
+ CopyMem (Item->Data.Ptr, Data, DataSize);\r
+ Item->DataSize = DataSize;\r
+ Item->Status = EFI_SUCCESS;\r
+ return EFI_SUCCESS;\r
+ }\r
+}\r
+\r
+\r
\r
/**\r
Callback function when DHCP process finished. It will save the\r
IP4_ADDR StationAddress;\r
IP4_ADDR SubnetMask;\r
IP4_ADDR GatewayAddress;\r
+ UINT32 Index;\r
+ UINT32 OptionCount;\r
+ EFI_DHCP4_PACKET_OPTION **OptionList;\r
\r
Instance = (IP4_CONFIG2_INSTANCE *) Context;\r
ASSERT (Instance->Dhcp4 != NULL);\r
goto Exit;\r
}\r
\r
+ //\r
+ // Parse the ACK to get required DNS server information.\r
+ //\r
+ OptionCount = 0;\r
+ OptionList = NULL;\r
+\r
+ Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ goto Exit;\r
+ }\r
+\r
+ OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *));\r
+ if (OptionList == NULL) {\r
+ goto Exit;\r
+ }\r
+\r
+ Status = Instance->Dhcp4->Parse (Instance->Dhcp4, Dhcp4Mode.ReplyPacket, &OptionCount, OptionList);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (OptionList);\r
+ goto Exit;\r
+ }\r
+\r
+ for (Index = 0; Index < OptionCount; Index++) {\r
+ //\r
+ // Look for DNS Server opcode (6).\r
+ //\r
+ if (OptionList[Index]->OpCode == DHCP_TAG_DNS_SERVER) {\r
+ if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) {\r
+ break;\r
+ }\r
+\r
+ Ip4Config2SetDnsServerWorker (Instance, OptionList[Index]->Length, &OptionList[Index]->Data[0]);\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (OptionList);\r
+\r
Instance->DhcpSuccess = TRUE;\r
}\r
\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.Length = 3;\r
ParaList.Head.Data[0] = DHCP_TAG_NETMASK;\r
ParaList.Route = DHCP_TAG_ROUTER;\r
+ ParaList.Dns = DHCP_TAG_DNS_SERVER;\r
OptionList[0] = &ParaList.Head;\r
Dhcp4Mode.ConfigData.OptionCount = 1;\r
Dhcp4Mode.ConfigData.OptionList = OptionList;\r
IN VOID *Data\r
)\r
{\r
- UINTN OldIndex;\r
- UINTN NewIndex;\r
- UINTN Index1;\r
- EFI_IPv4_ADDRESS *OldDns;\r
- EFI_IPv4_ADDRESS *NewDns;\r
- UINTN OldDnsCount;\r
- UINTN NewDnsCount;\r
- IP4_CONFIG2_DATA_ITEM *Item;\r
- BOOLEAN OneAdded;\r
- VOID *Tmp;\r
- IP4_ADDR DnsAddress;\r
-\r
- if ((DataSize % sizeof (EFI_IPv4_ADDRESS) != 0) || (DataSize == 0)) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
if (Instance->Policy != Ip4Config2PolicyStatic) {\r
return EFI_WRITE_PROTECTED;\r
}\r
\r
- Item = &Instance->DataItem[Ip4Config2DataTypeDnsServer];\r
- NewDns = (EFI_IPv4_ADDRESS *) Data;\r
- OldDns = Item->Data.DnsServers;\r
- NewDnsCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
- OldDnsCount = Item->DataSize / sizeof (EFI_IPv4_ADDRESS);\r
- OneAdded = FALSE;\r
-\r
- if (NewDnsCount != OldDnsCount) {\r
- Tmp = AllocatePool (DataSize);\r
- if (Tmp == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- } else {\r
- Tmp = NULL;\r
- }\r
-\r
- for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) {\r
- CopyMem (&DnsAddress, NewDns + NewIndex, sizeof (IP4_ADDR));\r
-\r
- if (!NetIp4IsUnicast (NTOHL (DnsAddress), 0)) {\r
- //\r
- // The dns server address must be unicast.\r
- //\r
- FreePool (Tmp);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- for (Index1 = NewIndex + 1; Index1 < NewDnsCount; Index1++) {\r
- if (EFI_IP4_EQUAL (NewDns + NewIndex, NewDns + Index1)) {\r
- FreePool (Tmp);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
-\r
- if (OneAdded) {\r
- //\r
- // If any address in the new setting is not in the old settings, skip the\r
- // comparision below.\r
- //\r
- continue;\r
- }\r
-\r
- for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) {\r
- if (EFI_IP4_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) {\r
- //\r
- // If found break out.\r
- //\r
- break;\r
- }\r
- }\r
-\r
- if (OldIndex == OldDnsCount) {\r
- OneAdded = TRUE;\r
- }\r
- }\r
-\r
- if (!OneAdded && (DataSize == Item->DataSize)) {\r
- //\r
- // No new item is added and the size is the same.\r
- //\r
- Item->Status = EFI_SUCCESS;\r
- return EFI_ABORTED;\r
- } else {\r
- if (Tmp != NULL) {\r
- if (Item->Data.Ptr != NULL) {\r
- FreePool (Item->Data.Ptr);\r
- } \r
- Item->Data.Ptr = Tmp;\r
- }\r
-\r
- CopyMem (Item->Data.Ptr, Data, DataSize);\r
- Item->DataSize = DataSize;\r
- Item->Status = EFI_SUCCESS;\r
- return EFI_SUCCESS;\r
- }\r
-\r
+ return Ip4Config2SetDnsServerWorker (Instance, DataSize, Data);\r
}\r
\r
/**\r