]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/HttpDxe/HttpDns.c
NetworkPkg: Stop and release DHCP4 child after boot info is ready
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpDns.c
CommitLineData
47f51a06
YT
1/** @file\r
2 Routines for HttpDxe driver to perform DNS resolution based on UEFI DNS protocols.\r
3\r
4Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "HttpDriver.h"\r
16\r
17/**\r
18 Retrieve the host address using the EFI_DNS4_PROTOCOL.\r
19\r
20 @param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.\r
21 @param[in] HostName Pointer to buffer containing hostname.\r
22 @param[out] IpAddress On output, pointer to buffer containing IPv4 address.\r
23\r
24 @retval EFI_SUCCESS Operation succeeded.\r
25 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
26 @retval EFI_DEVICE_ERROR An unexpected network error occurred.\r
27 @retval Others Other errors as indicated.\r
28 \r
29**/\r
30EFI_STATUS\r
31HttpDns4 (\r
32 IN HTTP_PROTOCOL *HttpInstance,\r
33 IN CHAR16 *HostName,\r
34 OUT EFI_IPv4_ADDRESS *IpAddress \r
35 )\r
36{\r
37 EFI_STATUS Status;\r
38 EFI_DNS4_PROTOCOL *Dns4;\r
39 EFI_DNS4_CONFIG_DATA Dns4CfgData;\r
40 EFI_DNS4_COMPLETION_TOKEN Token;\r
41 BOOLEAN IsDone;\r
42 HTTP_SERVICE *Service;\r
43 EFI_HANDLE Dns4Handle;\r
44 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;\r
45 UINTN DnsServerListCount;\r
46 EFI_IPv4_ADDRESS *DnsServerList;\r
47 UINTN DataSize;\r
48 \r
49\r
50 Service = HttpInstance->Service;\r
51 ASSERT (Service != NULL);\r
52\r
53 DnsServerList = NULL;\r
54 DnsServerListCount = 0;\r
55 ZeroMem (&Token, sizeof (EFI_DNS4_COMPLETION_TOKEN));\r
56\r
57 //\r
58 // Get DNS server list from EFI IPv4 Configuration II protocol.\r
59 //\r
60 Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2);\r
61 if (!EFI_ERROR (Status)) {\r
62 //\r
63 // Get the required size.\r
64 //\r
65 DataSize = 0;\r
66 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, NULL);\r
67 if (Status == EFI_BUFFER_TOO_SMALL) {\r
68 DnsServerList = AllocatePool (DataSize);\r
69 if (DnsServerList == NULL) {\r
70 return EFI_OUT_OF_RESOURCES;\r
71 }\r
72\r
73 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, DnsServerList);\r
74 if (EFI_ERROR (Status)) {\r
75 FreePool (DnsServerList);\r
76 DnsServerList = NULL;\r
77 } else {\r
78 DnsServerListCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
79 }\r
80 }\r
81 }\r
82\r
83 Dns4Handle = NULL;\r
84 Dns4 = NULL;\r
85 \r
86 //\r
87 // Create a DNS child instance and get the protocol.\r
88 //\r
89 Status = NetLibCreateServiceChild (\r
90 Service->ControllerHandle,\r
91 Service->ImageHandle,\r
92 &gEfiDns4ServiceBindingProtocolGuid,\r
93 &Dns4Handle\r
94 );\r
95 if (EFI_ERROR (Status)) {\r
96 goto Exit;\r
97 } \r
98\r
99 Status = gBS->OpenProtocol (\r
100 Dns4Handle,\r
101 &gEfiDns4ProtocolGuid,\r
102 (VOID **) &Dns4,\r
103 Service->ImageHandle,\r
104 Service->ControllerHandle,\r
105 EFI_OPEN_PROTOCOL_BY_DRIVER\r
106 );\r
107 if (EFI_ERROR (Status)) {\r
108 goto Exit;\r
109 }\r
110\r
111 //\r
112 // Configure DNS4 instance for the DNS server address and protocol.\r
113 //\r
114 ZeroMem (&Dns4CfgData, sizeof (Dns4CfgData));\r
115 Dns4CfgData.DnsServerListCount = DnsServerListCount;\r
116 Dns4CfgData.DnsServerList = DnsServerList;\r
117 Dns4CfgData.UseDefaultSetting = HttpInstance->IPv4Node.UseDefaultAddress;\r
118 if (!Dns4CfgData.UseDefaultSetting) {\r
119 IP4_COPY_ADDRESS (&Dns4CfgData.StationIp, &HttpInstance->IPv4Node.LocalAddress);\r
120 IP4_COPY_ADDRESS (&Dns4CfgData.SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);\r
121 }\r
122 Dns4CfgData.EnableDnsCache = TRUE;\r
123 Dns4CfgData.Protocol = EFI_IP_PROTO_UDP;\r
124 Status = Dns4->Configure (\r
125 Dns4,\r
126 &Dns4CfgData\r
127 );\r
128 if (EFI_ERROR (Status)) {\r
129 goto Exit;\r
130 }\r
131 \r
132 //\r
133 // Create event to set the is done flag when name resolution is finished.\r
134 //\r
135 ZeroMem (&Token, sizeof (Token));\r
136 Status = gBS->CreateEvent (\r
137 EVT_NOTIFY_SIGNAL,\r
138 TPL_NOTIFY,\r
139 HttpCommonNotify,\r
140 &IsDone,\r
141 &Token.Event\r
142 );\r
143 if (EFI_ERROR (Status)) {\r
144 goto Exit;\r
145 }\r
146\r
147 //\r
148 // Start asynchronous name resolution.\r
149 //\r
150 Token.Status = EFI_NOT_READY;\r
151 IsDone = FALSE;\r
152 Status = Dns4->HostNameToIp (Dns4, HostName, &Token);\r
153 if (EFI_ERROR (Status)) {\r
154 goto Exit;\r
155 }\r
156\r
157 while (!IsDone) {\r
158 Dns4->Poll (Dns4);\r
159 }\r
160\r
161 //\r
162 // Name resolution is done, check result.\r
163 //\r
164 Status = Token.Status; \r
165 if (!EFI_ERROR (Status)) {\r
166 if (Token.RspData.H2AData == NULL) {\r
167 Status = EFI_DEVICE_ERROR;\r
168 goto Exit;\r
169 }\r
170 if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) {\r
171 Status = EFI_DEVICE_ERROR;\r
172 goto Exit;\r
173 }\r
174 //\r
175 // We just return the first IP address from DNS protocol.\r
176 //\r
177 IP4_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);\r
178 Status = EFI_SUCCESS;\r
179 }\r
180\r
181Exit:\r
182 \r
183 if (Token.Event != NULL) {\r
184 gBS->CloseEvent (Token.Event);\r
185 }\r
186 if (Token.RspData.H2AData != NULL) {\r
187 if (Token.RspData.H2AData->IpList != NULL) {\r
188 FreePool (Token.RspData.H2AData->IpList);\r
189 }\r
190 FreePool (Token.RspData.H2AData);\r
191 }\r
192\r
193 if (Dns4 != NULL) {\r
194 Dns4->Configure (Dns4, NULL);\r
195 \r
196 gBS->CloseProtocol (\r
197 Dns4Handle,\r
198 &gEfiDns4ProtocolGuid,\r
199 Service->ImageHandle,\r
200 Service->ControllerHandle\r
201 );\r
202 }\r
203\r
204 if (Dns4Handle != NULL) {\r
205 NetLibDestroyServiceChild (\r
206 Service->ControllerHandle,\r
207 Service->ImageHandle,\r
208 &gEfiDns4ServiceBindingProtocolGuid,\r
209 Dns4Handle\r
210 );\r
211 }\r
212\r
213 if (DnsServerList != NULL) {\r
214 FreePool (DnsServerList);\r
215 }\r
216 \r
217 return Status;\r
218}\r