VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/NetworkPkg/HttpDxe/HttpDns.c@ 77662

Last change on this file since 77662 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette