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