TianoCore EDK2 master
Loading...
Searching...
No Matches
HttpDns.c
Go to the documentation of this file.
1
9#include "HttpDriver.h"
10
26 IN HTTP_PROTOCOL *HttpInstance,
27 IN CHAR16 *HostName,
28 OUT EFI_IPv4_ADDRESS *IpAddress
29 )
30{
31 EFI_STATUS Status;
33 EFI_DNS4_CONFIG_DATA Dns4CfgData;
35 BOOLEAN IsDone;
36 HTTP_SERVICE *Service;
37 EFI_HANDLE Dns4Handle;
38 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;
39 UINTN DnsServerListCount;
40 EFI_IPv4_ADDRESS *DnsServerList;
41 UINTN DataSize;
42
43 Service = HttpInstance->Service;
44 ASSERT (Service != NULL);
45
46 DnsServerList = NULL;
47 DnsServerListCount = 0;
48 ZeroMem (&Token, sizeof (EFI_DNS4_COMPLETION_TOKEN));
49
50 //
51 // Get DNS server list from EFI IPv4 Configuration II protocol.
52 //
53 Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp4Config2ProtocolGuid, (VOID **)&Ip4Config2);
54 if (!EFI_ERROR (Status)) {
55 //
56 // Get the required size.
57 //
58 DataSize = 0;
59 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, NULL);
60 if (Status == EFI_BUFFER_TOO_SMALL) {
61 DnsServerList = AllocatePool (DataSize);
62 if (DnsServerList == NULL) {
63 return EFI_OUT_OF_RESOURCES;
64 }
65
66 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, DnsServerList);
67 if (EFI_ERROR (Status)) {
68 FreePool (DnsServerList);
69 DnsServerList = NULL;
70 } else {
71 DnsServerListCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
72 }
73 }
74 }
75
76 Dns4Handle = NULL;
77 Dns4 = NULL;
78
79 //
80 // Create a DNS child instance and get the protocol.
81 //
83 Service->ControllerHandle,
84 Service->Ip4DriverBindingHandle,
85 &gEfiDns4ServiceBindingProtocolGuid,
86 &Dns4Handle
87 );
88 if (EFI_ERROR (Status)) {
89 goto Exit;
90 }
91
92 Status = gBS->OpenProtocol (
93 Dns4Handle,
94 &gEfiDns4ProtocolGuid,
95 (VOID **)&Dns4,
96 Service->Ip4DriverBindingHandle,
97 Service->ControllerHandle,
98 EFI_OPEN_PROTOCOL_BY_DRIVER
99 );
100 if (EFI_ERROR (Status)) {
101 goto Exit;
102 }
103
104 //
105 // Configure DNS4 instance for the DNS server address and protocol.
106 //
107 ZeroMem (&Dns4CfgData, sizeof (Dns4CfgData));
108 Dns4CfgData.DnsServerListCount = DnsServerListCount;
109 Dns4CfgData.DnsServerList = DnsServerList;
110 Dns4CfgData.UseDefaultSetting = HttpInstance->IPv4Node.UseDefaultAddress;
111 Dns4CfgData.RetryInterval = PcdGet32 (PcdHttpDnsRetryInterval);
112 Dns4CfgData.RetryCount = PcdGet32 (PcdHttpDnsRetryCount);
113 if (!Dns4CfgData.UseDefaultSetting) {
114 IP4_COPY_ADDRESS (&Dns4CfgData.StationIp, &HttpInstance->IPv4Node.LocalAddress);
115 IP4_COPY_ADDRESS (&Dns4CfgData.SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);
116 }
117
118 Dns4CfgData.EnableDnsCache = TRUE;
119 Dns4CfgData.Protocol = EFI_IP_PROTO_UDP;
120 Status = Dns4->Configure (
121 Dns4,
122 &Dns4CfgData
123 );
124 if (EFI_ERROR (Status)) {
125 goto Exit;
126 }
127
128 //
129 // Create event to set the is done flag when name resolution is finished.
130 //
131 ZeroMem (&Token, sizeof (Token));
132 Status = gBS->CreateEvent (
133 EVT_NOTIFY_SIGNAL,
134 TPL_NOTIFY,
136 &IsDone,
137 &Token.Event
138 );
139 if (EFI_ERROR (Status)) {
140 goto Exit;
141 }
142
143 //
144 // Start asynchronous name resolution.
145 //
146 Token.Status = EFI_NOT_READY;
147 IsDone = FALSE;
148 Status = Dns4->HostNameToIp (Dns4, HostName, &Token);
149 if (EFI_ERROR (Status)) {
150 goto Exit;
151 }
152
153 while (!IsDone) {
154 Dns4->Poll (Dns4);
155 }
156
157 //
158 // Name resolution is done, check result.
159 //
160 Status = Token.Status;
161 if (!EFI_ERROR (Status)) {
162 if (Token.RspData.H2AData == NULL) {
163 Status = EFI_DEVICE_ERROR;
164 goto Exit;
165 }
166
167 if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) {
168 Status = EFI_DEVICE_ERROR;
169 goto Exit;
170 }
171
172 //
173 // We just return the first IP address from DNS protocol.
174 //
175 IP4_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);
176 Status = EFI_SUCCESS;
177 }
178
179Exit:
180
181 if (Token.Event != NULL) {
182 gBS->CloseEvent (Token.Event);
183 }
184
185 if (Token.RspData.H2AData != NULL) {
186 if (Token.RspData.H2AData->IpList != NULL) {
188 }
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) {
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
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;
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 Service = HttpInstance->Service;
253 ASSERT (Service != NULL);
254
255 DnsServerList = NULL;
256 DnsServerListCount = 0;
257 Dns6 = NULL;
258 Dns6Handle = NULL;
259 ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));
260
261 //
262 // Get DNS server list from EFI IPv6 Configuration protocol.
263 //
264 Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp6ConfigProtocolGuid, (VOID **)&Ip6Config);
265 if (!EFI_ERROR (Status)) {
266 //
267 // Get the required size.
268 //
269 DataSize = 0;
270 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, NULL);
271 if (Status == EFI_BUFFER_TOO_SMALL) {
272 DnsServerList = AllocatePool (DataSize);
273 if (DnsServerList == NULL) {
274 return EFI_OUT_OF_RESOURCES;
275 }
276
277 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);
278 if (EFI_ERROR (Status)) {
279 FreePool (DnsServerList);
280 DnsServerList = NULL;
281 } else {
282 DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
283 }
284 }
285 }
286
287 //
288 // Create a DNSv6 child instance and get the protocol.
289 //
290 Status = NetLibCreateServiceChild (
291 Service->ControllerHandle,
292 Service->Ip6DriverBindingHandle,
293 &gEfiDns6ServiceBindingProtocolGuid,
294 &Dns6Handle
295 );
296 if (EFI_ERROR (Status)) {
297 goto Exit;
298 }
299
300 Status = gBS->OpenProtocol (
301 Dns6Handle,
302 &gEfiDns6ProtocolGuid,
303 (VOID **)&Dns6,
304 Service->Ip6DriverBindingHandle,
305 Service->ControllerHandle,
306 EFI_OPEN_PROTOCOL_BY_DRIVER
307 );
308 if (EFI_ERROR (Status)) {
309 goto Exit;
310 }
311
312 //
313 // Configure DNS6 instance for the DNS server address and protocol.
314 //
315 ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));
316 Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;
317 Dns6ConfigData.DnsServerList = DnsServerList;
318 Dns6ConfigData.EnableDnsCache = TRUE;
319 Dns6ConfigData.Protocol = EFI_IP_PROTO_UDP;
320 Dns6ConfigData.RetryInterval = PcdGet32 (PcdHttpDnsRetryInterval);
321 Dns6ConfigData.RetryCount = PcdGet32 (PcdHttpDnsRetryCount);
322 IP6_COPY_ADDRESS (&Dns6ConfigData.StationIp, &HttpInstance->Ipv6Node.LocalAddress);
323 Status = Dns6->Configure (
324 Dns6,
325 &Dns6ConfigData
326 );
327 if (EFI_ERROR (Status)) {
328 goto Exit;
329 }
330
331 Token.Status = EFI_NOT_READY;
332 IsDone = FALSE;
333 //
334 // Create event to set the IsDone flag when name resolution is finished.
335 //
336 Status = gBS->CreateEvent (
337 EVT_NOTIFY_SIGNAL,
338 TPL_NOTIFY,
340 &IsDone,
341 &Token.Event
342 );
343 if (EFI_ERROR (Status)) {
344 goto Exit;
345 }
346
347 //
348 // Start asynchronous name resolution.
349 //
350 Status = Dns6->HostNameToIp (Dns6, HostName, &Token);
351 if (EFI_ERROR (Status)) {
352 goto Exit;
353 }
354
355 while (!IsDone) {
356 Dns6->Poll (Dns6);
357 }
358
359 //
360 // Name resolution is done, check result.
361 //
362 Status = Token.Status;
363 if (!EFI_ERROR (Status)) {
364 if (Token.RspData.H2AData == NULL) {
365 Status = EFI_DEVICE_ERROR;
366 goto Exit;
367 }
368
369 if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) {
370 Status = EFI_DEVICE_ERROR;
371 goto Exit;
372 }
373
374 //
375 // We just return the first IPv6 address from DNS protocol.
376 //
377 IP6_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);
378 Status = EFI_SUCCESS;
379 }
380
381Exit:
382
383 if (Token.Event != NULL) {
384 gBS->CloseEvent (Token.Event);
385 }
386
387 if (Token.RspData.H2AData != NULL) {
388 if (Token.RspData.H2AData->IpList != NULL) {
390 }
391
392 FreePool (Token.RspData.H2AData);
393 }
394
395 if (Dns6 != NULL) {
396 Dns6->Configure (Dns6, NULL);
397
398 gBS->CloseProtocol (
399 Dns6Handle,
400 &gEfiDns6ProtocolGuid,
401 Service->Ip6DriverBindingHandle,
402 Service->ControllerHandle
403 );
404 }
405
406 if (Dns6Handle != NULL) {
408 Service->ControllerHandle,
409 Service->Ip6DriverBindingHandle,
410 &gEfiDns6ServiceBindingProtocolGuid,
411 Dns6Handle
412 );
413 }
414
415 if (DnsServerList != NULL) {
416 FreePool (DnsServerList);
417 }
418
419 return Status;
420}
UINT64 UINTN
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS HttpDns4(IN HTTP_PROTOCOL *HttpInstance, IN CHAR16 *HostName, OUT EFI_IPv4_ADDRESS *IpAddress)
Definition: HttpDns.c:25
EFI_STATUS HttpDns6(IN HTTP_PROTOCOL *HttpInstance, IN CHAR16 *HostName, OUT EFI_IPv6_ADDRESS *IpAddress)
Definition: HttpDns.c:234
VOID EFIAPI HttpCommonNotify(IN EFI_EVENT Event, IN VOID *Context)
Definition: HttpProto.c:22
@ Ip4Config2DataTypeDnsServer
Definition: Ip4Config2.h:74
@ Ip6ConfigDataTypeDnsServer
Definition: Ip6Config.h:90
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID EFIAPI Exit(IN EFI_STATUS Status)
IPv6_ADDRESS EFI_IPv6_ADDRESS
Definition: UefiBaseType.h:90
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
IPv4_ADDRESS EFI_IPv4_ADDRESS
Definition: UefiBaseType.h:85
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_IPv6_ADDRESS * IpList
Definition: Dns6.h:149
EFI_IPv4_ADDRESS * IpList
Definition: Dns4.h:161
DNS_HOST_TO_ADDR_DATA * H2AData
Definition: Dns4.h:260
EFI_STATUS Status
Definition: Dns4.h:241
union EFI_DNS4_COMPLETION_TOKEN::@573 RspData
BOOLEAN EnableDnsCache
Definition: Dns4.h:63
UINT8 Protocol
Definition: Dns4.h:71
EFI_IPv4_ADDRESS * DnsServerList
Definition: Dns4.h:54
BOOLEAN UseDefaultSetting
Definition: Dns4.h:58
EFI_IPv4_ADDRESS SubnetMask
Definition: Dns4.h:79
UINTN DnsServerListCount
Definition: Dns4.h:42
EFI_IPv4_ADDRESS StationIp
Definition: Dns4.h:75
UINT32 RetryInterval
Definition: Dns4.h:92
UINT32 RetryCount
Definition: Dns4.h:87
DNS6_HOST_TO_ADDR_DATA * H2AData
Definition: Dns6.h:249
union EFI_DNS6_COMPLETION_TOKEN::@574 RspData
EFI_STATUS Status
Definition: Dns6.h:229
UINT32 RetryCount
Definition: Dns6.h:79
UINT8 Protocol
Definition: Dns6.h:44
BOOLEAN EnableDnsCache
Definition: Dns6.h:38
UINT32 RetryInterval
Definition: Dns6.h:83
EFI_IPv6_ADDRESS * DnsServerList
Definition: Dns6.h:75
EFI_IPv6_ADDRESS StationIp
Definition: Dns6.h:50
UINT32 DnsServerCount
Definition: Dns6.h:63