]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/HttpDxe/HttpDns.c
NetworkPkg: Apply uncrustify changes
[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
ecf98fbc 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
47f51a06
YT
6\r
7**/\r
8\r
9#include "HttpDriver.h"\r
10\r
11/**\r
12 Retrieve the host address using the EFI_DNS4_PROTOCOL.\r
13\r
14 @param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.\r
15 @param[in] HostName Pointer to buffer containing hostname.\r
16 @param[out] IpAddress On output, pointer to buffer containing IPv4 address.\r
17\r
18 @retval EFI_SUCCESS Operation succeeded.\r
19 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
20 @retval EFI_DEVICE_ERROR An unexpected network error occurred.\r
21 @retval Others Other errors as indicated.\r
f75a7f56 22\r
47f51a06
YT
23**/\r
24EFI_STATUS\r
25HttpDns4 (\r
d1050b9d
MK
26 IN HTTP_PROTOCOL *HttpInstance,\r
27 IN CHAR16 *HostName,\r
28 OUT EFI_IPv4_ADDRESS *IpAddress\r
47f51a06
YT
29 )\r
30{\r
d1050b9d
MK
31 EFI_STATUS Status;\r
32 EFI_DNS4_PROTOCOL *Dns4;\r
33 EFI_DNS4_CONFIG_DATA Dns4CfgData;\r
34 EFI_DNS4_COMPLETION_TOKEN Token;\r
35 BOOLEAN IsDone;\r
36 HTTP_SERVICE *Service;\r
37 EFI_HANDLE Dns4Handle;\r
38 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;\r
39 UINTN DnsServerListCount;\r
40 EFI_IPv4_ADDRESS *DnsServerList;\r
41 UINTN DataSize;\r
47f51a06
YT
42\r
43 Service = HttpInstance->Service;\r
44 ASSERT (Service != NULL);\r
45\r
46 DnsServerList = NULL;\r
47 DnsServerListCount = 0;\r
48 ZeroMem (&Token, sizeof (EFI_DNS4_COMPLETION_TOKEN));\r
49\r
50 //\r
51 // Get DNS server list from EFI IPv4 Configuration II protocol.\r
52 //\r
d1050b9d 53 Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp4Config2ProtocolGuid, (VOID **)&Ip4Config2);\r
47f51a06
YT
54 if (!EFI_ERROR (Status)) {\r
55 //\r
56 // Get the required size.\r
57 //\r
58 DataSize = 0;\r
59 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, NULL);\r
60 if (Status == EFI_BUFFER_TOO_SMALL) {\r
61 DnsServerList = AllocatePool (DataSize);\r
62 if (DnsServerList == NULL) {\r
63 return EFI_OUT_OF_RESOURCES;\r
64 }\r
65\r
d1050b9d 66 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, DnsServerList);\r
47f51a06
YT
67 if (EFI_ERROR (Status)) {\r
68 FreePool (DnsServerList);\r
69 DnsServerList = NULL;\r
70 } else {\r
71 DnsServerListCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
72 }\r
73 }\r
74 }\r
75\r
76 Dns4Handle = NULL;\r
77 Dns4 = NULL;\r
f75a7f56 78\r
47f51a06
YT
79 //\r
80 // Create a DNS child instance and get the protocol.\r
81 //\r
82 Status = NetLibCreateServiceChild (\r
83 Service->ControllerHandle,\r
7cf59c85 84 Service->Ip4DriverBindingHandle,\r
47f51a06
YT
85 &gEfiDns4ServiceBindingProtocolGuid,\r
86 &Dns4Handle\r
87 );\r
88 if (EFI_ERROR (Status)) {\r
89 goto Exit;\r
f75a7f56 90 }\r
47f51a06
YT
91\r
92 Status = gBS->OpenProtocol (\r
93 Dns4Handle,\r
94 &gEfiDns4ProtocolGuid,\r
d1050b9d 95 (VOID **)&Dns4,\r
7cf59c85 96 Service->Ip4DriverBindingHandle,\r
47f51a06
YT
97 Service->ControllerHandle,\r
98 EFI_OPEN_PROTOCOL_BY_DRIVER\r
99 );\r
100 if (EFI_ERROR (Status)) {\r
101 goto Exit;\r
102 }\r
103\r
104 //\r
105 // Configure DNS4 instance for the DNS server address and protocol.\r
106 //\r
107 ZeroMem (&Dns4CfgData, sizeof (Dns4CfgData));\r
108 Dns4CfgData.DnsServerListCount = DnsServerListCount;\r
109 Dns4CfgData.DnsServerList = DnsServerList;\r
110 Dns4CfgData.UseDefaultSetting = HttpInstance->IPv4Node.UseDefaultAddress;\r
111 if (!Dns4CfgData.UseDefaultSetting) {\r
112 IP4_COPY_ADDRESS (&Dns4CfgData.StationIp, &HttpInstance->IPv4Node.LocalAddress);\r
113 IP4_COPY_ADDRESS (&Dns4CfgData.SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);\r
114 }\r
d1050b9d
MK
115\r
116 Dns4CfgData.EnableDnsCache = TRUE;\r
117 Dns4CfgData.Protocol = EFI_IP_PROTO_UDP;\r
118 Status = Dns4->Configure (\r
119 Dns4,\r
120 &Dns4CfgData\r
121 );\r
47f51a06
YT
122 if (EFI_ERROR (Status)) {\r
123 goto Exit;\r
124 }\r
f75a7f56 125\r
47f51a06
YT
126 //\r
127 // Create event to set the is done flag when name resolution is finished.\r
128 //\r
129 ZeroMem (&Token, sizeof (Token));\r
130 Status = gBS->CreateEvent (\r
131 EVT_NOTIFY_SIGNAL,\r
132 TPL_NOTIFY,\r
133 HttpCommonNotify,\r
134 &IsDone,\r
135 &Token.Event\r
136 );\r
137 if (EFI_ERROR (Status)) {\r
138 goto Exit;\r
139 }\r
140\r
141 //\r
142 // Start asynchronous name resolution.\r
143 //\r
144 Token.Status = EFI_NOT_READY;\r
145 IsDone = FALSE;\r
d1050b9d 146 Status = Dns4->HostNameToIp (Dns4, HostName, &Token);\r
47f51a06
YT
147 if (EFI_ERROR (Status)) {\r
148 goto Exit;\r
149 }\r
150\r
151 while (!IsDone) {\r
152 Dns4->Poll (Dns4);\r
153 }\r
154\r
155 //\r
156 // Name resolution is done, check result.\r
157 //\r
f75a7f56 158 Status = Token.Status;\r
47f51a06
YT
159 if (!EFI_ERROR (Status)) {\r
160 if (Token.RspData.H2AData == NULL) {\r
161 Status = EFI_DEVICE_ERROR;\r
162 goto Exit;\r
163 }\r
d1050b9d
MK
164\r
165 if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) {\r
47f51a06
YT
166 Status = EFI_DEVICE_ERROR;\r
167 goto Exit;\r
168 }\r
d1050b9d 169\r
47f51a06
YT
170 //\r
171 // We just return the first IP address from DNS protocol.\r
172 //\r
173 IP4_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);\r
174 Status = EFI_SUCCESS;\r
175 }\r
176\r
177Exit:\r
f75a7f56 178\r
47f51a06
YT
179 if (Token.Event != NULL) {\r
180 gBS->CloseEvent (Token.Event);\r
181 }\r
d1050b9d 182\r
47f51a06
YT
183 if (Token.RspData.H2AData != NULL) {\r
184 if (Token.RspData.H2AData->IpList != NULL) {\r
185 FreePool (Token.RspData.H2AData->IpList);\r
186 }\r
d1050b9d 187\r
47f51a06
YT
188 FreePool (Token.RspData.H2AData);\r
189 }\r
190\r
191 if (Dns4 != NULL) {\r
192 Dns4->Configure (Dns4, NULL);\r
f75a7f56 193\r
47f51a06 194 gBS->CloseProtocol (\r
b659408b
ZL
195 Dns4Handle,\r
196 &gEfiDns4ProtocolGuid,\r
7cf59c85 197 Service->Ip4DriverBindingHandle,\r
b659408b
ZL
198 Service->ControllerHandle\r
199 );\r
47f51a06
YT
200 }\r
201\r
202 if (Dns4Handle != NULL) {\r
203 NetLibDestroyServiceChild (\r
204 Service->ControllerHandle,\r
7cf59c85 205 Service->Ip4DriverBindingHandle,\r
47f51a06
YT
206 &gEfiDns4ServiceBindingProtocolGuid,\r
207 Dns4Handle\r
208 );\r
209 }\r
210\r
211 if (DnsServerList != NULL) {\r
212 FreePool (DnsServerList);\r
213 }\r
f75a7f56 214\r
47f51a06
YT
215 return Status;\r
216}\r
b659408b
ZL
217\r
218/**\r
219 Retrieve the host address using the EFI_DNS6_PROTOCOL.\r
220\r
221 @param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.\r
222 @param[in] HostName Pointer to buffer containing hostname.\r
223 @param[out] IpAddress On output, pointer to buffer containing IPv6 address.\r
224\r
225 @retval EFI_SUCCESS Operation succeeded.\r
226 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
227 @retval EFI_DEVICE_ERROR An unexpected network error occurred.\r
228 @retval Others Other errors as indicated.\r
f75a7f56 229\r
b659408b
ZL
230**/\r
231EFI_STATUS\r
232HttpDns6 (\r
d1050b9d
MK
233 IN HTTP_PROTOCOL *HttpInstance,\r
234 IN CHAR16 *HostName,\r
235 OUT EFI_IPv6_ADDRESS *IpAddress\r
b659408b
ZL
236 )\r
237{\r
d1050b9d
MK
238 EFI_STATUS Status;\r
239 HTTP_SERVICE *Service;\r
240 EFI_DNS6_PROTOCOL *Dns6;\r
241 EFI_DNS6_CONFIG_DATA Dns6ConfigData;\r
242 EFI_DNS6_COMPLETION_TOKEN Token;\r
243 EFI_HANDLE Dns6Handle;\r
244 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
245 EFI_IPv6_ADDRESS *DnsServerList;\r
246 UINTN DnsServerListCount;\r
247 UINTN DataSize;\r
248 BOOLEAN IsDone;\r
b659408b
ZL
249\r
250 Service = HttpInstance->Service;\r
251 ASSERT (Service != NULL);\r
252\r
d1050b9d
MK
253 DnsServerList = NULL;\r
254 DnsServerListCount = 0;\r
255 Dns6 = NULL;\r
256 Dns6Handle = NULL;\r
b659408b 257 ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));\r
f75a7f56 258\r
b659408b
ZL
259 //\r
260 // Get DNS server list from EFI IPv6 Configuration protocol.\r
261 //\r
d1050b9d 262 Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp6ConfigProtocolGuid, (VOID **)&Ip6Config);\r
b659408b
ZL
263 if (!EFI_ERROR (Status)) {\r
264 //\r
265 // Get the required size.\r
266 //\r
267 DataSize = 0;\r
d1050b9d 268 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, NULL);\r
b659408b
ZL
269 if (Status == EFI_BUFFER_TOO_SMALL) {\r
270 DnsServerList = AllocatePool (DataSize);\r
271 if (DnsServerList == NULL) {\r
272 return EFI_OUT_OF_RESOURCES;\r
f75a7f56 273 }\r
b659408b
ZL
274\r
275 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);\r
276 if (EFI_ERROR (Status)) {\r
277 FreePool (DnsServerList);\r
278 DnsServerList = NULL;\r
279 } else {\r
280 DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);\r
281 }\r
282 }\r
283 }\r
284\r
285 //\r
286 // Create a DNSv6 child instance and get the protocol.\r
287 //\r
288 Status = NetLibCreateServiceChild (\r
289 Service->ControllerHandle,\r
7cf59c85 290 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
291 &gEfiDns6ServiceBindingProtocolGuid,\r
292 &Dns6Handle\r
293 );\r
294 if (EFI_ERROR (Status)) {\r
295 goto Exit;\r
f75a7f56
LG
296 }\r
297\r
b659408b
ZL
298 Status = gBS->OpenProtocol (\r
299 Dns6Handle,\r
300 &gEfiDns6ProtocolGuid,\r
d1050b9d 301 (VOID **)&Dns6,\r
7cf59c85 302 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
303 Service->ControllerHandle,\r
304 EFI_OPEN_PROTOCOL_BY_DRIVER\r
305 );\r
306 if (EFI_ERROR (Status)) {\r
307 goto Exit;\r
308 }\r
309\r
310 //\r
311 // Configure DNS6 instance for the DNS server address and protocol.\r
312 //\r
313 ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));\r
314 Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;\r
315 Dns6ConfigData.DnsServerList = DnsServerList;\r
316 Dns6ConfigData.EnableDnsCache = TRUE;\r
317 Dns6ConfigData.Protocol = EFI_IP_PROTO_UDP;\r
318 IP6_COPY_ADDRESS (&Dns6ConfigData.StationIp, &HttpInstance->Ipv6Node.LocalAddress);\r
319 Status = Dns6->Configure (\r
320 Dns6,\r
321 &Dns6ConfigData\r
322 );\r
323 if (EFI_ERROR (Status)) {\r
324 goto Exit;\r
325 }\r
326\r
327 Token.Status = EFI_NOT_READY;\r
328 IsDone = FALSE;\r
329 //\r
330 // Create event to set the IsDone flag when name resolution is finished.\r
331 //\r
332 Status = gBS->CreateEvent (\r
333 EVT_NOTIFY_SIGNAL,\r
334 TPL_NOTIFY,\r
335 HttpCommonNotify,\r
336 &IsDone,\r
337 &Token.Event\r
338 );\r
339 if (EFI_ERROR (Status)) {\r
340 goto Exit;\r
341 }\r
342\r
343 //\r
344 // Start asynchronous name resolution.\r
345 //\r
346 Status = Dns6->HostNameToIp (Dns6, HostName, &Token);\r
347 if (EFI_ERROR (Status)) {\r
348 goto Exit;\r
349 }\r
350\r
351 while (!IsDone) {\r
352 Dns6->Poll (Dns6);\r
353 }\r
354\r
355 //\r
356 // Name resolution is done, check result.\r
357 //\r
f75a7f56 358 Status = Token.Status;\r
b659408b
ZL
359 if (!EFI_ERROR (Status)) {\r
360 if (Token.RspData.H2AData == NULL) {\r
361 Status = EFI_DEVICE_ERROR;\r
362 goto Exit;\r
363 }\r
d1050b9d
MK
364\r
365 if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) {\r
b659408b
ZL
366 Status = EFI_DEVICE_ERROR;\r
367 goto Exit;\r
368 }\r
d1050b9d 369\r
b659408b
ZL
370 //\r
371 // We just return the first IPv6 address from DNS protocol.\r
372 //\r
373 IP6_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);\r
374 Status = EFI_SUCCESS;\r
375 }\r
f75a7f56 376\r
b659408b
ZL
377Exit:\r
378\r
379 if (Token.Event != NULL) {\r
380 gBS->CloseEvent (Token.Event);\r
381 }\r
d1050b9d 382\r
b659408b
ZL
383 if (Token.RspData.H2AData != NULL) {\r
384 if (Token.RspData.H2AData->IpList != NULL) {\r
385 FreePool (Token.RspData.H2AData->IpList);\r
386 }\r
d1050b9d 387\r
b659408b
ZL
388 FreePool (Token.RspData.H2AData);\r
389 }\r
390\r
391 if (Dns6 != NULL) {\r
392 Dns6->Configure (Dns6, NULL);\r
f75a7f56 393\r
b659408b
ZL
394 gBS->CloseProtocol (\r
395 Dns6Handle,\r
396 &gEfiDns6ProtocolGuid,\r
7cf59c85 397 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
398 Service->ControllerHandle\r
399 );\r
400 }\r
401\r
402 if (Dns6Handle != NULL) {\r
403 NetLibDestroyServiceChild (\r
404 Service->ControllerHandle,\r
7cf59c85 405 Service->Ip6DriverBindingHandle,\r
b659408b
ZL
406 &gEfiDns6ServiceBindingProtocolGuid,\r
407 Dns6Handle\r
408 );\r
409 }\r
410\r
411 if (DnsServerList != NULL) {\r
412 FreePool (DnsServerList);\r
413 }\r
f75a7f56
LG
414\r
415 return Status;\r
b659408b 416}\r