2 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 "IScsiImpl.h"
18 Notify the callback function when an event is triggered.
20 @param[in] Event The triggered event.
21 @param[in] Context The opaque parameter to the function.
31 *((BOOLEAN
*) Context
) = TRUE
;
35 Retrieve the host address using the EFI_DNS4_PROTOCOL.
37 @param[in] Image The handle of the driver image.
38 @param[in] Controller The handle of the controller.
39 @param[in, out] NvData The Session config data structure.
41 @retval EFI_SUCCESS Operation succeeded.
42 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
43 @retval EFI_DEVICE_ERROR An unexpected network error occurred.
44 @retval Others Other errors as indicated.
50 IN EFI_HANDLE Controller
,
51 IN OUT ISCSI_SESSION_CONFIG_NVDATA
*NvData
55 EFI_DNS4_PROTOCOL
*Dns4
;
56 EFI_DNS4_CONFIG_DATA Dns4CfgData
;
57 EFI_DNS4_COMPLETION_TOKEN Token
;
59 EFI_HANDLE Dns4Handle
;
60 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Config2
;
61 EFI_IPv4_ADDRESS
*DnsServerList
;
62 UINTN DnsServerListCount
;
67 DnsServerListCount
= 0;
70 ZeroMem (&Token
, sizeof (EFI_DNS4_COMPLETION_TOKEN
));
73 // Get DNS server list from EFI IPv4 Configuration II protocol.
75 Status
= gBS
->HandleProtocol (Controller
, &gEfiIp4Config2ProtocolGuid
, (VOID
**) &Ip4Config2
);
76 if (!EFI_ERROR (Status
)) {
78 // Get the required size.
81 Status
= Ip4Config2
->GetData (Ip4Config2
, Ip4Config2DataTypeDnsServer
, &DataSize
, NULL
);
82 if (Status
== EFI_BUFFER_TOO_SMALL
) {
83 DnsServerList
= AllocatePool (DataSize
);
84 if (DnsServerList
== NULL
) {
85 return EFI_OUT_OF_RESOURCES
;
88 Status
= Ip4Config2
->GetData (Ip4Config2
, Ip4Config2DataTypeDnsServer
, &DataSize
, DnsServerList
);
89 if (EFI_ERROR (Status
)) {
90 FreePool (DnsServerList
);
93 DnsServerListCount
= DataSize
/ sizeof (EFI_IPv4_ADDRESS
);
100 // Create a DNS child instance and get the protocol.
102 Status
= NetLibCreateServiceChild (
105 &gEfiDns4ServiceBindingProtocolGuid
,
108 if (EFI_ERROR (Status
)) {
112 Status
= gBS
->OpenProtocol (
114 &gEfiDns4ProtocolGuid
,
118 EFI_OPEN_PROTOCOL_BY_DRIVER
120 if (EFI_ERROR (Status
)) {
125 // Configure DNS4 instance for the DNS server address and protocol.
127 ZeroMem (&Dns4CfgData
, sizeof (Dns4CfgData
));
128 Dns4CfgData
.DnsServerListCount
= DnsServerListCount
;
129 Dns4CfgData
.DnsServerList
= DnsServerList
;
130 Dns4CfgData
.EnableDnsCache
= TRUE
;
131 IP4_COPY_ADDRESS (&Dns4CfgData
.StationIp
, &NvData
->LocalIp
);
132 IP4_COPY_ADDRESS (&Dns4CfgData
.SubnetMask
, &NvData
->SubnetMask
);
133 Dns4CfgData
.Protocol
= EFI_IP_PROTO_UDP
;
134 Status
= Dns4
->Configure (
138 if (EFI_ERROR (Status
)) {
143 // Create event to set the is done flag when name resolution is finished.
145 ZeroMem (&Token
, sizeof (Token
));
146 Status
= gBS
->CreateEvent (
153 if (EFI_ERROR (Status
)) {
158 // Start asynchronous name resolution.
160 Token
.Status
= EFI_NOT_READY
;
163 HostName
= (CHAR16
*) AllocateZeroPool (ISCSI_NAME_MAX_SIZE
);
164 if (HostName
== NULL
) {
165 return EFI_OUT_OF_RESOURCES
;
168 AsciiStrToUnicodeStrS (
174 Status
= Dns4
->HostNameToIp (Dns4
, HostName
, &Token
);
175 if (EFI_ERROR (Status
)) {
184 // Name resolution is done, check result.
186 Status
= Token
.Status
;
187 if (!EFI_ERROR (Status
)) {
188 if (Token
.RspData
.H2AData
== NULL
) {
189 Status
= EFI_DEVICE_ERROR
;
192 if (Token
.RspData
.H2AData
->IpCount
== 0 || Token
.RspData
.H2AData
->IpList
== NULL
) {
193 Status
= EFI_DEVICE_ERROR
;
197 // We just return the first IP address from DNS protocol.
199 IP4_COPY_ADDRESS (&NvData
->TargetIp
.v4
, Token
.RspData
.H2AData
->IpList
);
200 Status
= EFI_SUCCESS
;
205 if (Token
.Event
!= NULL
) {
206 gBS
->CloseEvent (Token
.Event
);
208 if (Token
.RspData
.H2AData
!= NULL
) {
209 if (Token
.RspData
.H2AData
->IpList
!= NULL
) {
210 FreePool (Token
.RspData
.H2AData
->IpList
);
212 FreePool (Token
.RspData
.H2AData
);
216 Dns4
->Configure (Dns4
, NULL
);
220 &gEfiDns4ProtocolGuid
,
226 if (Dns4Handle
!= NULL
) {
227 NetLibDestroyServiceChild (
230 &gEfiDns4ServiceBindingProtocolGuid
,
239 Retrieve the host address using the EFI_DNS6_PROTOCOL.
241 @param[in] Image The handle of the driver image.
242 @param[in] Controller The handle of the controller.
243 @param[in, out] NvData The Session config data structure.
245 @retval EFI_SUCCESS Operation succeeded.
246 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
247 @retval EFI_DEVICE_ERROR An unexpected network error occurred.
248 @retval Others Other errors as indicated.
254 IN EFI_HANDLE Controller
,
255 IN OUT ISCSI_SESSION_CONFIG_NVDATA
*NvData
259 EFI_DNS6_PROTOCOL
*Dns6
;
260 EFI_DNS6_CONFIG_DATA Dns6ConfigData
;
261 EFI_DNS6_COMPLETION_TOKEN Token
;
262 EFI_HANDLE Dns6Handle
;
263 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
264 EFI_IPv6_ADDRESS
*DnsServerList
;
265 UINTN DnsServerListCount
;
270 DnsServerList
= NULL
;
271 DnsServerListCount
= 0;
274 ZeroMem (&Token
, sizeof (EFI_DNS6_COMPLETION_TOKEN
));
277 // Get DNS server list from EFI IPv6 Configuration protocol.
279 Status
= gBS
->HandleProtocol (Controller
, &gEfiIp6ConfigProtocolGuid
, (VOID
**) &Ip6Config
);
280 if (!EFI_ERROR (Status
)) {
282 // Get the required size.
285 Status
= Ip6Config
->GetData (Ip6Config
, Ip6ConfigDataTypeDnsServer
, &DataSize
, NULL
);
286 if (Status
== EFI_BUFFER_TOO_SMALL
) {
287 DnsServerList
= AllocatePool (DataSize
);
288 if (DnsServerList
== NULL
) {
289 return EFI_OUT_OF_RESOURCES
;
292 Status
= Ip6Config
->GetData (Ip6Config
, Ip6ConfigDataTypeDnsServer
, &DataSize
, DnsServerList
);
293 if (EFI_ERROR (Status
)) {
294 FreePool (DnsServerList
);
295 DnsServerList
= NULL
;
297 DnsServerListCount
= DataSize
/ sizeof (EFI_IPv6_ADDRESS
);
303 // Create a DNSv6 child instance and get the protocol.
305 Status
= NetLibCreateServiceChild (
308 &gEfiDns6ServiceBindingProtocolGuid
,
311 if (EFI_ERROR (Status
)) {
315 Status
= gBS
->OpenProtocol (
317 &gEfiDns6ProtocolGuid
,
321 EFI_OPEN_PROTOCOL_BY_DRIVER
323 if (EFI_ERROR (Status
)) {
328 // Configure DNS6 instance for the DNS server address and protocol.
330 ZeroMem (&Dns6ConfigData
, sizeof (EFI_DNS6_CONFIG_DATA
));
331 Dns6ConfigData
.DnsServerCount
= (UINT32
)DnsServerListCount
;
332 Dns6ConfigData
.DnsServerList
= DnsServerList
;
333 Dns6ConfigData
.EnableDnsCache
= TRUE
;
334 Dns6ConfigData
.Protocol
= EFI_IP_PROTO_UDP
;
335 Status
= Dns6
->Configure (
339 if (EFI_ERROR (Status
)) {
343 Token
.Status
= EFI_NOT_READY
;
346 // Create event to set the IsDone flag when name resolution is finished.
348 Status
= gBS
->CreateEvent (
355 if (EFI_ERROR (Status
)) {
360 // Start asynchronous name resolution.
362 HostName
= (CHAR16
*) AllocateZeroPool (ISCSI_NAME_MAX_SIZE
);
363 if (HostName
== NULL
) {
364 return EFI_OUT_OF_RESOURCES
;
367 AsciiStrToUnicodeStrS (
372 Status
= Dns6
->HostNameToIp (Dns6
, HostName
, &Token
);
373 if (EFI_ERROR (Status
)) {
382 // Name resolution is done, check result.
384 Status
= Token
.Status
;
385 if (!EFI_ERROR (Status
)) {
386 if (Token
.RspData
.H2AData
== NULL
) {
387 Status
= EFI_DEVICE_ERROR
;
390 if (Token
.RspData
.H2AData
->IpCount
== 0 || Token
.RspData
.H2AData
->IpList
== NULL
) {
391 Status
= EFI_DEVICE_ERROR
;
395 // We just return the first IPv6 address from DNS protocol.
397 IP6_COPY_ADDRESS (&NvData
->TargetIp
.v6
, Token
.RspData
.H2AData
->IpList
);
398 Status
= EFI_SUCCESS
;
403 if (Token
.Event
!= NULL
) {
404 gBS
->CloseEvent (Token
.Event
);
406 if (Token
.RspData
.H2AData
!= NULL
) {
407 if (Token
.RspData
.H2AData
->IpList
!= NULL
) {
408 FreePool (Token
.RspData
.H2AData
->IpList
);
410 FreePool (Token
.RspData
.H2AData
);
414 Dns6
->Configure (Dns6
, NULL
);
418 &gEfiDns6ProtocolGuid
,
424 if (Dns6Handle
!= NULL
) {
425 NetLibDestroyServiceChild (
428 &gEfiDns6ServiceBindingProtocolGuid
,