]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/DnsDxe/DnsProtocol.c
NetworkPkg: Remove ASSERT and use error handling in IpSecDxe
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsProtocol.c
CommitLineData
99c048ef 1/** @file\r
2Implementation of EFI_DNS4_PROTOCOL and EFI_DNS6_PROTOCOL interfaces.\r
3\r
0f4e123f 4Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
99c048ef 5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "DnsImpl.h"\r
16\r
17EFI_DNS4_PROTOCOL mDns4Protocol = {\r
18 Dns4GetModeData,\r
19 Dns4Configure,\r
20 Dns4HostNameToIp,\r
21 Dns4IpToHostName,\r
22 Dns4GeneralLookUp,\r
23 Dns4UpdateDnsCache,\r
24 Dns4Poll,\r
25 Dns4Cancel\r
26};\r
27\r
28EFI_DNS6_PROTOCOL mDns6Protocol = {\r
29 Dns6GetModeData,\r
30 Dns6Configure,\r
31 Dns6HostNameToIp,\r
32 Dns6IpToHostName,\r
33 Dns6GeneralLookUp,\r
34 Dns6UpdateDnsCache,\r
35 Dns6Poll,\r
36 Dns6Cancel\r
37};\r
38\r
39/**\r
0f4e123f 40 Retrieve mode data of this DNS instance.\r
99c048ef 41\r
0f4e123f 42 This function is used to retrieve DNS mode data for this DNS instance.\r
99c048ef 43\r
0f4e123f
JW
44 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
45 @param[out] DnsModeData Point to the mode data.\r
99c048ef 46\r
0f4e123f
JW
47 @retval EFI_SUCCESS The operation completed successfully.\r
48 @retval EFI_NOT_STARTED When DnsConfigData is queried, no configuration data\r
49 is available because this instance has not been\r
50 configured.\r
51 @retval EFI_INVALID_PARAMETER This is NULL or DnsModeData is NULL.\r
52 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 53**/\r
54EFI_STATUS\r
55EFIAPI\r
56Dns4GetModeData (\r
57 IN EFI_DNS4_PROTOCOL *This,\r
58 OUT EFI_DNS4_MODE_DATA *DnsModeData\r
59 )\r
60{\r
61 DNS_INSTANCE *Instance;\r
62 \r
63 EFI_TPL OldTpl;\r
64\r
65 UINTN Index;\r
66 \r
67 LIST_ENTRY *Entry;\r
68 LIST_ENTRY *Next;\r
69 \r
70 DNS4_SERVER_IP *ServerItem;\r
71 EFI_IPv4_ADDRESS *ServerList;\r
72 DNS4_CACHE *CacheItem;\r
73 EFI_DNS4_CACHE_ENTRY *CacheList;\r
74 EFI_STATUS Status;\r
75\r
76 ServerItem = NULL;\r
77 ServerList = NULL;\r
78 CacheItem = NULL;\r
79 CacheList = NULL;\r
80 Status = EFI_SUCCESS;\r
81 \r
82 \r
83 if ((This == NULL) || (DnsModeData == NULL)) {\r
84 return EFI_INVALID_PARAMETER;\r
85 }\r
86\r
87 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
88 \r
89 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
90 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
91 gBS->RestoreTPL (OldTpl);\r
92 return EFI_NOT_STARTED;\r
93 }\r
94 \r
95 ZeroMem (DnsModeData, sizeof (EFI_DNS4_MODE_DATA));\r
96\r
97 //\r
98 // Get the current configuration data of this instance. \r
99 //\r
100 Status = Dns4CopyConfigure (&DnsModeData->DnsConfigData, &Instance->Dns4CfgData);\r
101 if (EFI_ERROR (Status)) {\r
102 gBS->RestoreTPL (OldTpl);\r
103 return Status;\r
104 }\r
105\r
106 //\r
107 // Get the DnsServerCount and DnsServerList\r
108 //\r
109 Index = 0;\r
110 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4ServerList) {\r
111 Index++;\r
112 }\r
113 DnsModeData->DnsServerCount = (UINT32) Index;\r
114 ServerList = AllocatePool (sizeof (EFI_IPv4_ADDRESS) * DnsModeData->DnsServerCount);\r
115 ASSERT (ServerList != NULL);\r
116 Index = 0;\r
117 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4ServerList) {\r
118 ServerItem = NET_LIST_USER_STRUCT (Entry, DNS4_SERVER_IP, AllServerLink);\r
119 CopyMem (ServerList + Index, &ServerItem->Dns4ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
120 Index++;\r
121 }\r
122 DnsModeData->DnsServerList = ServerList;\r
123\r
124 //\r
125 // Get the DnsCacheCount and DnsCacheList\r
126 //\r
127 Index =0;\r
128 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
129 Index++;\r
130 }\r
131 DnsModeData->DnsCacheCount = (UINT32) Index;\r
132 CacheList = AllocatePool (sizeof (EFI_DNS4_CACHE_ENTRY) * DnsModeData->DnsCacheCount);\r
133 ASSERT (CacheList != NULL);\r
134 Index =0;\r
135 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
136 CacheItem = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
137 CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS4_CACHE_ENTRY));\r
138 Index++;\r
139 }\r
140 DnsModeData->DnsCacheList = CacheList;\r
141\r
142 gBS->RestoreTPL (OldTpl);\r
143 \r
144 return EFI_SUCCESS;\r
145}\r
146\r
147/**\r
0f4e123f
JW
148 Configure this DNS instance.\r
149\r
150 This function is used to configure DNS mode data for this DNS instance.\r
151\r
152 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
153 @param[in] DnsConfigData Point to the Configuration data.\r
154\r
155 @retval EFI_SUCCESS The operation completed successfully.\r
156 @retval EFI_UNSUPPORTED The designated protocol is not supported.\r
157 @retval EFI_INVALID_PARAMTER Thisis NULL.\r
158 The StationIp address provided in DnsConfigData is not a \r
159 valid unicast.\r
160 DnsServerList is NULL while DnsServerListCount\r
161 is not ZERO.\r
162 DnsServerListCount is ZERO while DnsServerList\r
163 is not NULL\r
164 @retval EFI_OUT_OF_RESOURCES The DNS instance data or required space could not be\r
165 allocated.\r
166 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The\r
167 EFI DNSv4 Protocol instance is not configured.\r
168 @retval EFI_ALREADY_STARTED Second call to Configure() with DnsConfigData. To \r
169 reconfigure the instance the caller must call Configure() \r
170 with NULL first to return driver to unconfigured state.\r
99c048ef 171**/\r
172EFI_STATUS\r
173EFIAPI\r
174Dns4Configure (\r
175 IN EFI_DNS4_PROTOCOL *This,\r
176 IN EFI_DNS4_CONFIG_DATA *DnsConfigData\r
177 )\r
178{\r
179 EFI_STATUS Status;\r
180 DNS_INSTANCE *Instance;\r
181 \r
182 EFI_TPL OldTpl;\r
183 IP4_ADDR Ip;\r
184 IP4_ADDR Netmask;\r
185\r
186 UINT32 ServerListCount;\r
187 EFI_IPv4_ADDRESS *ServerList; \r
188\r
189 Status = EFI_SUCCESS;\r
190 ServerList = NULL;\r
191 \r
192 if (This == NULL || \r
193 (DnsConfigData != NULL && ((DnsConfigData->DnsServerListCount != 0 && DnsConfigData->DnsServerList == NULL) || \r
194 (DnsConfigData->DnsServerListCount == 0 && DnsConfigData->DnsServerList != NULL)))) {\r
195 return EFI_INVALID_PARAMETER;\r
196 }\r
197\r
198 if (DnsConfigData != NULL && DnsConfigData->Protocol != DNS_PROTOCOL_UDP) {\r
199 return EFI_UNSUPPORTED;\r
200 }\r
201\r
202 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
203\r
204 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
205\r
206 if (DnsConfigData == NULL) {\r
207 ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));\r
208 \r
209 //\r
210 // Reset the Instance if ConfigData is NULL\r
211 //\r
212 if (!NetMapIsEmpty(&Instance->Dns4TxTokens)) {\r
213 Dns4InstanceCancelToken(Instance, NULL);\r
214 }\r
215\r
216 Instance->MaxRetry = 0;\r
217\r
218 if (Instance->UdpIo != NULL){\r
219 UdpIoCleanIo (Instance->UdpIo);\r
220 }\r
221 \r
222 if (Instance->Dns4CfgData.DnsServerList != NULL) {\r
223 FreePool (Instance->Dns4CfgData.DnsServerList);\r
224 }\r
225 ZeroMem (&Instance->Dns4CfgData, sizeof (EFI_DNS4_CONFIG_DATA));\r
226 \r
227 Instance->State = DNS_STATE_UNCONFIGED;\r
228 } else {\r
229 //\r
230 // Configure the parameters for new operation.\r
231 //\r
232 CopyMem (&Ip, &DnsConfigData->StationIp, sizeof (IP4_ADDR));\r
233 CopyMem (&Netmask, &DnsConfigData->SubnetMask, sizeof (IP4_ADDR));\r
234\r
235 Ip = NTOHL (Ip);\r
236 Netmask = NTOHL (Netmask);\r
237\r
238 if (!DnsConfigData->UseDefaultSetting &&\r
239 ((!IP4_IS_VALID_NETMASK (Netmask) || !NetIp4IsUnicast (Ip, Netmask)))) {\r
240 Status = EFI_INVALID_PARAMETER;\r
241 goto ON_EXIT;\r
242 }\r
243\r
244 Status = Dns4CopyConfigure (&Instance->Dns4CfgData, DnsConfigData);\r
245 if (EFI_ERROR (Status)) {\r
246 goto ON_EXIT;\r
247 }\r
248\r
249 if (DnsConfigData->DnsServerListCount == 0 || DnsConfigData->DnsServerList == NULL) {\r
250 gBS->RestoreTPL (OldTpl); \r
251 \r
252 //\r
253 // The DNS instance will retrieve DNS server from DHCP Server\r
254 //\r
255 Status = GetDns4ServerFromDhcp4 (\r
256 Instance,\r
257 &ServerListCount, \r
258 &ServerList\r
259 );\r
260 if (EFI_ERROR (Status)) {\r
261 return Status;\r
262 }\r
263\r
264 ASSERT(ServerList != NULL);\r
265 \r
266 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
267\r
268 CopyMem (&Instance->SessionDnsServer.v4, &ServerList[0], sizeof (EFI_IPv4_ADDRESS));\r
269 } else {\r
270 CopyMem (&Instance->SessionDnsServer.v4, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv4_ADDRESS));\r
271 }\r
272\r
273 //\r
274 // Config UDP\r
275 //\r
276 Status = Dns4ConfigUdp (Instance, Instance->UdpIo);\r
277 if (EFI_ERROR (Status)) {\r
278 if (Instance->Dns4CfgData.DnsServerList != NULL) {\r
279 FreePool (Instance->Dns4CfgData.DnsServerList);\r
280 }\r
281 goto ON_EXIT;\r
282 }\r
283\r
284 //\r
285 // Add configured DNS server used by this instance to ServerList.\r
286 //\r
287 Status = AddDns4ServerIp (&mDriverData->Dns4ServerList, Instance->SessionDnsServer.v4);\r
288 if (EFI_ERROR (Status)) {\r
289 if (Instance->Dns4CfgData.DnsServerList != NULL) {\r
290 FreePool (Instance->Dns4CfgData.DnsServerList);\r
291 }\r
292 goto ON_EXIT;\r
293 }\r
294 \r
295 Instance->State = DNS_STATE_CONFIGED;\r
296 }\r
297\r
298ON_EXIT:\r
299 gBS->RestoreTPL (OldTpl);\r
300 return Status;\r
301}\r
302\r
303/**\r
0f4e123f
JW
304 Host name to host address translation.\r
305\r
306 The HostNameToIp () function is used to translate the host name to host IP address. A\r
307 type A query is used to get the one or more IP addresses for this host.\r
308\r
309 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
310 @param[in] HostName Host name.\r
311 @param[in] Token Point to the completion token to translate host name\r
312 to host address.\r
313\r
314 @retval EFI_SUCCESS The operation completed successfully.\r
315 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
316 This is NULL.\r
317 Token is NULL.\r
318 Token.Event is NULL.\r
319 HostName is NULL. HostName string is unsupported format.\r
320 @retval EFI_NO_MAPPING There's no source address is available for use.\r
321 @retval EFI_NOT_STARTED This instance has not been started.\r
99c048ef 322**/\r
323EFI_STATUS\r
324EFIAPI\r
325Dns4HostNameToIp (\r
326 IN EFI_DNS4_PROTOCOL *This,\r
327 IN CHAR16 *HostName,\r
328 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
329 )\r
330{\r
331 EFI_STATUS Status;\r
332 \r
333 DNS_INSTANCE *Instance;\r
334 \r
335 EFI_DNS4_CONFIG_DATA *ConfigData;\r
336 \r
337 UINTN Index;\r
338 DNS4_CACHE *Item;\r
339 LIST_ENTRY *Entry;\r
340 LIST_ENTRY *Next;\r
341 \r
fcae1a99
JW
342 CHAR8 *QueryName;\r
343 \r
99c048ef 344 DNS4_TOKEN_ENTRY *TokenEntry;\r
345 NET_BUF *Packet;\r
346 \r
347 EFI_TPL OldTpl;\r
348 \r
349 Status = EFI_SUCCESS;\r
350 Item = NULL;\r
fcae1a99 351 QueryName = NULL;\r
99c048ef 352 TokenEntry = NULL;\r
353 Packet = NULL;\r
354 \r
355 //\r
356 // Validate the parameters\r
357 //\r
358 if ((This == NULL) || (HostName == NULL) || Token == NULL) {\r
359 return EFI_INVALID_PARAMETER;\r
360 }\r
361 \r
362 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
363 \r
364 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
365 \r
366 ConfigData = &(Instance->Dns4CfgData);\r
367 \r
368 Instance->MaxRetry = ConfigData->RetryCount;\r
369 \r
370 Token->Status = EFI_NOT_READY;\r
371 Token->RetryCount = 0;\r
372 Token->RetryInterval = ConfigData->RetryInterval;\r
373\r
374 if (Instance->State != DNS_STATE_CONFIGED) {\r
375 Status = EFI_NOT_STARTED;\r
376 goto ON_EXIT;\r
377 }\r
378\r
379 //\r
380 // Check the MaxRetry and RetryInterval values.\r
381 //\r
382 if (Instance->MaxRetry == 0) {\r
383 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
384 }\r
385\r
386 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
387 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
388 }\r
389\r
390 //\r
391 // Check cache\r
392 //\r
393 if (ConfigData->EnableDnsCache) {\r
394 Index = 0;\r
395 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
396 Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
397 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
398 Index++;\r
399 }\r
400 }\r
401\r
402 if (Index != 0) {\r
403 Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
404 if (Token->RspData.H2AData == NULL) {\r
405 Status = EFI_OUT_OF_RESOURCES;\r
406 goto ON_EXIT;\r
407 }\r
408\r
409 Token->RspData.H2AData->IpCount = (UINT32)Index;\r
410 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv4_ADDRESS) * Index);\r
411 if (Token->RspData.H2AData->IpList == NULL) {\r
412 if (Token->RspData.H2AData != NULL) {\r
413 FreePool (Token->RspData.H2AData);\r
414 }\r
415 \r
416 Status = EFI_OUT_OF_RESOURCES;\r
417 goto ON_EXIT;\r
418 }\r
419\r
420 Index = 0;\r
421 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {\r
422 Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
423 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
424 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS));\r
425 Index++; \r
426 }\r
427 }\r
428 \r
429 Token->Status = EFI_SUCCESS;\r
430 \r
431 if (Token->Event != NULL) {\r
432 gBS->SignalEvent (Token->Event);\r
433 DispatchDpc ();\r
434 }\r
435\r
436 Status = Token->Status;\r
437 goto ON_EXIT;\r
438 } \r
439 }\r
440\r
441 //\r
442 // Construct DNS TokenEntry.\r
443 //\r
444 TokenEntry = AllocateZeroPool (sizeof(DNS4_TOKEN_ENTRY));\r
445 if (TokenEntry == NULL) {\r
446 Status = EFI_OUT_OF_RESOURCES;\r
447 goto ON_EXIT;\r
448 }\r
449 \r
450 TokenEntry->PacketToLive = Token->RetryInterval;\r
451 TokenEntry->QueryHostName = HostName;\r
452 TokenEntry->Token = Token;\r
453\r
fcae1a99
JW
454 //\r
455 // Construct QName.\r
456 //\r
3700da73 457 QueryName = NetLibCreateDnsQName (TokenEntry->QueryHostName);\r
fcae1a99
JW
458 if (QueryName == NULL) {\r
459 Status = EFI_OUT_OF_RESOURCES;\r
460 goto ON_EXIT;\r
461 }\r
462 \r
99c048ef 463 //\r
464 // Construct DNS Query Packet.\r
465 //\r
fcae1a99 466 Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_A, DNS_CLASS_INET, &Packet);\r
99c048ef 467 if (EFI_ERROR (Status)) {\r
468 if (TokenEntry != NULL) {\r
469 FreePool (TokenEntry);\r
470 }\r
471 \r
472 goto ON_EXIT;\r
473 }\r
474\r
8339166d
JW
475 ASSERT (Packet != NULL);\r
476\r
99c048ef 477 //\r
478 // Save the token into the Dns4TxTokens map.\r
479 //\r
480 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);\r
481 if (EFI_ERROR (Status)) {\r
482 if (TokenEntry != NULL) {\r
483 FreePool (TokenEntry);\r
484 }\r
485 \r
486 NetbufFree (Packet);\r
487 \r
488 goto ON_EXIT;\r
489 }\r
490 \r
491 //\r
492 // Dns Query Ip\r
493 //\r
494 Status = DoDnsQuery (Instance, Packet);\r
495 if (EFI_ERROR (Status)) {\r
520a0746
JW
496 Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, TokenEntry);\r
497\r
99c048ef 498 if (TokenEntry != NULL) {\r
499 FreePool (TokenEntry);\r
500 }\r
501 \r
502 NetbufFree (Packet);\r
503 }\r
504 \r
505ON_EXIT:\r
fcae1a99
JW
506 if (QueryName != NULL) {\r
507 FreePool (QueryName);\r
508 }\r
509 \r
99c048ef 510 gBS->RestoreTPL (OldTpl);\r
511 return Status;\r
512}\r
513\r
514/**\r
0f4e123f
JW
515 IPv4 address to host name translation also known as Reverse DNS lookup.\r
516\r
517 The IpToHostName() function is used to translate the host address to host name. A type PTR \r
518 query is used to get the primary name of the host. Support of this function is optional.\r
519\r
520 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
521 @param[in] IpAddress Ip Address.\r
522 @param[in] Token Point to the completion token to translate host\r
523 address to host name.\r
524\r
525 @retval EFI_SUCCESS The operation completed successfully.\r
526 @retval EFI_UNSUPPORTED This function is not supported.\r
527 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
528 This is NULL.\r
529 Token is NULL.\r
530 Token.Event is NULL.\r
531 IpAddress is not valid IP address .\r
532 @retval EFI_NO_MAPPING There's no source address is available for use.\r
533 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
534 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 535**/\r
536EFI_STATUS\r
537EFIAPI\r
538Dns4IpToHostName (\r
539 IN EFI_DNS4_PROTOCOL *This,\r
540 IN EFI_IPv4_ADDRESS IpAddress,\r
541 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
542 )\r
543{\r
544 return EFI_UNSUPPORTED;\r
545}\r
546\r
547/**\r
0f4e123f
JW
548 Retrieve arbitrary information from the DNS server. \r
549\r
550 This GeneralLookup() function retrieves arbitrary information from the DNS. The caller\r
551 supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. All\r
552 RR content (e.g., TTL) was returned. The caller need parse the returned RR to get\r
553 required information. The function is optional.\r
554\r
555 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
556 @param[in] QName Pointer to Query Name.\r
557 @param[in] QType Query Type.\r
558 @param[in] QClass Query Name.\r
559 @param[in] Token Point to the completion token to retrieve arbitrary\r
560 information.\r
561\r
562 @retval EFI_SUCCESS The operation completed successfully.\r
563 @retval EFI_UNSUPPORTED This function is not supported. Or the requested\r
564 QType is not supported\r
565 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
566 This is NULL.\r
567 Token is NULL.\r
568 Token.Event is NULL.\r
569 QName is NULL.\r
570 @retval EFI_NO_MAPPING There's no source address is available for use.\r
571 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
572 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 573**/\r
574EFI_STATUS\r
575EFIAPI\r
576Dns4GeneralLookUp (\r
577 IN EFI_DNS4_PROTOCOL *This,\r
578 IN CHAR8 *QName,\r
579 IN UINT16 QType, \r
580 IN UINT16 QClass,\r
581 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
582 )\r
583{\r
fcae1a99
JW
584 EFI_STATUS Status;\r
585 \r
586 DNS_INSTANCE *Instance;\r
587 \r
588 EFI_DNS4_CONFIG_DATA *ConfigData;\r
589 \r
590 DNS4_TOKEN_ENTRY *TokenEntry;\r
591 NET_BUF *Packet;\r
592 \r
593 EFI_TPL OldTpl;\r
594 \r
595 Status = EFI_SUCCESS;\r
596 TokenEntry = NULL;\r
597 Packet = NULL;\r
598 \r
599 //\r
600 // Validate the parameters\r
601 //\r
602 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
603 return EFI_INVALID_PARAMETER;\r
604 }\r
605 \r
606 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
607 \r
608 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
609 \r
610 ConfigData = &(Instance->Dns4CfgData);\r
611 \r
612 Instance->MaxRetry = ConfigData->RetryCount;\r
613 \r
614 Token->Status = EFI_NOT_READY;\r
615 Token->RetryCount = 0;\r
616 Token->RetryInterval = ConfigData->RetryInterval;\r
617\r
618 if (Instance->State != DNS_STATE_CONFIGED) {\r
619 Status = EFI_NOT_STARTED;\r
620 goto ON_EXIT;\r
621 }\r
622\r
623 //\r
624 // Check the MaxRetry and RetryInterval values.\r
625 //\r
626 if (Instance->MaxRetry == 0) {\r
627 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
628 }\r
629\r
630 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
631 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
632 }\r
633\r
634 //\r
635 // Construct DNS TokenEntry.\r
636 //\r
637 TokenEntry = AllocateZeroPool (sizeof(DNS4_TOKEN_ENTRY));\r
638 if (TokenEntry == NULL) {\r
639 Status = EFI_OUT_OF_RESOURCES;\r
640 goto ON_EXIT;\r
641 }\r
642 \r
643 TokenEntry->PacketToLive = Token->RetryInterval;\r
644 TokenEntry->GeneralLookUp = TRUE;\r
645 TokenEntry->Token = Token;\r
646\r
647 //\r
648 // Construct DNS Query Packet.\r
649 //\r
650 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
651 if (EFI_ERROR (Status)) {\r
652 if (TokenEntry != NULL) {\r
653 FreePool (TokenEntry);\r
654 }\r
655 \r
656 goto ON_EXIT;\r
657 }\r
658\r
8339166d
JW
659 ASSERT (Packet != NULL);\r
660\r
fcae1a99
JW
661 //\r
662 // Save the token into the Dns4TxTokens map.\r
663 //\r
664 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);\r
665 if (EFI_ERROR (Status)) {\r
666 if (TokenEntry != NULL) {\r
667 FreePool (TokenEntry);\r
668 }\r
669 \r
670 NetbufFree (Packet);\r
671 \r
672 goto ON_EXIT;\r
673 }\r
674 \r
675 //\r
676 // Dns Query Ip\r
677 //\r
678 Status = DoDnsQuery (Instance, Packet);\r
679 if (EFI_ERROR (Status)) {\r
520a0746
JW
680 Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, TokenEntry);\r
681\r
fcae1a99
JW
682 if (TokenEntry != NULL) {\r
683 FreePool (TokenEntry);\r
684 }\r
685 \r
686 NetbufFree (Packet);\r
687 }\r
688 \r
689ON_EXIT:\r
690 gBS->RestoreTPL (OldTpl);\r
691 return Status;\r
99c048ef 692}\r
693\r
694/**\r
0f4e123f
JW
695 This function is to update the DNS Cache.\r
696\r
697 The UpdateDnsCache() function is used to add/delete/modify DNS cache entry. DNS cache\r
698 can be normally dynamically updated after the DNS resolve succeeds. This function\r
699 provided capability to manually add/delete/modify the DNS cache.\r
700\r
701 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
702 @param[in] DeleteFlag If FALSE, this function is to add one entry to the\r
703 DNS Cahce. If TRUE, this function will delete\r
704 matching DNS Cache entry.\r
705 @param[in] Override If TRUE, the maching DNS cache entry will be\r
706 overwritten with the supplied parameter. If FALSE,\r
707 EFI_ACCESS_DENIED will be returned if the entry to\r
708 be added is already existed.\r
709 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
710\r
711 @retval EFI_SUCCESS The operation completed successfully.\r
712 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
713 This is NULL.\r
714 DnsCacheEntry.HostName is NULL.\r
715 DnsCacheEntry.IpAddress is NULL.\r
716 DnsCacheEntry.Timeout is zero.\r
717 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is\r
718 not TRUE.\r
99c048ef 719**/\r
720EFI_STATUS\r
721EFIAPI\r
722Dns4UpdateDnsCache (\r
723 IN EFI_DNS4_PROTOCOL *This,\r
724 IN BOOLEAN DeleteFlag,\r
725 IN BOOLEAN Override,\r
726 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry\r
727 )\r
728{\r
729 EFI_STATUS Status; \r
730 EFI_TPL OldTpl;\r
731\r
732 Status = EFI_SUCCESS;\r
733 \r
734 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
735 return EFI_INVALID_PARAMETER; \r
736 }\r
737 \r
738 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
739\r
740 //\r
741 // Update Dns4Cache here.\r
742 //\r
743 Status = UpdateDns4Cache (&mDriverData->Dns4CacheList, DeleteFlag, Override, DnsCacheEntry);\r
744\r
745 gBS->RestoreTPL (OldTpl);\r
746 \r
747 return Status;\r
748}\r
749\r
750/**\r
0f4e123f
JW
751 Polls for incoming data packets and processes outgoing data packets.\r
752\r
753 The Poll() function can be used by network drivers and applications to increase the\r
754 rate that data packets are moved between the communications device and the transmit\r
755 and receive queues.\r
756 In some systems, the periodic timer event in the managed network driver may not poll\r
757 the underlying communications device fast enough to transmit and/or receive all data\r
758 packets without missing incoming packets or dropping outgoing packets. Drivers and\r
759 applications that are experiencing packet loss should try calling the Poll()\r
760 function more often.\r
761\r
762 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
763\r
764 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
765 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.\r
766 @retval EFI_INVALID_PARAMETER This is NULL.\r
767 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
768 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive\r
769 queue. Consider increasing the polling rate.\r
99c048ef 770**/\r
771EFI_STATUS\r
772EFIAPI\r
773Dns4Poll (\r
774 IN EFI_DNS4_PROTOCOL *This\r
775 )\r
776{\r
777 DNS_INSTANCE *Instance;\r
778 EFI_UDP4_PROTOCOL *Udp;\r
779\r
780 if (This == NULL) {\r
781 return EFI_INVALID_PARAMETER;\r
782 }\r
783\r
784 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
785\r
786 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
787 return EFI_NOT_STARTED;\r
788 } else if (Instance->State == DNS_STATE_DESTROY) {\r
789 return EFI_DEVICE_ERROR;\r
790 }\r
791\r
792 Udp = Instance->UdpIo->Protocol.Udp4;\r
793 \r
794 return Udp->Poll (Udp);\r
795}\r
796\r
797/**\r
0f4e123f
JW
798 Abort an asynchronous DNS operation, including translation between IP and Host, and\r
799 general look up behavior.\r
800\r
801 The Cancel() function is used to abort a pending resolution request. After calling\r
802 this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be\r
803 signaled. If the token is not in one of the queues, which usually means that the\r
804 asynchronous operation has completed, this function will not signal the token and\r
805 EFI_NOT_FOUND is returned.\r
806\r
807 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
808 @param[in] Token Pointer to a token that has been issued by\r
809 EFI_DNS4_PROTOCOL.HostNameToIp (),\r
810 EFI_DNS4_PROTOCOL.IpToHostName() or\r
811 EFI_DNS4_PROTOCOL.GeneralLookup().\r
812 If NULL, all pending tokens are aborted.\r
813\r
814 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
815 @retval EFI_NOT_STARTED This EFI DNS4 Protocol instance has not been started.\r
816 @retval EFI_INVALID_PARAMETER This is NULL.\r
817 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS\r
818 operation was not found in the transmit queue. It\r
819 was either completed or was not issued by\r
820 HostNameToIp(), IpToHostName() or GeneralLookup().\r
99c048ef 821**/\r
822EFI_STATUS\r
823EFIAPI\r
824Dns4Cancel (\r
825 IN EFI_DNS4_PROTOCOL *This,\r
826 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
827 )\r
828{\r
829 EFI_STATUS Status;\r
830 DNS_INSTANCE *Instance;\r
831 EFI_TPL OldTpl;\r
832\r
833 if (This == NULL) {\r
834 return EFI_INVALID_PARAMETER;\r
835 }\r
836\r
837 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
838\r
839 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
840 return EFI_NOT_STARTED;\r
841 }\r
842\r
843 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
844\r
845 //\r
846 // Cancle the tokens specified by Token for this instance.\r
847 //\r
848 Status = Dns4InstanceCancelToken (Instance, Token);\r
849\r
850 //\r
851 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
852 //\r
853 DispatchDpc ();\r
854\r
855 gBS->RestoreTPL (OldTpl);\r
856\r
857 return Status;\r
858}\r
859\r
860/**\r
0f4e123f 861 Retrieve mode data of this DNS instance.\r
99c048ef 862\r
0f4e123f 863 This function is used to retrieve DNS mode data for this DNS instance.\r
99c048ef 864\r
0f4e123f
JW
865 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
866 @param[out] DnsModeData Pointer to the caller-allocated storage for the \r
867 EFI_DNS6_MODE_DATA data.\r
99c048ef 868\r
0f4e123f
JW
869 @retval EFI_SUCCESS The operation completed successfully.\r
870 @retval EFI_NOT_STARTED When DnsConfigData is queried, no configuration data\r
871 is available because this instance has not been\r
872 configured.\r
873 @retval EFI_INVALID_PARAMETER This is NULL or DnsModeData is NULL.\r
874 @retval EFI_OUT_OF_RESOURCE Failed to allocate needed resources.\r
99c048ef 875**/\r
876EFI_STATUS\r
877EFIAPI\r
878Dns6GetModeData (\r
879 IN EFI_DNS6_PROTOCOL *This,\r
880 OUT EFI_DNS6_MODE_DATA *DnsModeData\r
881 )\r
882{\r
883 DNS_INSTANCE *Instance;\r
884 \r
885 EFI_TPL OldTpl;\r
886\r
887 UINTN Index;\r
888 \r
889 LIST_ENTRY *Entry;\r
890 LIST_ENTRY *Next;\r
891\r
892 DNS6_SERVER_IP *ServerItem;\r
893 EFI_IPv6_ADDRESS *ServerList;\r
894 DNS6_CACHE *CacheItem;\r
895 EFI_DNS6_CACHE_ENTRY *CacheList;\r
896 EFI_STATUS Status;\r
897\r
898 ServerItem = NULL;\r
899 ServerList = NULL;\r
900 CacheItem = NULL;\r
901 CacheList = NULL;\r
902 Status = EFI_SUCCESS;\r
903\r
904 if ((This == NULL) || (DnsModeData == NULL)) {\r
905 return EFI_INVALID_PARAMETER;\r
906 }\r
907\r
908 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
909 \r
910 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
911 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
912 gBS->RestoreTPL (OldTpl);\r
913 return EFI_NOT_STARTED;\r
914 }\r
915\r
916 ZeroMem (DnsModeData, sizeof (EFI_DNS6_MODE_DATA));\r
917\r
918 //\r
919 // Get the current configuration data of this instance. \r
920 //\r
921 Status = Dns6CopyConfigure(&DnsModeData->DnsConfigData, &Instance->Dns6CfgData);\r
922 if (EFI_ERROR (Status)) {\r
923 gBS->RestoreTPL (OldTpl);\r
924 return Status;\r
925 }\r
926 \r
927 //\r
928 // Get the DnsServerCount and DnsServerList\r
929 //\r
930 Index = 0;\r
931 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
932 Index++;\r
933 }\r
934 DnsModeData->DnsServerCount = (UINT32) Index;\r
935 ServerList = AllocatePool (sizeof(EFI_IPv6_ADDRESS) * DnsModeData->DnsServerCount);\r
936 ASSERT (ServerList != NULL);\r
937 Index = 0;\r
938 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
939 ServerItem = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);\r
940 CopyMem (ServerList + Index, &ServerItem->Dns6ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
941 Index++;\r
942 }\r
943 DnsModeData->DnsServerList = ServerList;\r
944\r
945 //\r
946 // Get the DnsCacheCount and DnsCacheList\r
947 //\r
948 Index =0;\r
949 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
950 Index++;\r
951 }\r
952 DnsModeData->DnsCacheCount = (UINT32) Index;\r
953 CacheList = AllocatePool (sizeof(EFI_DNS6_CACHE_ENTRY) * DnsModeData->DnsCacheCount);\r
954 ASSERT (CacheList != NULL);\r
955 Index =0;\r
956 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
957 CacheItem = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
958 CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS6_CACHE_ENTRY));\r
959 Index++;\r
960 }\r
961 DnsModeData->DnsCacheList = CacheList;\r
962\r
963 gBS->RestoreTPL (OldTpl);\r
964 \r
965 return EFI_SUCCESS;\r
966}\r
967\r
968/**\r
0f4e123f
JW
969 Configure this DNS instance.\r
970\r
971 The Configure() function is used to set and change the configuration data for this\r
972 EFI DNSv6 Protocol driver instance. Reset the DNS instance if DnsConfigData is NULL.\r
973\r
974 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
975 @param[in] DnsConfigData Pointer to the configuration data structure. All associated \r
976 storage to be allocated and released by caller.\r
977\r
978 @retval EFI_SUCCESS The operation completed successfully.\r
979 @retval EFI_INVALID_PARAMTER This is NULL.\r
980 The StationIp address provided in DnsConfigData is not zero and not a valid unicast.\r
981 DnsServerList is NULL while DnsServerList Count is not ZERO.\r
982 DnsServerList Count is ZERO while DnsServerList is not NULL.\r
983 @retval EFI_OUT_OF_RESOURCES The DNS instance data or required space could not be allocated.\r
984 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The\r
985 EFI DNSv6 Protocol instance is not configured.\r
986 @retval EFI_UNSUPPORTED The designated protocol is not supported.\r
987 @retval EFI_ALREADY_STARTED Second call to Configure() with DnsConfigData. To \r
988 reconfigure the instance the caller must call Configure() with \r
989 NULL first to return driver to unconfigured state.\r
99c048ef 990**/\r
991EFI_STATUS\r
992EFIAPI\r
993Dns6Configure (\r
994 IN EFI_DNS6_PROTOCOL *This,\r
995 IN EFI_DNS6_CONFIG_DATA *DnsConfigData\r
996 )\r
997{\r
998 EFI_STATUS Status;\r
999 DNS_INSTANCE *Instance;\r
1000 \r
1001 EFI_TPL OldTpl;\r
1002\r
1003 UINT32 ServerListCount;\r
1004 EFI_IPv6_ADDRESS *ServerList; \r
1005\r
1006 Status = EFI_SUCCESS;\r
1007 ServerList = NULL;\r
1008\r
1009 if (This == NULL || \r
1010 (DnsConfigData != NULL && ((DnsConfigData->DnsServerCount != 0 && DnsConfigData->DnsServerList == NULL) || \r
1011 (DnsConfigData->DnsServerCount == 0 && DnsConfigData->DnsServerList != NULL)))) {\r
1012 return EFI_INVALID_PARAMETER;\r
1013 }\r
1014\r
1015 if (DnsConfigData != NULL && DnsConfigData->Protocol != DNS_PROTOCOL_UDP) {\r
1016 return EFI_UNSUPPORTED;\r
1017 }\r
1018\r
1019 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1020\r
1021 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1022\r
1023 if (DnsConfigData == NULL) {\r
1024 ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));\r
1025\r
1026 //\r
1027 // Reset the Instance if ConfigData is NULL\r
1028 //\r
1029 if (!NetMapIsEmpty(&Instance->Dns6TxTokens)) {\r
1030 Dns6InstanceCancelToken(Instance, NULL);\r
1031 }\r
1032\r
1033 Instance->MaxRetry = 0;\r
1034\r
1035 if (Instance->UdpIo != NULL){\r
1036 UdpIoCleanIo (Instance->UdpIo);\r
1037 }\r
1038\r
1039 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1040 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1041 }\r
1042 ZeroMem (&Instance->Dns6CfgData, sizeof (EFI_DNS6_CONFIG_DATA));\r
1043 \r
1044 Instance->State = DNS_STATE_UNCONFIGED;\r
1045 } else {\r
1046 //\r
1047 // Configure the parameters for new operation.\r
1048 //\r
90ae1f02 1049 if (!NetIp6IsUnspecifiedAddr (&DnsConfigData->StationIp) && !NetIp6IsValidUnicast (&DnsConfigData->StationIp)) {\r
99c048ef 1050 Status = EFI_INVALID_PARAMETER;\r
1051 goto ON_EXIT;\r
1052 }\r
1053\r
1054 Status = Dns6CopyConfigure (&Instance->Dns6CfgData, DnsConfigData);\r
1055 if (EFI_ERROR (Status)) {\r
1056 goto ON_EXIT;\r
1057 }\r
1058\r
1059 if (DnsConfigData->DnsServerCount == 0 || DnsConfigData->DnsServerList == NULL) {\r
1060 gBS->RestoreTPL (OldTpl);\r
1061\r
1062 //\r
1063 //The DNS instance will retrieve DNS server from DHCP Server.\r
1064 //\r
1065 Status = GetDns6ServerFromDhcp6 (\r
1066 Instance->Service->ImageHandle,\r
1067 Instance->Service->ControllerHandle, \r
1068 &ServerListCount, \r
1069 &ServerList\r
1070 );\r
1071 if (EFI_ERROR (Status)) {\r
1072 goto ON_EXIT;\r
1073 }\r
1074 \r
1075 ASSERT(ServerList != NULL);\r
1076\r
1077 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1078\r
1079 CopyMem (&Instance->SessionDnsServer.v6, &ServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1080 } else {\r
1081 CopyMem (&Instance->SessionDnsServer.v6, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1082 }\r
1083\r
1084 //\r
1085 // Config UDP\r
1086 //\r
1087 Status = Dns6ConfigUdp (Instance, Instance->UdpIo);\r
1088 if (EFI_ERROR (Status)) {\r
1089 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1090 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1091 }\r
1092 goto ON_EXIT;\r
1093 }\r
1094\r
1095 //\r
1096 // Add configured DNS server used by this instance to ServerList.\r
1097 //\r
1098 Status = AddDns6ServerIp (&mDriverData->Dns6ServerList, Instance->SessionDnsServer.v6);\r
1099 if (EFI_ERROR (Status)) {\r
1100 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1101 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1102 }\r
1103 goto ON_EXIT;\r
1104 }\r
1105 \r
1106 Instance->State = DNS_STATE_CONFIGED;\r
1107 }\r
1108\r
1109ON_EXIT:\r
1110 gBS->RestoreTPL (OldTpl);\r
1111 return Status;\r
1112}\r
1113\r
1114/**\r
0f4e123f
JW
1115 Host name to host address translation.\r
1116\r
1117 The HostNameToIp () function is used to translate the host name to host IP address. A\r
1118 type AAAA query is used to get the one or more IPv6 addresses for this host.\r
1119\r
1120 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1121 @param[in] HostName Host name.\r
1122 @param[in] Token Point to the completion token to translate host name\r
1123 to host address.\r
1124\r
1125 @retval EFI_SUCCESS The operation completed successfully.\r
1126 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1127 This is NULL.\r
1128 Token is NULL.\r
1129 Token.Event is NULL.\r
1130 HostName is NULL or buffer contained unsupported characters.\r
1131 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1132 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
1133 @retval EFI_NOT_STARTED This instance has not been started.\r
1134 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 1135**/\r
1136EFI_STATUS\r
1137EFIAPI\r
1138Dns6HostNameToIp (\r
1139 IN EFI_DNS6_PROTOCOL *This,\r
1140 IN CHAR16 *HostName,\r
1141 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1142 )\r
1143{\r
1144 EFI_STATUS Status;\r
1145 \r
1146 DNS_INSTANCE *Instance;\r
1147\r
1148 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1149 \r
1150 UINTN Index; \r
1151 DNS6_CACHE *Item;\r
1152 LIST_ENTRY *Entry;\r
1153 LIST_ENTRY *Next;\r
1154 \r
fcae1a99
JW
1155 CHAR8 *QueryName;\r
1156 \r
99c048ef 1157 DNS6_TOKEN_ENTRY *TokenEntry;\r
1158 NET_BUF *Packet;\r
1159 \r
1160 EFI_TPL OldTpl;\r
1161 \r
1162 Status = EFI_SUCCESS;\r
1163 Item = NULL;\r
fcae1a99 1164 QueryName = NULL;\r
99c048ef 1165 TokenEntry = NULL;\r
1166 Packet = NULL;\r
1167\r
1168 //\r
1169 // Validate the parameters\r
1170 //\r
1171 if ((This == NULL) || (HostName == NULL) || Token == NULL) {\r
1172 return EFI_INVALID_PARAMETER;\r
1173 }\r
1174\r
1175 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1176 \r
1177 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1178 \r
1179 ConfigData = &(Instance->Dns6CfgData);\r
1180 \r
1181 Instance->MaxRetry = ConfigData->RetryCount;\r
1182\r
1183 Token->Status = EFI_NOT_READY;\r
1184 Token->RetryCount = 0;\r
1185 Token->RetryInterval = ConfigData->RetryInterval;\r
1186\r
1187 if (Instance->State != DNS_STATE_CONFIGED) {\r
1188 Status = EFI_NOT_STARTED;\r
1189 goto ON_EXIT;\r
1190 }\r
1191\r
1192 //\r
1193 // Check the MaxRetry and RetryInterval values.\r
1194 //\r
1195 if (Instance->MaxRetry == 0) {\r
1196 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1197 }\r
1198\r
1199 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1200 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1201 } \r
1202\r
1203 //\r
1204 // Check cache\r
1205 //\r
1206 if (ConfigData->EnableDnsCache) {\r
1207 Index = 0;\r
1208 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1209 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1210 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1211 Index++;\r
1212 }\r
1213 }\r
1214\r
1215 if (Index != 0) {\r
1216 Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
1217 if (Token->RspData.H2AData == NULL) {\r
1218 Status = EFI_OUT_OF_RESOURCES;\r
1219 goto ON_EXIT;\r
1220 }\r
1221\r
1222 Token->RspData.H2AData->IpCount = (UINT32)Index;\r
1223 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv6_ADDRESS) * Index);\r
1224 if (Token->RspData.H2AData->IpList == NULL) {\r
1225 if (Token->RspData.H2AData != NULL) {\r
1226 FreePool (Token->RspData.H2AData);\r
1227 }\r
1228 \r
1229 Status = EFI_OUT_OF_RESOURCES;\r
1230 goto ON_EXIT;\r
1231 }\r
1232\r
1233 Index = 0;\r
1234 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1235 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1236 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1237 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
1238 Index++;\r
1239 }\r
1240 }\r
1241 \r
1242 Token->Status = EFI_SUCCESS;\r
1243 \r
1244 if (Token->Event != NULL) {\r
1245 gBS->SignalEvent (Token->Event);\r
1246 DispatchDpc ();\r
1247 }\r
1248 \r
1249 Status = Token->Status;\r
1250 goto ON_EXIT;\r
1251 } \r
1252 }\r
1253\r
1254 //\r
1255 // Construct DNS TokenEntry.\r
1256 //\r
1257 TokenEntry = AllocateZeroPool (sizeof (DNS6_TOKEN_ENTRY));\r
1258 if (TokenEntry == NULL) {\r
1259 Status = EFI_OUT_OF_RESOURCES;\r
1260 goto ON_EXIT;\r
1261 }\r
1262 \r
1263 TokenEntry->PacketToLive = Token->RetryInterval;\r
1264 TokenEntry->QueryHostName = HostName;\r
1265 TokenEntry->Token = Token;\r
1266\r
fcae1a99
JW
1267\r
1268 //\r
1269 // Construct QName.\r
1270 //\r
3700da73 1271 QueryName = NetLibCreateDnsQName (TokenEntry->QueryHostName);\r
fcae1a99
JW
1272 if (QueryName == NULL) {\r
1273 Status = EFI_OUT_OF_RESOURCES;\r
1274 goto ON_EXIT;\r
1275 }\r
1276 \r
99c048ef 1277 //\r
1278 // Construct DNS Query Packet.\r
1279 //\r
fcae1a99 1280 Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_AAAA, DNS_CLASS_INET, &Packet);\r
99c048ef 1281 if (EFI_ERROR (Status)) {\r
1282 if (TokenEntry != NULL) {\r
1283 FreePool (TokenEntry);\r
1284 }\r
1285 \r
1286 goto ON_EXIT;\r
1287 }\r
1288\r
8339166d
JW
1289 ASSERT (Packet != NULL);\r
1290\r
99c048ef 1291 //\r
1292 // Save the token into the Dns6TxTokens map.\r
1293 //\r
1294 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1295 if (EFI_ERROR (Status)) {\r
1296 if (TokenEntry != NULL) {\r
1297 FreePool (TokenEntry);\r
1298 }\r
1299 \r
1300 NetbufFree (Packet);\r
1301 \r
1302 goto ON_EXIT;\r
1303 }\r
1304 \r
1305 //\r
1306 // Dns Query Ip\r
1307 //\r
1308 Status = DoDnsQuery (Instance, Packet);\r
1309 if (EFI_ERROR (Status)) {\r
520a0746
JW
1310 Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, TokenEntry);\r
1311 \r
99c048ef 1312 if (TokenEntry != NULL) {\r
1313 FreePool (TokenEntry);\r
1314 }\r
1315 \r
1316 NetbufFree (Packet);\r
1317 }\r
1318 \r
1319ON_EXIT:\r
fcae1a99
JW
1320 if (QueryName != NULL) {\r
1321 FreePool (QueryName);\r
1322 }\r
1323 \r
99c048ef 1324 gBS->RestoreTPL (OldTpl);\r
1325 return Status;\r
1326}\r
1327\r
1328/**\r
0f4e123f
JW
1329 Host address to host name translation.\r
1330\r
1331 The IpToHostName () function is used to translate the host address to host name. A\r
1332 type PTR query is used to get the primary name of the host. Implementation can choose\r
1333 to support this function or not.\r
1334\r
1335 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1336 @param[in] IpAddress Ip Address.\r
1337 @param[in] Token Point to the completion token to translate host\r
1338 address to host name.\r
1339\r
1340 @retval EFI_SUCCESS The operation completed successfully.\r
1341 @retval EFI_UNSUPPORTED This function is not supported.\r
1342 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1343 This is NULL.\r
1344 Token is NULL.\r
1345 Token.Event is NULL.\r
1346 IpAddress is not valid IP address.\r
1347 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1348 @retval EFI_NOT_STARTED This instance has not been started.\r
1349 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 1350**/\r
1351EFI_STATUS\r
1352EFIAPI\r
1353Dns6IpToHostName (\r
1354 IN EFI_DNS6_PROTOCOL *This,\r
1355 IN EFI_IPv6_ADDRESS IpAddress,\r
1356 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1357 )\r
1358{\r
1359 return EFI_UNSUPPORTED;\r
1360}\r
1361\r
1362/**\r
0f4e123f
JW
1363 This function provides capability to retrieve arbitrary information from the DNS\r
1364 server.\r
1365\r
1366 This GeneralLookup() function retrieves arbitrary information from the DNS. The caller\r
1367 supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. All\r
1368 RR content (e.g., TTL) was returned. The caller need parse the returned RR to get\r
1369 required information. The function is optional. Implementation can choose to support\r
1370 it or not.\r
1371\r
1372 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1373 @param[in] QName Pointer to Query Name.\r
1374 @param[in] QType Query Type.\r
1375 @param[in] QClass Query Name.\r
1376 @param[in] Token Point to the completion token to retrieve arbitrary\r
1377 information.\r
1378\r
1379 @retval EFI_SUCCESS The operation completed successfully.\r
1380 @retval EFI_UNSUPPORTED This function is not supported. Or the requested\r
1381 QType is not supported\r
1382 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1383 This is NULL.\r
1384 Token is NULL.\r
1385 Token.Event is NULL.\r
1386 QName is NULL.\r
1387 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1388 @retval EFI_NOT_STARTED This instance has not been started.\r
1389 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 1390**/\r
1391EFI_STATUS\r
1392EFIAPI\r
1393Dns6GeneralLookUp (\r
1394 IN EFI_DNS6_PROTOCOL *This,\r
1395 IN CHAR8 *QName,\r
1396 IN UINT16 QType, \r
1397 IN UINT16 QClass,\r
1398 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1399 )\r
1400{\r
fcae1a99
JW
1401 EFI_STATUS Status;\r
1402 \r
1403 DNS_INSTANCE *Instance;\r
1404 \r
1405 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1406 \r
1407 DNS6_TOKEN_ENTRY *TokenEntry;\r
1408 NET_BUF *Packet;\r
1409 \r
1410 EFI_TPL OldTpl;\r
1411 \r
1412 Status = EFI_SUCCESS;\r
1413 TokenEntry = NULL;\r
1414 Packet = NULL;\r
1415 \r
1416 //\r
1417 // Validate the parameters\r
1418 //\r
1419 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
1420 return EFI_INVALID_PARAMETER;\r
1421 }\r
1422 \r
1423 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1424 \r
1425 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1426 \r
1427 ConfigData = &(Instance->Dns6CfgData);\r
1428 \r
1429 Instance->MaxRetry = ConfigData->RetryCount;\r
1430 \r
1431 Token->Status = EFI_NOT_READY;\r
1432 Token->RetryCount = 0;\r
1433 Token->RetryInterval = ConfigData->RetryInterval;\r
1434\r
1435 if (Instance->State != DNS_STATE_CONFIGED) {\r
1436 Status = EFI_NOT_STARTED;\r
1437 goto ON_EXIT;\r
1438 }\r
1439\r
1440 //\r
1441 // Check the MaxRetry and RetryInterval values.\r
1442 //\r
1443 if (Instance->MaxRetry == 0) {\r
1444 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1445 }\r
1446\r
1447 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1448 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1449 }\r
1450\r
1451 //\r
1452 // Construct DNS TokenEntry.\r
1453 //\r
1454 TokenEntry = AllocateZeroPool (sizeof(DNS6_TOKEN_ENTRY));\r
1455 if (TokenEntry == NULL) {\r
1456 Status = EFI_OUT_OF_RESOURCES;\r
1457 goto ON_EXIT;\r
1458 }\r
1459 \r
1460 TokenEntry->PacketToLive = Token->RetryInterval;\r
1461 TokenEntry->GeneralLookUp = TRUE;\r
1462 TokenEntry->Token = Token;\r
1463\r
1464 //\r
1465 // Construct DNS Query Packet.\r
1466 //\r
1467 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
1468 if (EFI_ERROR (Status)) {\r
1469 if (TokenEntry != NULL) {\r
1470 FreePool (TokenEntry);\r
1471 }\r
1472 \r
1473 goto ON_EXIT;\r
1474 }\r
1475\r
8339166d
JW
1476 ASSERT (Packet != NULL);\r
1477\r
fcae1a99
JW
1478 //\r
1479 // Save the token into the Dns6TxTokens map.\r
1480 //\r
1481 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1482 if (EFI_ERROR (Status)) {\r
1483 if (TokenEntry != NULL) {\r
1484 FreePool (TokenEntry);\r
1485 }\r
1486 \r
1487 NetbufFree (Packet);\r
1488 \r
1489 goto ON_EXIT;\r
1490 }\r
1491 \r
1492 //\r
1493 // Dns Query Ip\r
1494 //\r
1495 Status = DoDnsQuery (Instance, Packet);\r
1496 if (EFI_ERROR (Status)) {\r
520a0746
JW
1497 Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, TokenEntry);\r
1498\r
fcae1a99
JW
1499 if (TokenEntry != NULL) {\r
1500 FreePool (TokenEntry);\r
1501 }\r
1502 \r
1503 NetbufFree (Packet);\r
1504 }\r
1505 \r
1506ON_EXIT:\r
1507 gBS->RestoreTPL (OldTpl);\r
1508 return Status;\r
99c048ef 1509}\r
1510\r
1511/**\r
0f4e123f
JW
1512 This function is to update the DNS Cache.\r
1513\r
1514 The UpdateDnsCache() function is used to add/delete/modify DNS cache entry. DNS cache\r
1515 can be normally dynamically updated after the DNS resolve succeeds. This function\r
1516 provided capability to manually add/delete/modify the DNS cache.\r
1517\r
1518 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1519 @param[in] DeleteFlag If FALSE, this function is to add one entry to the\r
1520 DNS Cahce. If TRUE, this function will delete\r
1521 matching DNS Cache entry.\r
1522 @param[in] Override If TRUE, the maching DNS cache entry will be\r
1523 overwritten with the supplied parameter. If FALSE,\r
1524 EFI_ACCESS_DENIED will be returned if the entry to\r
1525 be added is already existed.\r
1526 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
1527\r
1528 @retval EFI_SUCCESS The operation completed successfully.\r
1529 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1530 This is NULL.\r
1531 DnsCacheEntry.HostName is NULL.\r
1532 DnsCacheEntry.IpAddress is NULL.\r
1533 DnsCacheEntry.Timeout is zero.\r
1534 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is\r
1535 not TRUE.\r
1536 @retval EFI_OUT_OF_RESOURCE Failed to allocate needed resources.\r
99c048ef 1537**/\r
1538EFI_STATUS\r
1539EFIAPI\r
1540Dns6UpdateDnsCache (\r
1541 IN EFI_DNS6_PROTOCOL *This,\r
1542 IN BOOLEAN DeleteFlag,\r
1543 IN BOOLEAN Override,\r
1544 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry\r
1545 )\r
1546{\r
1547 EFI_STATUS Status; \r
1548 EFI_TPL OldTpl;\r
1549\r
1550 Status = EFI_SUCCESS;\r
1551 \r
1552 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
1553 return EFI_INVALID_PARAMETER; \r
1554 }\r
1555 \r
1556 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1557\r
1558 //\r
1559 // Update Dns6Cache here.\r
1560 //\r
1561 Status = UpdateDns6Cache (&mDriverData->Dns6CacheList, DeleteFlag, Override, DnsCacheEntry);\r
1562 \r
1563 gBS->RestoreTPL (OldTpl);\r
1564 \r
1565 return Status;\r
1566}\r
1567\r
1568/**\r
0f4e123f
JW
1569 Polls for incoming data packets and processes outgoing data packets.\r
1570\r
1571 The Poll() function can be used by network drivers and applications to increase the\r
1572 rate that data packets are moved between the communications device and the transmit\r
1573 and receive queues.\r
1574\r
1575 In some systems, the periodic timer event in the managed network driver may not poll\r
1576 the underlying communications device fast enough to transmit and/or receive all data\r
1577 packets without missing incoming packets or dropping outgoing packets. Drivers and\r
1578 applications that are experiencing packet loss should try calling the Poll()\r
1579 function more often.\r
1580\r
1581 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1582\r
1583 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1584 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.\r
1585 @retval EFI_INVALID_PARAMETER This is NULL.\r
1586 @retval EFI_NO_MAPPING There is no source address is available for use.\r
1587 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1588 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive\r
1589 queue. Consider increasing the polling rate.\r
99c048ef 1590**/\r
1591EFI_STATUS\r
1592EFIAPI\r
1593Dns6Poll (\r
1594 IN EFI_DNS6_PROTOCOL *This\r
1595 )\r
1596{\r
1597 DNS_INSTANCE *Instance;\r
1598 EFI_UDP6_PROTOCOL *Udp;\r
1599\r
1600 if (This == NULL) {\r
1601 return EFI_INVALID_PARAMETER;\r
1602 }\r
1603\r
1604 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1605\r
1606 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1607 return EFI_NOT_STARTED;\r
1608 } else if (Instance->State == DNS_STATE_DESTROY) {\r
1609 return EFI_DEVICE_ERROR;\r
1610 }\r
1611\r
1612 Udp = Instance->UdpIo->Protocol.Udp6;\r
1613 \r
1614 return Udp->Poll (Udp);\r
1615}\r
1616\r
1617/**\r
0f4e123f
JW
1618 Abort an asynchronous DNS operation, including translation between IP and Host, and\r
1619 general look up behavior.\r
1620\r
1621 The Cancel() function is used to abort a pending resolution request. After calling\r
1622 this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be\r
1623 signaled. If the token is not in one of the queues, which usually means that the\r
1624 asynchronous operation has completed, this function will not signal the token and\r
1625 EFI_NOT_FOUND is returned.\r
1626\r
1627 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1628 @param[in] Token Pointer to a token that has been issued by\r
1629 EFI_DNS6_PROTOCOL.HostNameToIp (),\r
1630 EFI_DNS6_PROTOCOL.IpToHostName() or\r
1631 EFI_DNS6_PROTOCOL.GeneralLookup().\r
1632 If NULL, all pending tokens are aborted.\r
1633\r
1634 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1635 @retval EFI_NOT_STARTED This EFI DNS6 Protocol instance has not been started.\r
1636 @retval EFI_INVALID_PARAMETER This is NULL.\r
1637 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1638 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS\r
1639 operation was not found in the transmit queue. It\r
1640 was either completed or was not issued by\r
1641 HostNameToIp(), IpToHostName() or GeneralLookup().\r
99c048ef 1642**/\r
1643EFI_STATUS\r
1644EFIAPI\r
1645Dns6Cancel (\r
1646 IN EFI_DNS6_PROTOCOL *This,\r
1647 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1648 )\r
1649{\r
1650 EFI_STATUS Status;\r
1651 DNS_INSTANCE *Instance;\r
1652 EFI_TPL OldTpl;\r
1653\r
1654 if (This == NULL) {\r
1655 return EFI_INVALID_PARAMETER;\r
1656 }\r
1657\r
1658 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1659\r
1660 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1661 return EFI_NOT_STARTED;\r
1662 }\r
1663\r
1664 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1665\r
1666 //\r
1667 // Cancle the tokens specified by Token for this instance.\r
1668 //\r
1669 Status = Dns6InstanceCancelToken (Instance, Token);\r
1670\r
1671 //\r
1672 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
1673 //\r
1674 DispatchDpc ();\r
1675\r
1676 gBS->RestoreTPL (OldTpl);\r
1677\r
1678 return Status;\r
1679}\r
1680\r