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