]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IScsiDxe/IScsiDns.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiDns.c
CommitLineData
eabc6e59
ZL
1/** @file\r
2 Perform DNS resolution based on UEFI DNS protocols.\r
3\r
4Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
ecf98fbc 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
eabc6e59
ZL
6\r
7**/\r
8\r
9#include "IScsiImpl.h"\r
10\r
11/**\r
12 Notify the callback function when an event is triggered.\r
13\r
14 @param[in] Event The triggered event.\r
15 @param[in] Context The opaque parameter to the function.\r
16\r
17**/\r
18VOID\r
19EFIAPI\r
20IScsiCommonNotify (\r
d1050b9d
MK
21 IN EFI_EVENT Event,\r
22 IN VOID *Context\r
eabc6e59
ZL
23 )\r
24{\r
d1050b9d 25 *((BOOLEAN *)Context) = TRUE;\r
eabc6e59
ZL
26}\r
27\r
28/**\r
29 Retrieve the host address using the EFI_DNS4_PROTOCOL.\r
30\r
31 @param[in] Image The handle of the driver image.\r
32 @param[in] Controller The handle of the controller.\r
33 @param[in, out] NvData The Session config data structure.\r
34\r
35 @retval EFI_SUCCESS Operation succeeded.\r
36 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
37 @retval EFI_DEVICE_ERROR An unexpected network error occurred.\r
38 @retval Others Other errors as indicated.\r
39\r
40**/\r
41EFI_STATUS\r
42IScsiDns4 (\r
d1050b9d
MK
43 IN EFI_HANDLE Image,\r
44 IN EFI_HANDLE Controller,\r
45 IN OUT ISCSI_SESSION_CONFIG_NVDATA *NvData\r
eabc6e59
ZL
46 )\r
47{\r
d1050b9d
MK
48 EFI_STATUS Status;\r
49 EFI_DNS4_PROTOCOL *Dns4;\r
50 EFI_DNS4_CONFIG_DATA Dns4CfgData;\r
51 EFI_DNS4_COMPLETION_TOKEN Token;\r
52 BOOLEAN IsDone;\r
53 EFI_HANDLE Dns4Handle;\r
54 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;\r
55 EFI_IPv4_ADDRESS *DnsServerList;\r
56 UINTN DnsServerListCount;\r
57 UINTN DataSize;\r
58 CHAR16 *HostName;\r
eabc6e59
ZL
59\r
60 DnsServerList = NULL;\r
61 DnsServerListCount = 0;\r
62 Dns4Handle = NULL;\r
63 Dns4 = NULL;\r
64 ZeroMem (&Token, sizeof (EFI_DNS4_COMPLETION_TOKEN));\r
65\r
66 //\r
67 // Get DNS server list from EFI IPv4 Configuration II protocol.\r
68 //\r
d1050b9d 69 Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **)&Ip4Config2);\r
eabc6e59
ZL
70 if (!EFI_ERROR (Status)) {\r
71 //\r
72 // Get the required size.\r
73 //\r
74 DataSize = 0;\r
75 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, NULL);\r
76 if (Status == EFI_BUFFER_TOO_SMALL) {\r
77 DnsServerList = AllocatePool (DataSize);\r
78 if (DnsServerList == NULL) {\r
79 return EFI_OUT_OF_RESOURCES;\r
80 }\r
81\r
d1050b9d 82 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, &DataSize, DnsServerList);\r
eabc6e59
ZL
83 if (EFI_ERROR (Status)) {\r
84 FreePool (DnsServerList);\r
85 DnsServerList = NULL;\r
86 } else {\r
87 DnsServerListCount = DataSize / sizeof (EFI_IPv4_ADDRESS);\r
88 }\r
89 }\r
90 }\r
91\r
eabc6e59
ZL
92 //\r
93 // Create a DNS child instance and get the protocol.\r
94 //\r
95 Status = NetLibCreateServiceChild (\r
96 Controller,\r
97 Image,\r
98 &gEfiDns4ServiceBindingProtocolGuid,\r
99 &Dns4Handle\r
100 );\r
101 if (EFI_ERROR (Status)) {\r
102 goto Exit;\r
103 }\r
104\r
105 Status = gBS->OpenProtocol (\r
106 Dns4Handle,\r
107 &gEfiDns4ProtocolGuid,\r
d1050b9d 108 (VOID **)&Dns4,\r
eabc6e59
ZL
109 Image,\r
110 Controller,\r
111 EFI_OPEN_PROTOCOL_BY_DRIVER\r
112 );\r
113 if (EFI_ERROR (Status)) {\r
114 goto Exit;\r
115 }\r
116\r
117 //\r
118 // Configure DNS4 instance for the DNS server address and protocol.\r
119 //\r
120 ZeroMem (&Dns4CfgData, sizeof (Dns4CfgData));\r
121 Dns4CfgData.DnsServerListCount = DnsServerListCount;\r
122 Dns4CfgData.DnsServerList = DnsServerList;\r
123 Dns4CfgData.EnableDnsCache = TRUE;\r
124 IP4_COPY_ADDRESS (&Dns4CfgData.StationIp, &NvData->LocalIp);\r
125 IP4_COPY_ADDRESS (&Dns4CfgData.SubnetMask, &NvData->SubnetMask);\r
d1050b9d
MK
126 Dns4CfgData.Protocol = EFI_IP_PROTO_UDP;\r
127 Status = Dns4->Configure (\r
128 Dns4,\r
129 &Dns4CfgData\r
130 );\r
eabc6e59
ZL
131 if (EFI_ERROR (Status)) {\r
132 goto Exit;\r
133 }\r
134\r
135 //\r
136 // Create event to set the is done flag when name resolution is finished.\r
137 //\r
138 ZeroMem (&Token, sizeof (Token));\r
139 Status = gBS->CreateEvent (\r
140 EVT_NOTIFY_SIGNAL,\r
141 TPL_NOTIFY,\r
142 IScsiCommonNotify,\r
143 &IsDone,\r
144 &Token.Event\r
145 );\r
146 if (EFI_ERROR (Status)) {\r
147 goto Exit;\r
148 }\r
149\r
150 //\r
151 // Start asynchronous name resolution.\r
152 //\r
153 Token.Status = EFI_NOT_READY;\r
154 IsDone = FALSE;\r
155\r
d1050b9d 156 HostName = (CHAR16 *)AllocateZeroPool (ISCSI_NAME_MAX_SIZE);\r
eabc6e59
ZL
157 if (HostName == NULL) {\r
158 return EFI_OUT_OF_RESOURCES;\r
159 }\r
160\r
161 AsciiStrToUnicodeStrS (\r
162 NvData->TargetUrl,\r
163 HostName,\r
164 ISCSI_NAME_MAX_SIZE\r
165 );\r
166\r
167 Status = Dns4->HostNameToIp (Dns4, HostName, &Token);\r
168 if (EFI_ERROR (Status)) {\r
169 goto Exit;\r
170 }\r
171\r
172 while (!IsDone) {\r
173 Dns4->Poll (Dns4);\r
174 }\r
175\r
176 //\r
177 // Name resolution is done, check result.\r
178 //\r
179 Status = Token.Status;\r
180 if (!EFI_ERROR (Status)) {\r
181 if (Token.RspData.H2AData == NULL) {\r
182 Status = EFI_DEVICE_ERROR;\r
183 goto Exit;\r
184 }\r
d1050b9d
MK
185\r
186 if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) {\r
eabc6e59
ZL
187 Status = EFI_DEVICE_ERROR;\r
188 goto Exit;\r
189 }\r
d1050b9d 190\r
eabc6e59
ZL
191 //\r
192 // We just return the first IP address from DNS protocol.\r
193 //\r
194 IP4_COPY_ADDRESS (&NvData->TargetIp.v4, Token.RspData.H2AData->IpList);\r
195 Status = EFI_SUCCESS;\r
196 }\r
197\r
198Exit:\r
199\r
200 if (Token.Event != NULL) {\r
201 gBS->CloseEvent (Token.Event);\r
202 }\r
d1050b9d 203\r
eabc6e59
ZL
204 if (Token.RspData.H2AData != NULL) {\r
205 if (Token.RspData.H2AData->IpList != NULL) {\r
206 FreePool (Token.RspData.H2AData->IpList);\r
207 }\r
d1050b9d 208\r
eabc6e59
ZL
209 FreePool (Token.RspData.H2AData);\r
210 }\r
211\r
212 if (Dns4 != NULL) {\r
213 Dns4->Configure (Dns4, NULL);\r
214\r
215 gBS->CloseProtocol (\r
216 Dns4Handle,\r
217 &gEfiDns4ProtocolGuid,\r
218 Image,\r
219 Controller\r
220 );\r
221 }\r
222\r
223 if (Dns4Handle != NULL) {\r
224 NetLibDestroyServiceChild (\r
225 Controller,\r
226 Image,\r
227 &gEfiDns4ServiceBindingProtocolGuid,\r
228 Dns4Handle\r
229 );\r
230 }\r
231\r
232 return Status;\r
233}\r
234\r
235/**\r
236 Retrieve the host address using the EFI_DNS6_PROTOCOL.\r
237\r
238 @param[in] Image The handle of the driver image.\r
239 @param[in] Controller The handle of the controller.\r
240 @param[in, out] NvData The Session config data structure.\r
241\r
242 @retval EFI_SUCCESS Operation succeeded.\r
243 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
244 @retval EFI_DEVICE_ERROR An unexpected network error occurred.\r
245 @retval Others Other errors as indicated.\r
246\r
247**/\r
248EFI_STATUS\r
249IScsiDns6 (\r
d1050b9d
MK
250 IN EFI_HANDLE Image,\r
251 IN EFI_HANDLE Controller,\r
252 IN OUT ISCSI_SESSION_CONFIG_NVDATA *NvData\r
eabc6e59
ZL
253 )\r
254{\r
d1050b9d
MK
255 EFI_STATUS Status;\r
256 EFI_DNS6_PROTOCOL *Dns6;\r
257 EFI_DNS6_CONFIG_DATA Dns6ConfigData;\r
258 EFI_DNS6_COMPLETION_TOKEN Token;\r
259 EFI_HANDLE Dns6Handle;\r
260 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
261 EFI_IPv6_ADDRESS *DnsServerList;\r
262 UINTN DnsServerListCount;\r
263 UINTN DataSize;\r
264 BOOLEAN IsDone;\r
265 CHAR16 *HostName;\r
266\r
267 DnsServerList = NULL;\r
268 DnsServerListCount = 0;\r
269 Dns6 = NULL;\r
270 Dns6Handle = NULL;\r
eabc6e59
ZL
271 ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));\r
272\r
273 //\r
274 // Get DNS server list from EFI IPv6 Configuration protocol.\r
275 //\r
d1050b9d 276 Status = gBS->HandleProtocol (Controller, &gEfiIp6ConfigProtocolGuid, (VOID **)&Ip6Config);\r
eabc6e59
ZL
277 if (!EFI_ERROR (Status)) {\r
278 //\r
279 // Get the required size.\r
280 //\r
281 DataSize = 0;\r
d1050b9d 282 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, NULL);\r
eabc6e59
ZL
283 if (Status == EFI_BUFFER_TOO_SMALL) {\r
284 DnsServerList = AllocatePool (DataSize);\r
285 if (DnsServerList == NULL) {\r
286 return EFI_OUT_OF_RESOURCES;\r
287 }\r
288\r
289 Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);\r
290 if (EFI_ERROR (Status)) {\r
291 FreePool (DnsServerList);\r
292 DnsServerList = NULL;\r
293 } else {\r
294 DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);\r
295 }\r
296 }\r
297 }\r
298\r
299 //\r
300 // Create a DNSv6 child instance and get the protocol.\r
301 //\r
302 Status = NetLibCreateServiceChild (\r
303 Controller,\r
304 Image,\r
305 &gEfiDns6ServiceBindingProtocolGuid,\r
306 &Dns6Handle\r
307 );\r
308 if (EFI_ERROR (Status)) {\r
309 goto Exit;\r
310 }\r
311\r
312 Status = gBS->OpenProtocol (\r
313 Dns6Handle,\r
314 &gEfiDns6ProtocolGuid,\r
d1050b9d 315 (VOID **)&Dns6,\r
eabc6e59
ZL
316 Image,\r
317 Controller,\r
318 EFI_OPEN_PROTOCOL_BY_DRIVER\r
319 );\r
320 if (EFI_ERROR (Status)) {\r
321 goto Exit;\r
322 }\r
323\r
324 //\r
325 // Configure DNS6 instance for the DNS server address and protocol.\r
326 //\r
327 ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));\r
328 Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;\r
329 Dns6ConfigData.DnsServerList = DnsServerList;\r
330 Dns6ConfigData.EnableDnsCache = TRUE;\r
331 Dns6ConfigData.Protocol = EFI_IP_PROTO_UDP;\r
d1050b9d
MK
332 Status = Dns6->Configure (\r
333 Dns6,\r
334 &Dns6ConfigData\r
335 );\r
eabc6e59
ZL
336 if (EFI_ERROR (Status)) {\r
337 goto Exit;\r
338 }\r
339\r
340 Token.Status = EFI_NOT_READY;\r
341 IsDone = FALSE;\r
342 //\r
343 // Create event to set the IsDone flag when name resolution is finished.\r
344 //\r
345 Status = gBS->CreateEvent (\r
346 EVT_NOTIFY_SIGNAL,\r
347 TPL_NOTIFY,\r
348 IScsiCommonNotify,\r
349 &IsDone,\r
350 &Token.Event\r
351 );\r
352 if (EFI_ERROR (Status)) {\r
353 goto Exit;\r
354 }\r
355\r
356 //\r
357 // Start asynchronous name resolution.\r
358 //\r
d1050b9d 359 HostName = (CHAR16 *)AllocateZeroPool (ISCSI_NAME_MAX_SIZE);\r
eabc6e59
ZL
360 if (HostName == NULL) {\r
361 return EFI_OUT_OF_RESOURCES;\r
362 }\r
363\r
364 AsciiStrToUnicodeStrS (\r
365 NvData->TargetUrl,\r
366 HostName,\r
367 ISCSI_NAME_MAX_SIZE\r
368 );\r
369 Status = Dns6->HostNameToIp (Dns6, HostName, &Token);\r
370 if (EFI_ERROR (Status)) {\r
371 goto Exit;\r
372 }\r
373\r
374 while (!IsDone) {\r
375 Dns6->Poll (Dns6);\r
376 }\r
377\r
378 //\r
379 // Name resolution is done, check result.\r
380 //\r
381 Status = Token.Status;\r
382 if (!EFI_ERROR (Status)) {\r
383 if (Token.RspData.H2AData == NULL) {\r
384 Status = EFI_DEVICE_ERROR;\r
385 goto Exit;\r
386 }\r
d1050b9d
MK
387\r
388 if ((Token.RspData.H2AData->IpCount == 0) || (Token.RspData.H2AData->IpList == NULL)) {\r
eabc6e59
ZL
389 Status = EFI_DEVICE_ERROR;\r
390 goto Exit;\r
391 }\r
d1050b9d 392\r
eabc6e59
ZL
393 //\r
394 // We just return the first IPv6 address from DNS protocol.\r
395 //\r
396 IP6_COPY_ADDRESS (&NvData->TargetIp.v6, Token.RspData.H2AData->IpList);\r
397 Status = EFI_SUCCESS;\r
398 }\r
399\r
400Exit:\r
401\r
402 if (Token.Event != NULL) {\r
403 gBS->CloseEvent (Token.Event);\r
404 }\r
d1050b9d 405\r
eabc6e59
ZL
406 if (Token.RspData.H2AData != NULL) {\r
407 if (Token.RspData.H2AData->IpList != NULL) {\r
408 FreePool (Token.RspData.H2AData->IpList);\r
409 }\r
d1050b9d 410\r
eabc6e59
ZL
411 FreePool (Token.RspData.H2AData);\r
412 }\r
413\r
414 if (Dns6 != NULL) {\r
415 Dns6->Configure (Dns6, NULL);\r
416\r
417 gBS->CloseProtocol (\r
418 Dns6Handle,\r
419 &gEfiDns6ProtocolGuid,\r
420 Image,\r
421 Controller\r
422 );\r
423 }\r
424\r
425 if (Dns6Handle != NULL) {\r
426 NetLibDestroyServiceChild (\r
427 Controller,\r
428 Image,\r
429 &gEfiDns6ServiceBindingProtocolGuid,\r
430 Dns6Handle\r
431 );\r
432 }\r
433\r
434 return Status;\r
435}\r