2 Routines for HttpDxe driver to perform DNS resolution based on UEFI DNS protocols.
4 Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "HttpDriver.h"
12 Retrieve the host address using the EFI_DNS4_PROTOCOL.
14 @param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.
15 @param[in] HostName Pointer to buffer containing hostname.
16 @param[out] IpAddress On output, pointer to buffer containing IPv4 address.
18 @retval EFI_SUCCESS Operation succeeded.
19 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
20 @retval EFI_DEVICE_ERROR An unexpected network error occurred.
21 @retval Others Other errors as indicated.
26 IN HTTP_PROTOCOL
*HttpInstance
,
28 OUT EFI_IPv4_ADDRESS
*IpAddress
32 EFI_DNS4_PROTOCOL
*Dns4
;
33 EFI_DNS4_CONFIG_DATA Dns4CfgData
;
34 EFI_DNS4_COMPLETION_TOKEN Token
;
36 HTTP_SERVICE
*Service
;
37 EFI_HANDLE Dns4Handle
;
38 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Config2
;
39 UINTN DnsServerListCount
;
40 EFI_IPv4_ADDRESS
*DnsServerList
;
43 Service
= HttpInstance
->Service
;
44 ASSERT (Service
!= NULL
);
47 DnsServerListCount
= 0;
48 ZeroMem (&Token
, sizeof (EFI_DNS4_COMPLETION_TOKEN
));
51 // Get DNS server list from EFI IPv4 Configuration II protocol.
53 Status
= gBS
->HandleProtocol (Service
->ControllerHandle
, &gEfiIp4Config2ProtocolGuid
, (VOID
**)&Ip4Config2
);
54 if (!EFI_ERROR (Status
)) {
56 // Get the required size.
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
;
66 Status
= Ip4Config2
->GetData (Ip4Config2
, Ip4Config2DataTypeDnsServer
, &DataSize
, DnsServerList
);
67 if (EFI_ERROR (Status
)) {
68 FreePool (DnsServerList
);
71 DnsServerListCount
= DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
80 // Create a DNS child instance and get the protocol.
82 Status
= NetLibCreateServiceChild (
83 Service
->ControllerHandle
,
84 Service
->Ip4DriverBindingHandle
,
85 &gEfiDns4ServiceBindingProtocolGuid
,
88 if (EFI_ERROR (Status
)) {
92 Status
= gBS
->OpenProtocol (
94 &gEfiDns4ProtocolGuid
,
96 Service
->Ip4DriverBindingHandle
,
97 Service
->ControllerHandle
,
98 EFI_OPEN_PROTOCOL_BY_DRIVER
100 if (EFI_ERROR (Status
)) {
105 // Configure DNS4 instance for the DNS server address and protocol.
107 ZeroMem (&Dns4CfgData
, sizeof (Dns4CfgData
));
108 Dns4CfgData
.DnsServerListCount
= DnsServerListCount
;
109 Dns4CfgData
.DnsServerList
= DnsServerList
;
110 Dns4CfgData
.UseDefaultSetting
= HttpInstance
->IPv4Node
.UseDefaultAddress
;
111 if (!Dns4CfgData
.UseDefaultSetting
) {
112 IP4_COPY_ADDRESS (&Dns4CfgData
.StationIp
, &HttpInstance
->IPv4Node
.LocalAddress
);
113 IP4_COPY_ADDRESS (&Dns4CfgData
.SubnetMask
, &HttpInstance
->IPv4Node
.LocalSubnet
);
116 Dns4CfgData
.EnableDnsCache
= TRUE
;
117 Dns4CfgData
.Protocol
= EFI_IP_PROTO_UDP
;
118 Status
= Dns4
->Configure (
122 if (EFI_ERROR (Status
)) {
127 // Create event to set the is done flag when name resolution is finished.
129 ZeroMem (&Token
, sizeof (Token
));
130 Status
= gBS
->CreateEvent (
137 if (EFI_ERROR (Status
)) {
142 // Start asynchronous name resolution.
144 Token
.Status
= EFI_NOT_READY
;
146 Status
= Dns4
->HostNameToIp (Dns4
, HostName
, &Token
);
147 if (EFI_ERROR (Status
)) {
156 // Name resolution is done, check result.
158 Status
= Token
.Status
;
159 if (!EFI_ERROR (Status
)) {
160 if (Token
.RspData
.H2AData
== NULL
) {
161 Status
= EFI_DEVICE_ERROR
;
165 if ((Token
.RspData
.H2AData
->IpCount
== 0) || (Token
.RspData
.H2AData
->IpList
== NULL
)) {
166 Status
= EFI_DEVICE_ERROR
;
171 // We just return the first IP address from DNS protocol.
173 IP4_COPY_ADDRESS (IpAddress
, Token
.RspData
.H2AData
->IpList
);
174 Status
= EFI_SUCCESS
;
179 if (Token
.Event
!= NULL
) {
180 gBS
->CloseEvent (Token
.Event
);
183 if (Token
.RspData
.H2AData
!= NULL
) {
184 if (Token
.RspData
.H2AData
->IpList
!= NULL
) {
185 FreePool (Token
.RspData
.H2AData
->IpList
);
188 FreePool (Token
.RspData
.H2AData
);
192 Dns4
->Configure (Dns4
, NULL
);
196 &gEfiDns4ProtocolGuid
,
197 Service
->Ip4DriverBindingHandle
,
198 Service
->ControllerHandle
202 if (Dns4Handle
!= NULL
) {
203 NetLibDestroyServiceChild (
204 Service
->ControllerHandle
,
205 Service
->Ip4DriverBindingHandle
,
206 &gEfiDns4ServiceBindingProtocolGuid
,
211 if (DnsServerList
!= NULL
) {
212 FreePool (DnsServerList
);
219 Retrieve the host address using the EFI_DNS6_PROTOCOL.
221 @param[in] HttpInstance Pointer to HTTP_PROTOCOL instance.
222 @param[in] HostName Pointer to buffer containing hostname.
223 @param[out] IpAddress On output, pointer to buffer containing IPv6 address.
225 @retval EFI_SUCCESS Operation succeeded.
226 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
227 @retval EFI_DEVICE_ERROR An unexpected network error occurred.
228 @retval Others Other errors as indicated.
233 IN HTTP_PROTOCOL
*HttpInstance
,
235 OUT EFI_IPv6_ADDRESS
*IpAddress
239 HTTP_SERVICE
*Service
;
240 EFI_DNS6_PROTOCOL
*Dns6
;
241 EFI_DNS6_CONFIG_DATA Dns6ConfigData
;
242 EFI_DNS6_COMPLETION_TOKEN Token
;
243 EFI_HANDLE Dns6Handle
;
244 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
245 EFI_IPv6_ADDRESS
*DnsServerList
;
246 UINTN DnsServerListCount
;
250 Service
= HttpInstance
->Service
;
251 ASSERT (Service
!= NULL
);
253 DnsServerList
= NULL
;
254 DnsServerListCount
= 0;
257 ZeroMem (&Token
, sizeof (EFI_DNS6_COMPLETION_TOKEN
));
260 // Get DNS server list from EFI IPv6 Configuration protocol.
262 Status
= gBS
->HandleProtocol (Service
->ControllerHandle
, &gEfiIp6ConfigProtocolGuid
, (VOID
**)&Ip6Config
);
263 if (!EFI_ERROR (Status
)) {
265 // Get the required size.
268 Status
= Ip6Config
->GetData (Ip6Config
, Ip6ConfigDataTypeDnsServer
, &DataSize
, NULL
);
269 if (Status
== EFI_BUFFER_TOO_SMALL
) {
270 DnsServerList
= AllocatePool (DataSize
);
271 if (DnsServerList
== NULL
) {
272 return EFI_OUT_OF_RESOURCES
;
275 Status
= Ip6Config
->GetData (Ip6Config
, Ip6ConfigDataTypeDnsServer
, &DataSize
, DnsServerList
);
276 if (EFI_ERROR (Status
)) {
277 FreePool (DnsServerList
);
278 DnsServerList
= NULL
;
280 DnsServerListCount
= DataSize
/ sizeof (EFI_IPv6_ADDRESS
);
286 // Create a DNSv6 child instance and get the protocol.
288 Status
= NetLibCreateServiceChild (
289 Service
->ControllerHandle
,
290 Service
->Ip6DriverBindingHandle
,
291 &gEfiDns6ServiceBindingProtocolGuid
,
294 if (EFI_ERROR (Status
)) {
298 Status
= gBS
->OpenProtocol (
300 &gEfiDns6ProtocolGuid
,
302 Service
->Ip6DriverBindingHandle
,
303 Service
->ControllerHandle
,
304 EFI_OPEN_PROTOCOL_BY_DRIVER
306 if (EFI_ERROR (Status
)) {
311 // Configure DNS6 instance for the DNS server address and protocol.
313 ZeroMem (&Dns6ConfigData
, sizeof (EFI_DNS6_CONFIG_DATA
));
314 Dns6ConfigData
.DnsServerCount
= (UINT32
)DnsServerListCount
;
315 Dns6ConfigData
.DnsServerList
= DnsServerList
;
316 Dns6ConfigData
.EnableDnsCache
= TRUE
;
317 Dns6ConfigData
.Protocol
= EFI_IP_PROTO_UDP
;
318 IP6_COPY_ADDRESS (&Dns6ConfigData
.StationIp
, &HttpInstance
->Ipv6Node
.LocalAddress
);
319 Status
= Dns6
->Configure (
323 if (EFI_ERROR (Status
)) {
327 Token
.Status
= EFI_NOT_READY
;
330 // Create event to set the IsDone flag when name resolution is finished.
332 Status
= gBS
->CreateEvent (
339 if (EFI_ERROR (Status
)) {
344 // Start asynchronous name resolution.
346 Status
= Dns6
->HostNameToIp (Dns6
, HostName
, &Token
);
347 if (EFI_ERROR (Status
)) {
356 // Name resolution is done, check result.
358 Status
= Token
.Status
;
359 if (!EFI_ERROR (Status
)) {
360 if (Token
.RspData
.H2AData
== NULL
) {
361 Status
= EFI_DEVICE_ERROR
;
365 if ((Token
.RspData
.H2AData
->IpCount
== 0) || (Token
.RspData
.H2AData
->IpList
== NULL
)) {
366 Status
= EFI_DEVICE_ERROR
;
371 // We just return the first IPv6 address from DNS protocol.
373 IP6_COPY_ADDRESS (IpAddress
, Token
.RspData
.H2AData
->IpList
);
374 Status
= EFI_SUCCESS
;
379 if (Token
.Event
!= NULL
) {
380 gBS
->CloseEvent (Token
.Event
);
383 if (Token
.RspData
.H2AData
!= NULL
) {
384 if (Token
.RspData
.H2AData
->IpList
!= NULL
) {
385 FreePool (Token
.RspData
.H2AData
->IpList
);
388 FreePool (Token
.RspData
.H2AData
);
392 Dns6
->Configure (Dns6
, NULL
);
396 &gEfiDns6ProtocolGuid
,
397 Service
->Ip6DriverBindingHandle
,
398 Service
->ControllerHandle
402 if (Dns6Handle
!= NULL
) {
403 NetLibDestroyServiceChild (
404 Service
->ControllerHandle
,
405 Service
->Ip6DriverBindingHandle
,
406 &gEfiDns6ServiceBindingProtocolGuid
,
411 if (DnsServerList
!= NULL
) {
412 FreePool (DnsServerList
);