2 Routines for HttpDxe driver to perform DNS resolution based on UEFI DNS protocols.
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "HttpDriver.h"
18 Retrieve the host address using the EFI_DNS4_PROTOCOL.
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.
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.
32 IN HTTP_PROTOCOL
*HttpInstance
,
34 OUT EFI_IPv4_ADDRESS
*IpAddress
38 EFI_DNS4_PROTOCOL
*Dns4
;
39 EFI_DNS4_CONFIG_DATA Dns4CfgData
;
40 EFI_DNS4_COMPLETION_TOKEN Token
;
42 HTTP_SERVICE
*Service
;
43 EFI_HANDLE Dns4Handle
;
44 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Config2
;
45 UINTN DnsServerListCount
;
46 EFI_IPv4_ADDRESS
*DnsServerList
;
50 Service
= HttpInstance
->Service
;
51 ASSERT (Service
!= NULL
);
54 DnsServerListCount
= 0;
55 ZeroMem (&Token
, sizeof (EFI_DNS4_COMPLETION_TOKEN
));
58 // Get DNS server list from EFI IPv4 Configuration II protocol.
60 Status
= gBS
->HandleProtocol (Service
->ControllerHandle
, &gEfiIp4Config2ProtocolGuid
, (VOID
**) &Ip4Config2
);
61 if (!EFI_ERROR (Status
)) {
63 // Get the required size.
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
;
73 Status
= Ip4Config2
->GetData (Ip4Config2
, Ip4Config2DataTypeDnsServer
, &DataSize
, DnsServerList
);
74 if (EFI_ERROR (Status
)) {
75 FreePool (DnsServerList
);
78 DnsServerListCount
= DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
87 // Create a DNS child instance and get the protocol.
89 Status
= NetLibCreateServiceChild (
90 Service
->ControllerHandle
,
91 Service
->Ip4DriverBindingHandle
,
92 &gEfiDns4ServiceBindingProtocolGuid
,
95 if (EFI_ERROR (Status
)) {
99 Status
= gBS
->OpenProtocol (
101 &gEfiDns4ProtocolGuid
,
103 Service
->Ip4DriverBindingHandle
,
104 Service
->ControllerHandle
,
105 EFI_OPEN_PROTOCOL_BY_DRIVER
107 if (EFI_ERROR (Status
)) {
112 // Configure DNS4 instance for the DNS server address and protocol.
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
);
122 Dns4CfgData
.EnableDnsCache
= TRUE
;
123 Dns4CfgData
.Protocol
= EFI_IP_PROTO_UDP
;
124 Status
= Dns4
->Configure (
128 if (EFI_ERROR (Status
)) {
133 // Create event to set the is done flag when name resolution is finished.
135 ZeroMem (&Token
, sizeof (Token
));
136 Status
= gBS
->CreateEvent (
143 if (EFI_ERROR (Status
)) {
148 // Start asynchronous name resolution.
150 Token
.Status
= EFI_NOT_READY
;
152 Status
= Dns4
->HostNameToIp (Dns4
, HostName
, &Token
);
153 if (EFI_ERROR (Status
)) {
162 // Name resolution is done, check result.
164 Status
= Token
.Status
;
165 if (!EFI_ERROR (Status
)) {
166 if (Token
.RspData
.H2AData
== NULL
) {
167 Status
= EFI_DEVICE_ERROR
;
170 if (Token
.RspData
.H2AData
->IpCount
== 0 || Token
.RspData
.H2AData
->IpList
== NULL
) {
171 Status
= EFI_DEVICE_ERROR
;
175 // We just return the first IP address from DNS protocol.
177 IP4_COPY_ADDRESS (IpAddress
, Token
.RspData
.H2AData
->IpList
);
178 Status
= EFI_SUCCESS
;
183 if (Token
.Event
!= NULL
) {
184 gBS
->CloseEvent (Token
.Event
);
186 if (Token
.RspData
.H2AData
!= NULL
) {
187 if (Token
.RspData
.H2AData
->IpList
!= NULL
) {
188 FreePool (Token
.RspData
.H2AData
->IpList
);
190 FreePool (Token
.RspData
.H2AData
);
194 Dns4
->Configure (Dns4
, NULL
);
198 &gEfiDns4ProtocolGuid
,
199 Service
->Ip4DriverBindingHandle
,
200 Service
->ControllerHandle
204 if (Dns4Handle
!= NULL
) {
205 NetLibDestroyServiceChild (
206 Service
->ControllerHandle
,
207 Service
->Ip4DriverBindingHandle
,
208 &gEfiDns4ServiceBindingProtocolGuid
,
213 if (DnsServerList
!= NULL
) {
214 FreePool (DnsServerList
);
221 Retrieve the host address using the EFI_DNS6_PROTOCOL.
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.
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.
235 IN HTTP_PROTOCOL
*HttpInstance
,
237 OUT EFI_IPv6_ADDRESS
*IpAddress
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
;
253 Service
= HttpInstance
->Service
;
254 ASSERT (Service
!= NULL
);
256 DnsServerList
= NULL
;
257 DnsServerListCount
= 0;
260 ZeroMem (&Token
, sizeof (EFI_DNS6_COMPLETION_TOKEN
));
263 // Get DNS server list from EFI IPv6 Configuration protocol.
265 Status
= gBS
->HandleProtocol (Service
->ControllerHandle
, &gEfiIp6ConfigProtocolGuid
, (VOID
**) &Ip6Config
);
266 if (!EFI_ERROR (Status
)) {
268 // Get the required size.
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
;
278 Status
= Ip6Config
->GetData (Ip6Config
, Ip6ConfigDataTypeDnsServer
, &DataSize
, DnsServerList
);
279 if (EFI_ERROR (Status
)) {
280 FreePool (DnsServerList
);
281 DnsServerList
= NULL
;
283 DnsServerListCount
= DataSize
/ sizeof (EFI_IPv6_ADDRESS
);
289 // Create a DNSv6 child instance and get the protocol.
291 Status
= NetLibCreateServiceChild (
292 Service
->ControllerHandle
,
293 Service
->Ip6DriverBindingHandle
,
294 &gEfiDns6ServiceBindingProtocolGuid
,
297 if (EFI_ERROR (Status
)) {
301 Status
= gBS
->OpenProtocol (
303 &gEfiDns6ProtocolGuid
,
305 Service
->Ip6DriverBindingHandle
,
306 Service
->ControllerHandle
,
307 EFI_OPEN_PROTOCOL_BY_DRIVER
309 if (EFI_ERROR (Status
)) {
314 // Configure DNS6 instance for the DNS server address and protocol.
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 (
326 if (EFI_ERROR (Status
)) {
330 Token
.Status
= EFI_NOT_READY
;
333 // Create event to set the IsDone flag when name resolution is finished.
335 Status
= gBS
->CreateEvent (
342 if (EFI_ERROR (Status
)) {
347 // Start asynchronous name resolution.
349 Status
= Dns6
->HostNameToIp (Dns6
, HostName
, &Token
);
350 if (EFI_ERROR (Status
)) {
359 // Name resolution is done, check result.
361 Status
= Token
.Status
;
362 if (!EFI_ERROR (Status
)) {
363 if (Token
.RspData
.H2AData
== NULL
) {
364 Status
= EFI_DEVICE_ERROR
;
367 if (Token
.RspData
.H2AData
->IpCount
== 0 || Token
.RspData
.H2AData
->IpList
== NULL
) {
368 Status
= EFI_DEVICE_ERROR
;
372 // We just return the first IPv6 address from DNS protocol.
374 IP6_COPY_ADDRESS (IpAddress
, Token
.RspData
.H2AData
->IpList
);
375 Status
= EFI_SUCCESS
;
380 if (Token
.Event
!= NULL
) {
381 gBS
->CloseEvent (Token
.Event
);
383 if (Token
.RspData
.H2AData
!= NULL
) {
384 if (Token
.RspData
.H2AData
->IpList
!= NULL
) {
385 FreePool (Token
.RspData
.H2AData
->IpList
);
387 FreePool (Token
.RspData
.H2AData
);
391 Dns6
->Configure (Dns6
, NULL
);
395 &gEfiDns6ProtocolGuid
,
396 Service
->Ip6DriverBindingHandle
,
397 Service
->ControllerHandle
401 if (Dns6Handle
!= NULL
) {
402 NetLibDestroyServiceChild (
403 Service
->ControllerHandle
,
404 Service
->Ip6DriverBindingHandle
,
405 &gEfiDns6ServiceBindingProtocolGuid
,
410 if (DnsServerList
!= NULL
) {
411 FreePool (DnsServerList
);