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