]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/DnsDxe/DnsProtocol.c
NetworkPkg: Correct inconsistent function descriptions in DNS
[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
457 QueryName = DnsFillinQNameForQueryIp (TokenEntry->QueryHostName);\r
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
496 if (TokenEntry != NULL) {\r
497 FreePool (TokenEntry);\r
498 }\r
499 \r
500 NetbufFree (Packet);\r
501 }\r
502 \r
503ON_EXIT:\r
fcae1a99
JW
504 if (QueryName != NULL) {\r
505 FreePool (QueryName);\r
506 }\r
507 \r
99c048ef 508 gBS->RestoreTPL (OldTpl);\r
509 return Status;\r
510}\r
511\r
512/**\r
0f4e123f
JW
513 IPv4 address to host name translation also known as Reverse DNS lookup.\r
514\r
515 The IpToHostName() function is used to translate the host address to host name. A type PTR \r
516 query is used to get the primary name of the host. Support of this function is optional.\r
517\r
518 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
519 @param[in] IpAddress Ip Address.\r
520 @param[in] Token Point to the completion token to translate host\r
521 address to host name.\r
522\r
523 @retval EFI_SUCCESS The operation completed successfully.\r
524 @retval EFI_UNSUPPORTED This function is not supported.\r
525 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
526 This is NULL.\r
527 Token is NULL.\r
528 Token.Event is NULL.\r
529 IpAddress is not valid IP address .\r
530 @retval EFI_NO_MAPPING There's no source address is available for use.\r
531 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
532 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 533**/\r
534EFI_STATUS\r
535EFIAPI\r
536Dns4IpToHostName (\r
537 IN EFI_DNS4_PROTOCOL *This,\r
538 IN EFI_IPv4_ADDRESS IpAddress,\r
539 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
540 )\r
541{\r
542 return EFI_UNSUPPORTED;\r
543}\r
544\r
545/**\r
0f4e123f
JW
546 Retrieve arbitrary information from the DNS server. \r
547\r
548 This GeneralLookup() function retrieves arbitrary information from the DNS. The caller\r
549 supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. All\r
550 RR content (e.g., TTL) was returned. The caller need parse the returned RR to get\r
551 required information. The function is optional.\r
552\r
553 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
554 @param[in] QName Pointer to Query Name.\r
555 @param[in] QType Query Type.\r
556 @param[in] QClass Query Name.\r
557 @param[in] Token Point to the completion token to retrieve arbitrary\r
558 information.\r
559\r
560 @retval EFI_SUCCESS The operation completed successfully.\r
561 @retval EFI_UNSUPPORTED This function is not supported. Or the requested\r
562 QType is not supported\r
563 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
564 This is NULL.\r
565 Token is NULL.\r
566 Token.Event is NULL.\r
567 QName is NULL.\r
568 @retval EFI_NO_MAPPING There's no source address is available for use.\r
569 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
570 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 571**/\r
572EFI_STATUS\r
573EFIAPI\r
574Dns4GeneralLookUp (\r
575 IN EFI_DNS4_PROTOCOL *This,\r
576 IN CHAR8 *QName,\r
577 IN UINT16 QType, \r
578 IN UINT16 QClass,\r
579 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
580 )\r
581{\r
fcae1a99
JW
582 EFI_STATUS Status;\r
583 \r
584 DNS_INSTANCE *Instance;\r
585 \r
586 EFI_DNS4_CONFIG_DATA *ConfigData;\r
587 \r
588 DNS4_TOKEN_ENTRY *TokenEntry;\r
589 NET_BUF *Packet;\r
590 \r
591 EFI_TPL OldTpl;\r
592 \r
593 Status = EFI_SUCCESS;\r
594 TokenEntry = NULL;\r
595 Packet = NULL;\r
596 \r
597 //\r
598 // Validate the parameters\r
599 //\r
600 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
601 return EFI_INVALID_PARAMETER;\r
602 }\r
603 \r
604 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
605 \r
606 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
607 \r
608 ConfigData = &(Instance->Dns4CfgData);\r
609 \r
610 Instance->MaxRetry = ConfigData->RetryCount;\r
611 \r
612 Token->Status = EFI_NOT_READY;\r
613 Token->RetryCount = 0;\r
614 Token->RetryInterval = ConfigData->RetryInterval;\r
615\r
616 if (Instance->State != DNS_STATE_CONFIGED) {\r
617 Status = EFI_NOT_STARTED;\r
618 goto ON_EXIT;\r
619 }\r
620\r
621 //\r
622 // Check the MaxRetry and RetryInterval values.\r
623 //\r
624 if (Instance->MaxRetry == 0) {\r
625 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
626 }\r
627\r
628 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
629 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
630 }\r
631\r
632 //\r
633 // Construct DNS TokenEntry.\r
634 //\r
635 TokenEntry = AllocateZeroPool (sizeof(DNS4_TOKEN_ENTRY));\r
636 if (TokenEntry == NULL) {\r
637 Status = EFI_OUT_OF_RESOURCES;\r
638 goto ON_EXIT;\r
639 }\r
640 \r
641 TokenEntry->PacketToLive = Token->RetryInterval;\r
642 TokenEntry->GeneralLookUp = TRUE;\r
643 TokenEntry->Token = Token;\r
644\r
645 //\r
646 // Construct DNS Query Packet.\r
647 //\r
648 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
649 if (EFI_ERROR (Status)) {\r
650 if (TokenEntry != NULL) {\r
651 FreePool (TokenEntry);\r
652 }\r
653 \r
654 goto ON_EXIT;\r
655 }\r
656\r
8339166d
JW
657 ASSERT (Packet != NULL);\r
658\r
fcae1a99
JW
659 //\r
660 // Save the token into the Dns4TxTokens map.\r
661 //\r
662 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);\r
663 if (EFI_ERROR (Status)) {\r
664 if (TokenEntry != NULL) {\r
665 FreePool (TokenEntry);\r
666 }\r
667 \r
668 NetbufFree (Packet);\r
669 \r
670 goto ON_EXIT;\r
671 }\r
672 \r
673 //\r
674 // Dns Query Ip\r
675 //\r
676 Status = DoDnsQuery (Instance, Packet);\r
677 if (EFI_ERROR (Status)) {\r
678 if (TokenEntry != NULL) {\r
679 FreePool (TokenEntry);\r
680 }\r
681 \r
682 NetbufFree (Packet);\r
683 }\r
684 \r
685ON_EXIT:\r
686 gBS->RestoreTPL (OldTpl);\r
687 return Status;\r
99c048ef 688}\r
689\r
690/**\r
0f4e123f
JW
691 This function is to update the DNS Cache.\r
692\r
693 The UpdateDnsCache() function is used to add/delete/modify DNS cache entry. DNS cache\r
694 can be normally dynamically updated after the DNS resolve succeeds. This function\r
695 provided capability to manually add/delete/modify the DNS cache.\r
696\r
697 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
698 @param[in] DeleteFlag If FALSE, this function is to add one entry to the\r
699 DNS Cahce. If TRUE, this function will delete\r
700 matching DNS Cache entry.\r
701 @param[in] Override If TRUE, the maching DNS cache entry will be\r
702 overwritten with the supplied parameter. If FALSE,\r
703 EFI_ACCESS_DENIED will be returned if the entry to\r
704 be added is already existed.\r
705 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
706\r
707 @retval EFI_SUCCESS The operation completed successfully.\r
708 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
709 This is NULL.\r
710 DnsCacheEntry.HostName is NULL.\r
711 DnsCacheEntry.IpAddress is NULL.\r
712 DnsCacheEntry.Timeout is zero.\r
713 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is\r
714 not TRUE.\r
99c048ef 715**/\r
716EFI_STATUS\r
717EFIAPI\r
718Dns4UpdateDnsCache (\r
719 IN EFI_DNS4_PROTOCOL *This,\r
720 IN BOOLEAN DeleteFlag,\r
721 IN BOOLEAN Override,\r
722 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry\r
723 )\r
724{\r
725 EFI_STATUS Status; \r
726 EFI_TPL OldTpl;\r
727\r
728 Status = EFI_SUCCESS;\r
729 \r
730 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
731 return EFI_INVALID_PARAMETER; \r
732 }\r
733 \r
734 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
735\r
736 //\r
737 // Update Dns4Cache here.\r
738 //\r
739 Status = UpdateDns4Cache (&mDriverData->Dns4CacheList, DeleteFlag, Override, DnsCacheEntry);\r
740\r
741 gBS->RestoreTPL (OldTpl);\r
742 \r
743 return Status;\r
744}\r
745\r
746/**\r
0f4e123f
JW
747 Polls for incoming data packets and processes outgoing data packets.\r
748\r
749 The Poll() function can be used by network drivers and applications to increase the\r
750 rate that data packets are moved between the communications device and the transmit\r
751 and receive queues.\r
752 In some systems, the periodic timer event in the managed network driver may not poll\r
753 the underlying communications device fast enough to transmit and/or receive all data\r
754 packets without missing incoming packets or dropping outgoing packets. Drivers and\r
755 applications that are experiencing packet loss should try calling the Poll()\r
756 function more often.\r
757\r
758 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
759\r
760 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
761 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.\r
762 @retval EFI_INVALID_PARAMETER This is NULL.\r
763 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
764 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive\r
765 queue. Consider increasing the polling rate.\r
99c048ef 766**/\r
767EFI_STATUS\r
768EFIAPI\r
769Dns4Poll (\r
770 IN EFI_DNS4_PROTOCOL *This\r
771 )\r
772{\r
773 DNS_INSTANCE *Instance;\r
774 EFI_UDP4_PROTOCOL *Udp;\r
775\r
776 if (This == NULL) {\r
777 return EFI_INVALID_PARAMETER;\r
778 }\r
779\r
780 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
781\r
782 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
783 return EFI_NOT_STARTED;\r
784 } else if (Instance->State == DNS_STATE_DESTROY) {\r
785 return EFI_DEVICE_ERROR;\r
786 }\r
787\r
788 Udp = Instance->UdpIo->Protocol.Udp4;\r
789 \r
790 return Udp->Poll (Udp);\r
791}\r
792\r
793/**\r
0f4e123f
JW
794 Abort an asynchronous DNS operation, including translation between IP and Host, and\r
795 general look up behavior.\r
796\r
797 The Cancel() function is used to abort a pending resolution request. After calling\r
798 this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be\r
799 signaled. If the token is not in one of the queues, which usually means that the\r
800 asynchronous operation has completed, this function will not signal the token and\r
801 EFI_NOT_FOUND is returned.\r
802\r
803 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.\r
804 @param[in] Token Pointer to a token that has been issued by\r
805 EFI_DNS4_PROTOCOL.HostNameToIp (),\r
806 EFI_DNS4_PROTOCOL.IpToHostName() or\r
807 EFI_DNS4_PROTOCOL.GeneralLookup().\r
808 If NULL, all pending tokens are aborted.\r
809\r
810 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
811 @retval EFI_NOT_STARTED This EFI DNS4 Protocol instance has not been started.\r
812 @retval EFI_INVALID_PARAMETER This is NULL.\r
813 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS\r
814 operation was not found in the transmit queue. It\r
815 was either completed or was not issued by\r
816 HostNameToIp(), IpToHostName() or GeneralLookup().\r
99c048ef 817**/\r
818EFI_STATUS\r
819EFIAPI\r
820Dns4Cancel (\r
821 IN EFI_DNS4_PROTOCOL *This,\r
822 IN EFI_DNS4_COMPLETION_TOKEN *Token\r
823 )\r
824{\r
825 EFI_STATUS Status;\r
826 DNS_INSTANCE *Instance;\r
827 EFI_TPL OldTpl;\r
828\r
829 if (This == NULL) {\r
830 return EFI_INVALID_PARAMETER;\r
831 }\r
832\r
833 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);\r
834\r
835 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
836 return EFI_NOT_STARTED;\r
837 }\r
838\r
839 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
840\r
841 //\r
842 // Cancle the tokens specified by Token for this instance.\r
843 //\r
844 Status = Dns4InstanceCancelToken (Instance, Token);\r
845\r
846 //\r
847 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
848 //\r
849 DispatchDpc ();\r
850\r
851 gBS->RestoreTPL (OldTpl);\r
852\r
853 return Status;\r
854}\r
855\r
856/**\r
0f4e123f 857 Retrieve mode data of this DNS instance.\r
99c048ef 858\r
0f4e123f 859 This function is used to retrieve DNS mode data for this DNS instance.\r
99c048ef 860\r
0f4e123f
JW
861 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
862 @param[out] DnsModeData Pointer to the caller-allocated storage for the \r
863 EFI_DNS6_MODE_DATA data.\r
99c048ef 864\r
0f4e123f
JW
865 @retval EFI_SUCCESS The operation completed successfully.\r
866 @retval EFI_NOT_STARTED When DnsConfigData is queried, no configuration data\r
867 is available because this instance has not been\r
868 configured.\r
869 @retval EFI_INVALID_PARAMETER This is NULL or DnsModeData is NULL.\r
870 @retval EFI_OUT_OF_RESOURCE Failed to allocate needed resources.\r
99c048ef 871**/\r
872EFI_STATUS\r
873EFIAPI\r
874Dns6GetModeData (\r
875 IN EFI_DNS6_PROTOCOL *This,\r
876 OUT EFI_DNS6_MODE_DATA *DnsModeData\r
877 )\r
878{\r
879 DNS_INSTANCE *Instance;\r
880 \r
881 EFI_TPL OldTpl;\r
882\r
883 UINTN Index;\r
884 \r
885 LIST_ENTRY *Entry;\r
886 LIST_ENTRY *Next;\r
887\r
888 DNS6_SERVER_IP *ServerItem;\r
889 EFI_IPv6_ADDRESS *ServerList;\r
890 DNS6_CACHE *CacheItem;\r
891 EFI_DNS6_CACHE_ENTRY *CacheList;\r
892 EFI_STATUS Status;\r
893\r
894 ServerItem = NULL;\r
895 ServerList = NULL;\r
896 CacheItem = NULL;\r
897 CacheList = NULL;\r
898 Status = EFI_SUCCESS;\r
899\r
900 if ((This == NULL) || (DnsModeData == NULL)) {\r
901 return EFI_INVALID_PARAMETER;\r
902 }\r
903\r
904 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
905 \r
906 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
907 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
908 gBS->RestoreTPL (OldTpl);\r
909 return EFI_NOT_STARTED;\r
910 }\r
911\r
912 ZeroMem (DnsModeData, sizeof (EFI_DNS6_MODE_DATA));\r
913\r
914 //\r
915 // Get the current configuration data of this instance. \r
916 //\r
917 Status = Dns6CopyConfigure(&DnsModeData->DnsConfigData, &Instance->Dns6CfgData);\r
918 if (EFI_ERROR (Status)) {\r
919 gBS->RestoreTPL (OldTpl);\r
920 return Status;\r
921 }\r
922 \r
923 //\r
924 // Get the DnsServerCount and DnsServerList\r
925 //\r
926 Index = 0;\r
927 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
928 Index++;\r
929 }\r
930 DnsModeData->DnsServerCount = (UINT32) Index;\r
931 ServerList = AllocatePool (sizeof(EFI_IPv6_ADDRESS) * DnsModeData->DnsServerCount);\r
932 ASSERT (ServerList != NULL);\r
933 Index = 0;\r
934 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {\r
935 ServerItem = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);\r
936 CopyMem (ServerList + Index, &ServerItem->Dns6ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
937 Index++;\r
938 }\r
939 DnsModeData->DnsServerList = ServerList;\r
940\r
941 //\r
942 // Get the DnsCacheCount and DnsCacheList\r
943 //\r
944 Index =0;\r
945 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
946 Index++;\r
947 }\r
948 DnsModeData->DnsCacheCount = (UINT32) Index;\r
949 CacheList = AllocatePool (sizeof(EFI_DNS6_CACHE_ENTRY) * DnsModeData->DnsCacheCount);\r
950 ASSERT (CacheList != NULL);\r
951 Index =0;\r
952 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
953 CacheItem = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
954 CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS6_CACHE_ENTRY));\r
955 Index++;\r
956 }\r
957 DnsModeData->DnsCacheList = CacheList;\r
958\r
959 gBS->RestoreTPL (OldTpl);\r
960 \r
961 return EFI_SUCCESS;\r
962}\r
963\r
964/**\r
0f4e123f
JW
965 Configure this DNS instance.\r
966\r
967 The Configure() function is used to set and change the configuration data for this\r
968 EFI DNSv6 Protocol driver instance. Reset the DNS instance if DnsConfigData is NULL.\r
969\r
970 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
971 @param[in] DnsConfigData Pointer to the configuration data structure. All associated \r
972 storage to be allocated and released by caller.\r
973\r
974 @retval EFI_SUCCESS The operation completed successfully.\r
975 @retval EFI_INVALID_PARAMTER This is NULL.\r
976 The StationIp address provided in DnsConfigData is not zero and not a valid unicast.\r
977 DnsServerList is NULL while DnsServerList Count is not ZERO.\r
978 DnsServerList Count is ZERO while DnsServerList is not NULL.\r
979 @retval EFI_OUT_OF_RESOURCES The DNS instance data or required space could not be allocated.\r
980 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The\r
981 EFI DNSv6 Protocol instance is not configured.\r
982 @retval EFI_UNSUPPORTED The designated protocol is not supported.\r
983 @retval EFI_ALREADY_STARTED Second call to Configure() with DnsConfigData. To \r
984 reconfigure the instance the caller must call Configure() with \r
985 NULL first to return driver to unconfigured state.\r
99c048ef 986**/\r
987EFI_STATUS\r
988EFIAPI\r
989Dns6Configure (\r
990 IN EFI_DNS6_PROTOCOL *This,\r
991 IN EFI_DNS6_CONFIG_DATA *DnsConfigData\r
992 )\r
993{\r
994 EFI_STATUS Status;\r
995 DNS_INSTANCE *Instance;\r
996 \r
997 EFI_TPL OldTpl;\r
998\r
999 UINT32 ServerListCount;\r
1000 EFI_IPv6_ADDRESS *ServerList; \r
1001\r
1002 Status = EFI_SUCCESS;\r
1003 ServerList = NULL;\r
1004\r
1005 if (This == NULL || \r
1006 (DnsConfigData != NULL && ((DnsConfigData->DnsServerCount != 0 && DnsConfigData->DnsServerList == NULL) || \r
1007 (DnsConfigData->DnsServerCount == 0 && DnsConfigData->DnsServerList != NULL)))) {\r
1008 return EFI_INVALID_PARAMETER;\r
1009 }\r
1010\r
1011 if (DnsConfigData != NULL && DnsConfigData->Protocol != DNS_PROTOCOL_UDP) {\r
1012 return EFI_UNSUPPORTED;\r
1013 }\r
1014\r
1015 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1016\r
1017 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1018\r
1019 if (DnsConfigData == NULL) {\r
1020 ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));\r
1021\r
1022 //\r
1023 // Reset the Instance if ConfigData is NULL\r
1024 //\r
1025 if (!NetMapIsEmpty(&Instance->Dns6TxTokens)) {\r
1026 Dns6InstanceCancelToken(Instance, NULL);\r
1027 }\r
1028\r
1029 Instance->MaxRetry = 0;\r
1030\r
1031 if (Instance->UdpIo != NULL){\r
1032 UdpIoCleanIo (Instance->UdpIo);\r
1033 }\r
1034\r
1035 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1036 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1037 }\r
1038 ZeroMem (&Instance->Dns6CfgData, sizeof (EFI_DNS6_CONFIG_DATA));\r
1039 \r
1040 Instance->State = DNS_STATE_UNCONFIGED;\r
1041 } else {\r
1042 //\r
1043 // Configure the parameters for new operation.\r
1044 //\r
90ae1f02 1045 if (!NetIp6IsUnspecifiedAddr (&DnsConfigData->StationIp) && !NetIp6IsValidUnicast (&DnsConfigData->StationIp)) {\r
99c048ef 1046 Status = EFI_INVALID_PARAMETER;\r
1047 goto ON_EXIT;\r
1048 }\r
1049\r
1050 Status = Dns6CopyConfigure (&Instance->Dns6CfgData, DnsConfigData);\r
1051 if (EFI_ERROR (Status)) {\r
1052 goto ON_EXIT;\r
1053 }\r
1054\r
1055 if (DnsConfigData->DnsServerCount == 0 || DnsConfigData->DnsServerList == NULL) {\r
1056 gBS->RestoreTPL (OldTpl);\r
1057\r
1058 //\r
1059 //The DNS instance will retrieve DNS server from DHCP Server.\r
1060 //\r
1061 Status = GetDns6ServerFromDhcp6 (\r
1062 Instance->Service->ImageHandle,\r
1063 Instance->Service->ControllerHandle, \r
1064 &ServerListCount, \r
1065 &ServerList\r
1066 );\r
1067 if (EFI_ERROR (Status)) {\r
1068 goto ON_EXIT;\r
1069 }\r
1070 \r
1071 ASSERT(ServerList != NULL);\r
1072\r
1073 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1074\r
1075 CopyMem (&Instance->SessionDnsServer.v6, &ServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1076 } else {\r
1077 CopyMem (&Instance->SessionDnsServer.v6, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv6_ADDRESS));\r
1078 }\r
1079\r
1080 //\r
1081 // Config UDP\r
1082 //\r
1083 Status = Dns6ConfigUdp (Instance, Instance->UdpIo);\r
1084 if (EFI_ERROR (Status)) {\r
1085 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1086 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1087 }\r
1088 goto ON_EXIT;\r
1089 }\r
1090\r
1091 //\r
1092 // Add configured DNS server used by this instance to ServerList.\r
1093 //\r
1094 Status = AddDns6ServerIp (&mDriverData->Dns6ServerList, Instance->SessionDnsServer.v6);\r
1095 if (EFI_ERROR (Status)) {\r
1096 if (Instance->Dns6CfgData.DnsServerList != NULL) {\r
1097 FreePool (Instance->Dns6CfgData.DnsServerList);\r
1098 }\r
1099 goto ON_EXIT;\r
1100 }\r
1101 \r
1102 Instance->State = DNS_STATE_CONFIGED;\r
1103 }\r
1104\r
1105ON_EXIT:\r
1106 gBS->RestoreTPL (OldTpl);\r
1107 return Status;\r
1108}\r
1109\r
1110/**\r
0f4e123f
JW
1111 Host name to host address translation.\r
1112\r
1113 The HostNameToIp () function is used to translate the host name to host IP address. A\r
1114 type AAAA query is used to get the one or more IPv6 addresses for this host.\r
1115\r
1116 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1117 @param[in] HostName Host name.\r
1118 @param[in] Token Point to the completion token to translate host name\r
1119 to host address.\r
1120\r
1121 @retval EFI_SUCCESS The operation completed successfully.\r
1122 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1123 This is NULL.\r
1124 Token is NULL.\r
1125 Token.Event is NULL.\r
1126 HostName is NULL or buffer contained unsupported characters.\r
1127 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1128 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.\r
1129 @retval EFI_NOT_STARTED This instance has not been started.\r
1130 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 1131**/\r
1132EFI_STATUS\r
1133EFIAPI\r
1134Dns6HostNameToIp (\r
1135 IN EFI_DNS6_PROTOCOL *This,\r
1136 IN CHAR16 *HostName,\r
1137 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1138 )\r
1139{\r
1140 EFI_STATUS Status;\r
1141 \r
1142 DNS_INSTANCE *Instance;\r
1143\r
1144 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1145 \r
1146 UINTN Index; \r
1147 DNS6_CACHE *Item;\r
1148 LIST_ENTRY *Entry;\r
1149 LIST_ENTRY *Next;\r
1150 \r
fcae1a99
JW
1151 CHAR8 *QueryName;\r
1152 \r
99c048ef 1153 DNS6_TOKEN_ENTRY *TokenEntry;\r
1154 NET_BUF *Packet;\r
1155 \r
1156 EFI_TPL OldTpl;\r
1157 \r
1158 Status = EFI_SUCCESS;\r
1159 Item = NULL;\r
fcae1a99 1160 QueryName = NULL;\r
99c048ef 1161 TokenEntry = NULL;\r
1162 Packet = NULL;\r
1163\r
1164 //\r
1165 // Validate the parameters\r
1166 //\r
1167 if ((This == NULL) || (HostName == NULL) || Token == NULL) {\r
1168 return EFI_INVALID_PARAMETER;\r
1169 }\r
1170\r
1171 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1172 \r
1173 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1174 \r
1175 ConfigData = &(Instance->Dns6CfgData);\r
1176 \r
1177 Instance->MaxRetry = ConfigData->RetryCount;\r
1178\r
1179 Token->Status = EFI_NOT_READY;\r
1180 Token->RetryCount = 0;\r
1181 Token->RetryInterval = ConfigData->RetryInterval;\r
1182\r
1183 if (Instance->State != DNS_STATE_CONFIGED) {\r
1184 Status = EFI_NOT_STARTED;\r
1185 goto ON_EXIT;\r
1186 }\r
1187\r
1188 //\r
1189 // Check the MaxRetry and RetryInterval values.\r
1190 //\r
1191 if (Instance->MaxRetry == 0) {\r
1192 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1193 }\r
1194\r
1195 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1196 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1197 } \r
1198\r
1199 //\r
1200 // Check cache\r
1201 //\r
1202 if (ConfigData->EnableDnsCache) {\r
1203 Index = 0;\r
1204 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1205 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1206 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1207 Index++;\r
1208 }\r
1209 }\r
1210\r
1211 if (Index != 0) {\r
1212 Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
1213 if (Token->RspData.H2AData == NULL) {\r
1214 Status = EFI_OUT_OF_RESOURCES;\r
1215 goto ON_EXIT;\r
1216 }\r
1217\r
1218 Token->RspData.H2AData->IpCount = (UINT32)Index;\r
1219 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv6_ADDRESS) * Index);\r
1220 if (Token->RspData.H2AData->IpList == NULL) {\r
1221 if (Token->RspData.H2AData != NULL) {\r
1222 FreePool (Token->RspData.H2AData);\r
1223 }\r
1224 \r
1225 Status = EFI_OUT_OF_RESOURCES;\r
1226 goto ON_EXIT;\r
1227 }\r
1228\r
1229 Index = 0;\r
1230 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {\r
1231 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
1232 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {\r
1233 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
1234 Index++;\r
1235 }\r
1236 }\r
1237 \r
1238 Token->Status = EFI_SUCCESS;\r
1239 \r
1240 if (Token->Event != NULL) {\r
1241 gBS->SignalEvent (Token->Event);\r
1242 DispatchDpc ();\r
1243 }\r
1244 \r
1245 Status = Token->Status;\r
1246 goto ON_EXIT;\r
1247 } \r
1248 }\r
1249\r
1250 //\r
1251 // Construct DNS TokenEntry.\r
1252 //\r
1253 TokenEntry = AllocateZeroPool (sizeof (DNS6_TOKEN_ENTRY));\r
1254 if (TokenEntry == NULL) {\r
1255 Status = EFI_OUT_OF_RESOURCES;\r
1256 goto ON_EXIT;\r
1257 }\r
1258 \r
1259 TokenEntry->PacketToLive = Token->RetryInterval;\r
1260 TokenEntry->QueryHostName = HostName;\r
1261 TokenEntry->Token = Token;\r
1262\r
fcae1a99
JW
1263\r
1264 //\r
1265 // Construct QName.\r
1266 //\r
1267 QueryName = DnsFillinQNameForQueryIp (TokenEntry->QueryHostName);\r
1268 if (QueryName == NULL) {\r
1269 Status = EFI_OUT_OF_RESOURCES;\r
1270 goto ON_EXIT;\r
1271 }\r
1272 \r
99c048ef 1273 //\r
1274 // Construct DNS Query Packet.\r
1275 //\r
fcae1a99 1276 Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_AAAA, DNS_CLASS_INET, &Packet);\r
99c048ef 1277 if (EFI_ERROR (Status)) {\r
1278 if (TokenEntry != NULL) {\r
1279 FreePool (TokenEntry);\r
1280 }\r
1281 \r
1282 goto ON_EXIT;\r
1283 }\r
1284\r
8339166d
JW
1285 ASSERT (Packet != NULL);\r
1286\r
99c048ef 1287 //\r
1288 // Save the token into the Dns6TxTokens map.\r
1289 //\r
1290 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1291 if (EFI_ERROR (Status)) {\r
1292 if (TokenEntry != NULL) {\r
1293 FreePool (TokenEntry);\r
1294 }\r
1295 \r
1296 NetbufFree (Packet);\r
1297 \r
1298 goto ON_EXIT;\r
1299 }\r
1300 \r
1301 //\r
1302 // Dns Query Ip\r
1303 //\r
1304 Status = DoDnsQuery (Instance, Packet);\r
1305 if (EFI_ERROR (Status)) {\r
1306 if (TokenEntry != NULL) {\r
1307 FreePool (TokenEntry);\r
1308 }\r
1309 \r
1310 NetbufFree (Packet);\r
1311 }\r
1312 \r
1313ON_EXIT:\r
fcae1a99
JW
1314 if (QueryName != NULL) {\r
1315 FreePool (QueryName);\r
1316 }\r
1317 \r
99c048ef 1318 gBS->RestoreTPL (OldTpl);\r
1319 return Status;\r
1320}\r
1321\r
1322/**\r
0f4e123f
JW
1323 Host address to host name translation.\r
1324\r
1325 The IpToHostName () function is used to translate the host address to host name. A\r
1326 type PTR query is used to get the primary name of the host. Implementation can choose\r
1327 to support this function or not.\r
1328\r
1329 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1330 @param[in] IpAddress Ip Address.\r
1331 @param[in] Token Point to the completion token to translate host\r
1332 address to host name.\r
1333\r
1334 @retval EFI_SUCCESS The operation completed successfully.\r
1335 @retval EFI_UNSUPPORTED This function is not supported.\r
1336 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1337 This is NULL.\r
1338 Token is NULL.\r
1339 Token.Event is NULL.\r
1340 IpAddress is not valid IP address.\r
1341 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1342 @retval EFI_NOT_STARTED This instance has not been started.\r
1343 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 1344**/\r
1345EFI_STATUS\r
1346EFIAPI\r
1347Dns6IpToHostName (\r
1348 IN EFI_DNS6_PROTOCOL *This,\r
1349 IN EFI_IPv6_ADDRESS IpAddress,\r
1350 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1351 )\r
1352{\r
1353 return EFI_UNSUPPORTED;\r
1354}\r
1355\r
1356/**\r
0f4e123f
JW
1357 This function provides capability to retrieve arbitrary information from the DNS\r
1358 server.\r
1359\r
1360 This GeneralLookup() function retrieves arbitrary information from the DNS. The caller\r
1361 supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. All\r
1362 RR content (e.g., TTL) was returned. The caller need parse the returned RR to get\r
1363 required information. The function is optional. Implementation can choose to support\r
1364 it or not.\r
1365\r
1366 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1367 @param[in] QName Pointer to Query Name.\r
1368 @param[in] QType Query Type.\r
1369 @param[in] QClass Query Name.\r
1370 @param[in] Token Point to the completion token to retrieve arbitrary\r
1371 information.\r
1372\r
1373 @retval EFI_SUCCESS The operation completed successfully.\r
1374 @retval EFI_UNSUPPORTED This function is not supported. Or the requested\r
1375 QType is not supported\r
1376 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1377 This is NULL.\r
1378 Token is NULL.\r
1379 Token.Event is NULL.\r
1380 QName is NULL.\r
1381 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1382 @retval EFI_NOT_STARTED This instance has not been started.\r
1383 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.\r
99c048ef 1384**/\r
1385EFI_STATUS\r
1386EFIAPI\r
1387Dns6GeneralLookUp (\r
1388 IN EFI_DNS6_PROTOCOL *This,\r
1389 IN CHAR8 *QName,\r
1390 IN UINT16 QType, \r
1391 IN UINT16 QClass,\r
1392 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1393 )\r
1394{\r
fcae1a99
JW
1395 EFI_STATUS Status;\r
1396 \r
1397 DNS_INSTANCE *Instance;\r
1398 \r
1399 EFI_DNS6_CONFIG_DATA *ConfigData;\r
1400 \r
1401 DNS6_TOKEN_ENTRY *TokenEntry;\r
1402 NET_BUF *Packet;\r
1403 \r
1404 EFI_TPL OldTpl;\r
1405 \r
1406 Status = EFI_SUCCESS;\r
1407 TokenEntry = NULL;\r
1408 Packet = NULL;\r
1409 \r
1410 //\r
1411 // Validate the parameters\r
1412 //\r
1413 if ((This == NULL) || (QName == NULL) || Token == NULL) {\r
1414 return EFI_INVALID_PARAMETER;\r
1415 }\r
1416 \r
1417 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1418 \r
1419 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1420 \r
1421 ConfigData = &(Instance->Dns6CfgData);\r
1422 \r
1423 Instance->MaxRetry = ConfigData->RetryCount;\r
1424 \r
1425 Token->Status = EFI_NOT_READY;\r
1426 Token->RetryCount = 0;\r
1427 Token->RetryInterval = ConfigData->RetryInterval;\r
1428\r
1429 if (Instance->State != DNS_STATE_CONFIGED) {\r
1430 Status = EFI_NOT_STARTED;\r
1431 goto ON_EXIT;\r
1432 }\r
1433\r
1434 //\r
1435 // Check the MaxRetry and RetryInterval values.\r
1436 //\r
1437 if (Instance->MaxRetry == 0) {\r
1438 Instance->MaxRetry = DNS_DEFAULT_RETRY;\r
1439 }\r
1440\r
1441 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {\r
1442 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;\r
1443 }\r
1444\r
1445 //\r
1446 // Construct DNS TokenEntry.\r
1447 //\r
1448 TokenEntry = AllocateZeroPool (sizeof(DNS6_TOKEN_ENTRY));\r
1449 if (TokenEntry == NULL) {\r
1450 Status = EFI_OUT_OF_RESOURCES;\r
1451 goto ON_EXIT;\r
1452 }\r
1453 \r
1454 TokenEntry->PacketToLive = Token->RetryInterval;\r
1455 TokenEntry->GeneralLookUp = TRUE;\r
1456 TokenEntry->Token = Token;\r
1457\r
1458 //\r
1459 // Construct DNS Query Packet.\r
1460 //\r
1461 Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);\r
1462 if (EFI_ERROR (Status)) {\r
1463 if (TokenEntry != NULL) {\r
1464 FreePool (TokenEntry);\r
1465 }\r
1466 \r
1467 goto ON_EXIT;\r
1468 }\r
1469\r
8339166d
JW
1470 ASSERT (Packet != NULL);\r
1471\r
fcae1a99
JW
1472 //\r
1473 // Save the token into the Dns6TxTokens map.\r
1474 //\r
1475 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);\r
1476 if (EFI_ERROR (Status)) {\r
1477 if (TokenEntry != NULL) {\r
1478 FreePool (TokenEntry);\r
1479 }\r
1480 \r
1481 NetbufFree (Packet);\r
1482 \r
1483 goto ON_EXIT;\r
1484 }\r
1485 \r
1486 //\r
1487 // Dns Query Ip\r
1488 //\r
1489 Status = DoDnsQuery (Instance, Packet);\r
1490 if (EFI_ERROR (Status)) {\r
1491 if (TokenEntry != NULL) {\r
1492 FreePool (TokenEntry);\r
1493 }\r
1494 \r
1495 NetbufFree (Packet);\r
1496 }\r
1497 \r
1498ON_EXIT:\r
1499 gBS->RestoreTPL (OldTpl);\r
1500 return Status;\r
99c048ef 1501}\r
1502\r
1503/**\r
0f4e123f
JW
1504 This function is to update the DNS Cache.\r
1505\r
1506 The UpdateDnsCache() function is used to add/delete/modify DNS cache entry. DNS cache\r
1507 can be normally dynamically updated after the DNS resolve succeeds. This function\r
1508 provided capability to manually add/delete/modify the DNS cache.\r
1509\r
1510 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1511 @param[in] DeleteFlag If FALSE, this function is to add one entry to the\r
1512 DNS Cahce. If TRUE, this function will delete\r
1513 matching DNS Cache entry.\r
1514 @param[in] Override If TRUE, the maching DNS cache entry will be\r
1515 overwritten with the supplied parameter. If FALSE,\r
1516 EFI_ACCESS_DENIED will be returned if the entry to\r
1517 be added is already existed.\r
1518 @param[in] DnsCacheEntry Pointer to DNS Cache entry.\r
1519\r
1520 @retval EFI_SUCCESS The operation completed successfully.\r
1521 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
1522 This is NULL.\r
1523 DnsCacheEntry.HostName is NULL.\r
1524 DnsCacheEntry.IpAddress is NULL.\r
1525 DnsCacheEntry.Timeout is zero.\r
1526 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is\r
1527 not TRUE.\r
1528 @retval EFI_OUT_OF_RESOURCE Failed to allocate needed resources.\r
99c048ef 1529**/\r
1530EFI_STATUS\r
1531EFIAPI\r
1532Dns6UpdateDnsCache (\r
1533 IN EFI_DNS6_PROTOCOL *This,\r
1534 IN BOOLEAN DeleteFlag,\r
1535 IN BOOLEAN Override,\r
1536 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry\r
1537 )\r
1538{\r
1539 EFI_STATUS Status; \r
1540 EFI_TPL OldTpl;\r
1541\r
1542 Status = EFI_SUCCESS;\r
1543 \r
1544 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {\r
1545 return EFI_INVALID_PARAMETER; \r
1546 }\r
1547 \r
1548 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1549\r
1550 //\r
1551 // Update Dns6Cache here.\r
1552 //\r
1553 Status = UpdateDns6Cache (&mDriverData->Dns6CacheList, DeleteFlag, Override, DnsCacheEntry);\r
1554 \r
1555 gBS->RestoreTPL (OldTpl);\r
1556 \r
1557 return Status;\r
1558}\r
1559\r
1560/**\r
0f4e123f
JW
1561 Polls for incoming data packets and processes outgoing data packets.\r
1562\r
1563 The Poll() function can be used by network drivers and applications to increase the\r
1564 rate that data packets are moved between the communications device and the transmit\r
1565 and receive queues.\r
1566\r
1567 In some systems, the periodic timer event in the managed network driver may not poll\r
1568 the underlying communications device fast enough to transmit and/or receive all data\r
1569 packets without missing incoming packets or dropping outgoing packets. Drivers and\r
1570 applications that are experiencing packet loss should try calling the Poll()\r
1571 function more often.\r
1572\r
1573 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1574\r
1575 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1576 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.\r
1577 @retval EFI_INVALID_PARAMETER This is NULL.\r
1578 @retval EFI_NO_MAPPING There is no source address is available for use.\r
1579 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
1580 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive\r
1581 queue. Consider increasing the polling rate.\r
99c048ef 1582**/\r
1583EFI_STATUS\r
1584EFIAPI\r
1585Dns6Poll (\r
1586 IN EFI_DNS6_PROTOCOL *This\r
1587 )\r
1588{\r
1589 DNS_INSTANCE *Instance;\r
1590 EFI_UDP6_PROTOCOL *Udp;\r
1591\r
1592 if (This == NULL) {\r
1593 return EFI_INVALID_PARAMETER;\r
1594 }\r
1595\r
1596 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1597\r
1598 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1599 return EFI_NOT_STARTED;\r
1600 } else if (Instance->State == DNS_STATE_DESTROY) {\r
1601 return EFI_DEVICE_ERROR;\r
1602 }\r
1603\r
1604 Udp = Instance->UdpIo->Protocol.Udp6;\r
1605 \r
1606 return Udp->Poll (Udp);\r
1607}\r
1608\r
1609/**\r
0f4e123f
JW
1610 Abort an asynchronous DNS operation, including translation between IP and Host, and\r
1611 general look up behavior.\r
1612\r
1613 The Cancel() function is used to abort a pending resolution request. After calling\r
1614 this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be\r
1615 signaled. If the token is not in one of the queues, which usually means that the\r
1616 asynchronous operation has completed, this function will not signal the token and\r
1617 EFI_NOT_FOUND is returned.\r
1618\r
1619 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.\r
1620 @param[in] Token Pointer to a token that has been issued by\r
1621 EFI_DNS6_PROTOCOL.HostNameToIp (),\r
1622 EFI_DNS6_PROTOCOL.IpToHostName() or\r
1623 EFI_DNS6_PROTOCOL.GeneralLookup().\r
1624 If NULL, all pending tokens are aborted.\r
1625\r
1626 @retval EFI_SUCCESS Incoming or outgoing data was processed.\r
1627 @retval EFI_NOT_STARTED This EFI DNS6 Protocol instance has not been started.\r
1628 @retval EFI_INVALID_PARAMETER This is NULL.\r
1629 @retval EFI_NO_MAPPING There's no source address is available for use.\r
1630 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS\r
1631 operation was not found in the transmit queue. It\r
1632 was either completed or was not issued by\r
1633 HostNameToIp(), IpToHostName() or GeneralLookup().\r
99c048ef 1634**/\r
1635EFI_STATUS\r
1636EFIAPI\r
1637Dns6Cancel (\r
1638 IN EFI_DNS6_PROTOCOL *This,\r
1639 IN EFI_DNS6_COMPLETION_TOKEN *Token\r
1640 )\r
1641{\r
1642 EFI_STATUS Status;\r
1643 DNS_INSTANCE *Instance;\r
1644 EFI_TPL OldTpl;\r
1645\r
1646 if (This == NULL) {\r
1647 return EFI_INVALID_PARAMETER;\r
1648 }\r
1649\r
1650 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);\r
1651\r
1652 if (Instance->State == DNS_STATE_UNCONFIGED) {\r
1653 return EFI_NOT_STARTED;\r
1654 }\r
1655\r
1656 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
1657\r
1658 //\r
1659 // Cancle the tokens specified by Token for this instance.\r
1660 //\r
1661 Status = Dns6InstanceCancelToken (Instance, Token);\r
1662\r
1663 //\r
1664 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.\r
1665 //\r
1666 DispatchDpc ();\r
1667\r
1668 gBS->RestoreTPL (OldTpl);\r
1669\r
1670 return Status;\r
1671}\r
1672\r