]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/HttpDxe/HttpDns.c
NetworkPkg: Clean up source files
[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
f75a7f56 4Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r
47f51a06
YT
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
f75a7f56 28\r
47f51a06
YT
29**/\r
30EFI_STATUS\r
31HttpDns4 (\r
32 IN HTTP_PROTOCOL *HttpInstance,\r
33 IN CHAR16 *HostName,\r
f75a7f56 34 OUT EFI_IPv4_ADDRESS *IpAddress\r
47f51a06
YT
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
f75a7f56 48\r
47f51a06
YT
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
f75a7f56 85\r
47f51a06
YT
86 //\r
87 // Create a DNS child instance and get the protocol.\r
88 //\r
89 Status = NetLibCreateServiceChild (\r
90 Service->ControllerHandle,\r
7cf59c85 91 Service->Ip4DriverBindingHandle,\r
47f51a06
YT
92 &gEfiDns4ServiceBindingProtocolGuid,\r
93 &Dns4Handle\r
94 );\r
95 if (EFI_ERROR (Status)) {\r
96 goto Exit;\r
f75a7f56 97 }\r
47f51a06
YT
98\r
99 Status = gBS->OpenProtocol (\r
100 Dns4Handle,\r
101 &gEfiDns4ProtocolGuid,\r
102 (VOID **) &Dns4,\r
7cf59c85 103 Service->Ip4DriverBindingHandle,\r
47f51a06
YT
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
f75a7f56 131\r
47f51a06
YT
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
f75a7f56 164 Status = Token.Status;\r
47f51a06
YT
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
f75a7f56 182\r
47f51a06
YT
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
f75a7f56 195\r
47f51a06 196 gBS->CloseProtocol (\r
b659408b
ZL
197 Dns4Handle,\r
198 &gEfiDns4ProtocolGuid,\r
7cf59c85 199 Service->Ip4DriverBindingHandle,\r
b659408b
ZL
200 Service->ControllerHandle\r
201 );\r
47f51a06
YT
202 }\r
203\r
204 if (Dns4Handle != NULL) {\r
205 NetLibDestroyServiceChild (\r
206 Service->ControllerHandle,\r
7cf59c85 207 Service->Ip4DriverBindingHandle,\r
47f51a06
YT
208 &gEfiDns4ServiceBindingProtocolGuid,\r
209 Dns4Handle\r
210 );\r
211 }\r
212\r
213 if (DnsServerList != NULL) {\r
214 FreePool (DnsServerList);\r
215 }\r
f75a7f56 216\r
47f51a06
YT
217 return Status;\r
218}\r
b659408b
ZL
219\r
220/**\r
221 Retrieve the host address using the EFI_DNS6_PROTOCOL.\r
222\r
223 @param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.\r
224 @param[in] HostName Pointer to buffer containing hostname.\r
225 @param[out] IpAddress On output, pointer to buffer containing IPv6 address.\r
226\r
227 @retval EFI_SUCCESS Operation succeeded.\r
228 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
229 @retval EFI_DEVICE_ERROR An unexpected network error occurred.\r
230 @retval Others Other errors as indicated.\r
f75a7f56 231\r
b659408b
ZL
232**/\r
233EFI_STATUS\r
234HttpDns6 (\r
235 IN HTTP_PROTOCOL *HttpInstance,\r
236 IN CHAR16 *HostName,\r
f75a7f56 237 OUT EFI_IPv6_ADDRESS *IpAddress\r
b659408b
ZL
238 )\r
239{\r
240 EFI_STATUS Status;\r
241 HTTP_SERVICE *Service;\r
242 EFI_DNS6_PROTOCOL *Dns6;\r
243 EFI_DNS6_CONFIG_DATA Dns6ConfigData;\r
244 EFI_DNS6_COMPLETION_TOKEN Token;\r
245 EFI_HANDLE Dns6Handle;\r
246 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
247 EFI_IPv6_ADDRESS *DnsServerList;\r
248 UINTN DnsServerListCount;\r
249 UINTN DataSize;\r
250 BOOLEAN IsDone;\r
f75a7f56 251\r
b659408b
ZL
252\r
253 Service = HttpInstance->Service;\r
254 ASSERT (Service != NULL);\r
255\r
256 DnsServerList = NULL;\r
257 DnsServerListCount = 0;\r
258 Dns6 = NULL;\r
259 Dns6Handle = NULL;\r
260 ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));\r
f75a7f56 261\r
b659408b
ZL
262 //\r
263 // Get DNS server list from EFI IPv6 Configuration protocol.\r
264 //\r
265 Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp6ConfigProtocolGuid, (VOID **) &Ip6Config);\r
266 if (!EFI_ERROR (Status)) {\r
267 //\r
268 // Get the required size.\r
269 //\r
270 DataSize = 0;\r
271 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, NULL);\r
272 if (Status == EFI_BUFFER_TOO_SMALL) {\r
273 DnsServerList = AllocatePool (DataSize);\r
274 if (DnsServerList == NULL) {\r
275 return EFI_OUT_OF_RESOURCES;\r
f75a7f56 276 }\r
b659408b
ZL
277\r
278 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);\r
279 if (EFI_ERROR (Status)) {\r
280 FreePool (DnsServerList);\r
281 DnsServerList = NULL;\r
282 } else {\r
283 DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);\r
284 }\r
285 }\r
286 }\r
287\r
288 //\r
289 // Create a DNSv6 child instance and get the protocol.\r
290 //\r
291 Status = NetLibCreateServiceChild (\r
292 Service->ControllerHandle,\r
7cf59c85 293 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
294 &gEfiDns6ServiceBindingProtocolGuid,\r
295 &Dns6Handle\r
296 );\r
297 if (EFI_ERROR (Status)) {\r
298 goto Exit;\r
f75a7f56
LG
299 }\r
300\r
b659408b
ZL
301 Status = gBS->OpenProtocol (\r
302 Dns6Handle,\r
303 &gEfiDns6ProtocolGuid,\r
304 (VOID **) &Dns6,\r
7cf59c85 305 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
306 Service->ControllerHandle,\r
307 EFI_OPEN_PROTOCOL_BY_DRIVER\r
308 );\r
309 if (EFI_ERROR (Status)) {\r
310 goto Exit;\r
311 }\r
312\r
313 //\r
314 // Configure DNS6 instance for the DNS server address and protocol.\r
315 //\r
316 ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));\r
317 Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;\r
318 Dns6ConfigData.DnsServerList = DnsServerList;\r
319 Dns6ConfigData.EnableDnsCache = TRUE;\r
320 Dns6ConfigData.Protocol = EFI_IP_PROTO_UDP;\r
321 IP6_COPY_ADDRESS (&Dns6ConfigData.StationIp, &HttpInstance->Ipv6Node.LocalAddress);\r
322 Status = Dns6->Configure (\r
323 Dns6,\r
324 &Dns6ConfigData\r
325 );\r
326 if (EFI_ERROR (Status)) {\r
327 goto Exit;\r
328 }\r
329\r
330 Token.Status = EFI_NOT_READY;\r
331 IsDone = FALSE;\r
332 //\r
333 // Create event to set the IsDone flag when name resolution is finished.\r
334 //\r
335 Status = gBS->CreateEvent (\r
336 EVT_NOTIFY_SIGNAL,\r
337 TPL_NOTIFY,\r
338 HttpCommonNotify,\r
339 &IsDone,\r
340 &Token.Event\r
341 );\r
342 if (EFI_ERROR (Status)) {\r
343 goto Exit;\r
344 }\r
345\r
346 //\r
347 // Start asynchronous name resolution.\r
348 //\r
349 Status = Dns6->HostNameToIp (Dns6, HostName, &Token);\r
350 if (EFI_ERROR (Status)) {\r
351 goto Exit;\r
352 }\r
353\r
354 while (!IsDone) {\r
355 Dns6->Poll (Dns6);\r
356 }\r
357\r
358 //\r
359 // Name resolution is done, check result.\r
360 //\r
f75a7f56 361 Status = Token.Status;\r
b659408b
ZL
362 if (!EFI_ERROR (Status)) {\r
363 if (Token.RspData.H2AData == NULL) {\r
364 Status = EFI_DEVICE_ERROR;\r
365 goto Exit;\r
366 }\r
367 if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) {\r
368 Status = EFI_DEVICE_ERROR;\r
369 goto Exit;\r
370 }\r
371 //\r
372 // We just return the first IPv6 address from DNS protocol.\r
373 //\r
374 IP6_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);\r
375 Status = EFI_SUCCESS;\r
376 }\r
f75a7f56 377\r
b659408b
ZL
378Exit:\r
379\r
380 if (Token.Event != NULL) {\r
381 gBS->CloseEvent (Token.Event);\r
382 }\r
383 if (Token.RspData.H2AData != NULL) {\r
384 if (Token.RspData.H2AData->IpList != NULL) {\r
385 FreePool (Token.RspData.H2AData->IpList);\r
386 }\r
387 FreePool (Token.RspData.H2AData);\r
388 }\r
389\r
390 if (Dns6 != NULL) {\r
391 Dns6->Configure (Dns6, NULL);\r
f75a7f56 392\r
b659408b
ZL
393 gBS->CloseProtocol (\r
394 Dns6Handle,\r
395 &gEfiDns6ProtocolGuid,\r
7cf59c85 396 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
397 Service->ControllerHandle\r
398 );\r
399 }\r
400\r
401 if (Dns6Handle != NULL) {\r
402 NetLibDestroyServiceChild (\r
403 Service->ControllerHandle,\r
7cf59c85 404 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
405 &gEfiDns6ServiceBindingProtocolGuid,\r
406 Dns6Handle\r
407 );\r
408 }\r
409\r
410 if (DnsServerList != NULL) {\r
411 FreePool (DnsServerList);\r
412 }\r
f75a7f56
LG
413\r
414 return Status;\r
b659408b 415}\r