NetworkPkg: Add DNS feature support over IPv4 and IPv6.
[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 DNS4_TOKEN_ENTRY *TokenEntry;
333 NET_BUF *Packet;
334
335 EFI_TPL OldTpl;
336
337 Status = EFI_SUCCESS;
338 Item = NULL;
339 TokenEntry = NULL;
340 Packet = NULL;
341
342 //
343 // Validate the parameters
344 //
345 if ((This == NULL) || (HostName == NULL) || Token == NULL) {
346 return EFI_INVALID_PARAMETER;
347 }
348
349 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
350
351 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);
352
353 ConfigData = &(Instance->Dns4CfgData);
354
355 Instance->MaxRetry = ConfigData->RetryCount;
356
357 Token->Status = EFI_NOT_READY;
358 Token->RetryCount = 0;
359 Token->RetryInterval = ConfigData->RetryInterval;
360
361 if (Instance->State != DNS_STATE_CONFIGED) {
362 Status = EFI_NOT_STARTED;
363 goto ON_EXIT;
364 }
365
366 //
367 // Check the MaxRetry and RetryInterval values.
368 //
369 if (Instance->MaxRetry == 0) {
370 Instance->MaxRetry = DNS_DEFAULT_RETRY;
371 }
372
373 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {
374 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;
375 }
376
377 //
378 // Check cache
379 //
380 if (ConfigData->EnableDnsCache) {
381 Index = 0;
382 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
383 Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
384 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {
385 Index++;
386 }
387 }
388
389 if (Index != 0) {
390 Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));
391 if (Token->RspData.H2AData == NULL) {
392 Status = EFI_OUT_OF_RESOURCES;
393 goto ON_EXIT;
394 }
395
396 Token->RspData.H2AData->IpCount = (UINT32)Index;
397 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv4_ADDRESS) * Index);
398 if (Token->RspData.H2AData->IpList == NULL) {
399 if (Token->RspData.H2AData != NULL) {
400 FreePool (Token->RspData.H2AData);
401 }
402
403 Status = EFI_OUT_OF_RESOURCES;
404 goto ON_EXIT;
405 }
406
407 Index = 0;
408 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
409 Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
410 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {
411 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS));
412 Index++;
413 }
414 }
415
416 Token->Status = EFI_SUCCESS;
417
418 if (Token->Event != NULL) {
419 gBS->SignalEvent (Token->Event);
420 DispatchDpc ();
421 }
422
423 Status = Token->Status;
424 goto ON_EXIT;
425 }
426 }
427
428 //
429 // Construct DNS TokenEntry.
430 //
431 TokenEntry = AllocateZeroPool (sizeof(DNS4_TOKEN_ENTRY));
432 if (TokenEntry == NULL) {
433 Status = EFI_OUT_OF_RESOURCES;
434 goto ON_EXIT;
435 }
436
437 TokenEntry->PacketToLive = Token->RetryInterval;
438 TokenEntry->QueryHostName = HostName;
439 TokenEntry->Token = Token;
440
441 //
442 // Construct DNS Query Packet.
443 //
444 Status = ConstructDNSQueryIp (Instance, TokenEntry->QueryHostName, DNS_TYPE_A, &Packet);
445 if (EFI_ERROR (Status)) {
446 if (TokenEntry != NULL) {
447 FreePool (TokenEntry);
448 }
449
450 goto ON_EXIT;
451 }
452
453 //
454 // Save the token into the Dns4TxTokens map.
455 //
456 Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);
457 if (EFI_ERROR (Status)) {
458 if (TokenEntry != NULL) {
459 FreePool (TokenEntry);
460 }
461
462 NetbufFree (Packet);
463
464 goto ON_EXIT;
465 }
466
467 //
468 // Dns Query Ip
469 //
470 Status = DoDnsQuery (Instance, Packet);
471 if (EFI_ERROR (Status)) {
472 if (TokenEntry != NULL) {
473 FreePool (TokenEntry);
474 }
475
476 NetbufFree (Packet);
477 }
478
479 ON_EXIT:
480 gBS->RestoreTPL (OldTpl);
481 return Status;
482 }
483
484 /**
485 The function is used to translate the host address to host name.
486 A type PTR query is used to get the primary name of the host.
487
488 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.
489 @param[in] IpAddress IP address.
490 @param[in] Token Pointer to the caller-allocated completion used token to translate host address to host name.
491
492 @retval EFI_SUCCESS The operation completed successfully.
493 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
494 @retval EFI_INVALID_PARAMETER This is NULL.
495 Token is NULL.
496 Token.Event is NULL.
497 IpAddress is not valid IP address.
498 @retval EFI_NO_MAPPING There's no source address is available for use.
499 @retval EFI_NOT_STARTED This instance has not been started.
500 @retval EFI_UNSUPPORTED This function is not supported.
501
502 **/
503 EFI_STATUS
504 EFIAPI
505 Dns4IpToHostName (
506 IN EFI_DNS4_PROTOCOL *This,
507 IN EFI_IPv4_ADDRESS IpAddress,
508 IN EFI_DNS4_COMPLETION_TOKEN *Token
509 )
510 {
511 return EFI_UNSUPPORTED;
512 }
513
514 /**
515 This function retrieves arbitrary information from the DNS.
516 The caller supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned.
517 All RR content (e.g., Ttl) was returned.
518 The caller need parse the returned RR to get required information. This function is optional.
519
520 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.
521 @param[in] QName Pointer to Query Name.
522 @param[in] QType Query Type.
523 @param[in] QClass Query Name.
524 @param[in] Token Point to the caller-allocated completion token to retrieve arbitrary information.
525
526 @retval EFI_SUCCESS The operation completed successfully.
527 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
528 @retval EFI_INVALID_PARAMETER This is NULL.
529 Token is NULL.
530 Token.Event is NULL.
531 QName is NULL.
532 @retval EFI_NO_MAPPING There's no source address is available for use.
533 @retval EFI_ALREADY_STARTED This Token is being used in another DNS session.
534 @retval EFI_UNSUPPORTED This function is not supported. Or the requested QType is not supported
535
536 **/
537 EFI_STATUS
538 EFIAPI
539 Dns4GeneralLookUp (
540 IN EFI_DNS4_PROTOCOL *This,
541 IN CHAR8 *QName,
542 IN UINT16 QType,
543 IN UINT16 QClass,
544 IN EFI_DNS4_COMPLETION_TOKEN *Token
545 )
546 {
547 return EFI_UNSUPPORTED;
548 }
549
550 /**
551 This function is used to add/delete/modify DNS cache entry.
552 DNS cache can be normally dynamically updated after the DNS resolve succeeds.
553 This function provided capability to manually add/delete/modify the DNS cache.
554
555 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.
556 @param[in] DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
557 If TRUE, this function will delete matching DNS Cache entry.
558 @param[in] Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
559 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
560 @param[in] DnsCacheEntry Pointer to DNS Cache entry.
561
562 @retval EFI_SUCCESS The operation completed successfully.
563 @retval EFI_INVALID_PARAMETER This is NULL.
564 DnsCacheEntry.HostName is NULL.
565 DnsCacheEntry.IpAddress is NULL.
566 DnsCacheEntry.Timeout is zero.
567 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is not TRUE.
568
569 **/
570 EFI_STATUS
571 EFIAPI
572 Dns4UpdateDnsCache (
573 IN EFI_DNS4_PROTOCOL *This,
574 IN BOOLEAN DeleteFlag,
575 IN BOOLEAN Override,
576 IN EFI_DNS4_CACHE_ENTRY DnsCacheEntry
577 )
578 {
579 EFI_STATUS Status;
580 EFI_TPL OldTpl;
581
582 Status = EFI_SUCCESS;
583
584 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {
585 return EFI_INVALID_PARAMETER;
586 }
587
588 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
589
590 //
591 // Update Dns4Cache here.
592 //
593 Status = UpdateDns4Cache (&mDriverData->Dns4CacheList, DeleteFlag, Override, DnsCacheEntry);
594
595 gBS->RestoreTPL (OldTpl);
596
597 return Status;
598 }
599
600 /**
601 This function can be used by network drivers and applications to increase the rate that data packets are moved between
602 the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed
603 network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets
604 without missing incoming packets or dropping outgoing packets.
605
606 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.
607
608 @retval EFI_SUCCESS Incoming or outgoing data was processed.
609 @retval EFI_INVALID_PARAMETER This is NULL.
610 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.
611 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
612 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue.
613 Consider increasing the polling rate.
614
615 **/
616 EFI_STATUS
617 EFIAPI
618 Dns4Poll (
619 IN EFI_DNS4_PROTOCOL *This
620 )
621 {
622 DNS_INSTANCE *Instance;
623 EFI_UDP4_PROTOCOL *Udp;
624
625 if (This == NULL) {
626 return EFI_INVALID_PARAMETER;
627 }
628
629 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);
630
631 if (Instance->State == DNS_STATE_UNCONFIGED) {
632 return EFI_NOT_STARTED;
633 } else if (Instance->State == DNS_STATE_DESTROY) {
634 return EFI_DEVICE_ERROR;
635 }
636
637 Udp = Instance->UdpIo->Protocol.Udp4;
638
639 return Udp->Poll (Udp);
640 }
641
642 /**
643 This function is used to abort a pending resolution request.
644 After calling this function, Token.Status will be set to EFI_ABORTED and then Token.
645
646 @param[in] This Pointer to EFI_DNS4_PROTOCOL instance.
647 @param[in] Token Pointer to a token that has been issued by EFI_DNS4_PROTOCOL.HostNameToIp(),
648 EFI_DNS4_PROTOCOL.IpToHostName() or EFI_DNS4_PROTOCOL.GeneralLookup().
649 If NULL, all pending tokens are aborted.
650
651 @retval EFI_SUCCESS Incoming or outgoing data was processed.
652 @retval EFI_INVALID_PARAMETER This is NULL.
653 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.
654 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS operation was not found in the transmit queue.
655 It was either completed or was not issued by HostNameToIp(), IpToHostName() or GeneralLookup().
656
657 **/
658 EFI_STATUS
659 EFIAPI
660 Dns4Cancel (
661 IN EFI_DNS4_PROTOCOL *This,
662 IN EFI_DNS4_COMPLETION_TOKEN *Token
663 )
664 {
665 EFI_STATUS Status;
666 DNS_INSTANCE *Instance;
667 EFI_TPL OldTpl;
668
669 if (This == NULL) {
670 return EFI_INVALID_PARAMETER;
671 }
672
673 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);
674
675 if (Instance->State == DNS_STATE_UNCONFIGED) {
676 return EFI_NOT_STARTED;
677 }
678
679 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
680
681 //
682 // Cancle the tokens specified by Token for this instance.
683 //
684 Status = Dns4InstanceCancelToken (Instance, Token);
685
686 //
687 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
688 //
689 DispatchDpc ();
690
691 gBS->RestoreTPL (OldTpl);
692
693 return Status;
694 }
695
696 /**
697 This function is used to retrieve DNS mode data for this DNS instance.
698
699 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
700 @param[out] DnsModeData Pointer to the caller-allocated storage for the EFI_DNS6_MODE_DATA structure.
701
702 @retval EFI_SUCCESS The operation completed successfully.
703 @retval EFI_NOT_STARTED When DnsConfigData is queried, no configuration data is
704 available because this instance has not been configured.
705 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
706 @retval EFI_INVALID_PARAMETER This is NULL or DnsModeData is NULL.
707
708 **/
709 EFI_STATUS
710 EFIAPI
711 Dns6GetModeData (
712 IN EFI_DNS6_PROTOCOL *This,
713 OUT EFI_DNS6_MODE_DATA *DnsModeData
714 )
715 {
716 DNS_INSTANCE *Instance;
717
718 EFI_TPL OldTpl;
719
720 UINTN Index;
721
722 LIST_ENTRY *Entry;
723 LIST_ENTRY *Next;
724
725 DNS6_SERVER_IP *ServerItem;
726 EFI_IPv6_ADDRESS *ServerList;
727 DNS6_CACHE *CacheItem;
728 EFI_DNS6_CACHE_ENTRY *CacheList;
729 EFI_STATUS Status;
730
731 ServerItem = NULL;
732 ServerList = NULL;
733 CacheItem = NULL;
734 CacheList = NULL;
735 Status = EFI_SUCCESS;
736
737 if ((This == NULL) || (DnsModeData == NULL)) {
738 return EFI_INVALID_PARAMETER;
739 }
740
741 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
742
743 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);
744 if (Instance->State == DNS_STATE_UNCONFIGED) {
745 gBS->RestoreTPL (OldTpl);
746 return EFI_NOT_STARTED;
747 }
748
749 ZeroMem (DnsModeData, sizeof (EFI_DNS6_MODE_DATA));
750
751 //
752 // Get the current configuration data of this instance.
753 //
754 Status = Dns6CopyConfigure(&DnsModeData->DnsConfigData, &Instance->Dns6CfgData);
755 if (EFI_ERROR (Status)) {
756 gBS->RestoreTPL (OldTpl);
757 return Status;
758 }
759
760 //
761 // Get the DnsServerCount and DnsServerList
762 //
763 Index = 0;
764 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {
765 Index++;
766 }
767 DnsModeData->DnsServerCount = (UINT32) Index;
768 ServerList = AllocatePool (sizeof(EFI_IPv6_ADDRESS) * DnsModeData->DnsServerCount);
769 ASSERT (ServerList != NULL);
770 Index = 0;
771 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {
772 ServerItem = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);
773 CopyMem (ServerList + Index, &ServerItem->Dns6ServerIp, sizeof (EFI_IPv6_ADDRESS));
774 Index++;
775 }
776 DnsModeData->DnsServerList = ServerList;
777
778 //
779 // Get the DnsCacheCount and DnsCacheList
780 //
781 Index =0;
782 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
783 Index++;
784 }
785 DnsModeData->DnsCacheCount = (UINT32) Index;
786 CacheList = AllocatePool (sizeof(EFI_DNS6_CACHE_ENTRY) * DnsModeData->DnsCacheCount);
787 ASSERT (CacheList != NULL);
788 Index =0;
789 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
790 CacheItem = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
791 CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS6_CACHE_ENTRY));
792 Index++;
793 }
794 DnsModeData->DnsCacheList = CacheList;
795
796 gBS->RestoreTPL (OldTpl);
797
798 return EFI_SUCCESS;
799 }
800
801 /**
802 The function is used to set and change the configuration data for this EFI DNSv6 Protocol driver instance.
803 Reset the DNS instance if DnsConfigData is NULL.
804
805 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
806 @param[in] DnsConfigData Pointer to the configuration data structure.
807 All associated storage to be allocated and released by caller.
808
809 @retval EFI_SUCCESS The operation completed successfully.
810 @retval EFI_UNSUPPORTED The designated protocol is not supported.
811 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
812 @retval EFI_INVALID_PARAMETER This is NULL.
813 The StationIp address provided in DnsConfigData is not a valid unicast.
814 DnsServerList is NULL while DnsServerListCount is not equal to Zero.
815 DnsServerListCount is Zero while DnsServerList is not equal to NULL.
816 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI DNSv6 Protocol instance is not configured.
817
818 **/
819 EFI_STATUS
820 EFIAPI
821 Dns6Configure (
822 IN EFI_DNS6_PROTOCOL *This,
823 IN EFI_DNS6_CONFIG_DATA *DnsConfigData
824 )
825 {
826 EFI_STATUS Status;
827 DNS_INSTANCE *Instance;
828
829 EFI_TPL OldTpl;
830
831 UINT32 ServerListCount;
832 EFI_IPv6_ADDRESS *ServerList;
833
834 Status = EFI_SUCCESS;
835 ServerList = NULL;
836
837 if (This == NULL ||
838 (DnsConfigData != NULL && ((DnsConfigData->DnsServerCount != 0 && DnsConfigData->DnsServerList == NULL) ||
839 (DnsConfigData->DnsServerCount == 0 && DnsConfigData->DnsServerList != NULL)))) {
840 return EFI_INVALID_PARAMETER;
841 }
842
843 if (DnsConfigData != NULL && DnsConfigData->Protocol != DNS_PROTOCOL_UDP) {
844 return EFI_UNSUPPORTED;
845 }
846
847 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
848
849 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);
850
851 if (DnsConfigData == NULL) {
852 ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));
853
854 //
855 // Reset the Instance if ConfigData is NULL
856 //
857 if (!NetMapIsEmpty(&Instance->Dns6TxTokens)) {
858 Dns6InstanceCancelToken(Instance, NULL);
859 }
860
861 Instance->MaxRetry = 0;
862
863 if (Instance->UdpIo != NULL){
864 UdpIoCleanIo (Instance->UdpIo);
865 }
866
867 if (Instance->Dns6CfgData.DnsServerList != NULL) {
868 FreePool (Instance->Dns6CfgData.DnsServerList);
869 }
870 ZeroMem (&Instance->Dns6CfgData, sizeof (EFI_DNS6_CONFIG_DATA));
871
872 Instance->State = DNS_STATE_UNCONFIGED;
873 } else {
874 //
875 // Configure the parameters for new operation.
876 //
877 if (!NetIp6IsValidUnicast (&DnsConfigData->StationIp)) {
878 Status = EFI_INVALID_PARAMETER;
879 goto ON_EXIT;
880 }
881
882 Status = Dns6CopyConfigure (&Instance->Dns6CfgData, DnsConfigData);
883 if (EFI_ERROR (Status)) {
884 goto ON_EXIT;
885 }
886
887 if (DnsConfigData->DnsServerCount == 0 || DnsConfigData->DnsServerList == NULL) {
888 gBS->RestoreTPL (OldTpl);
889
890 //
891 //The DNS instance will retrieve DNS server from DHCP Server.
892 //
893 Status = GetDns6ServerFromDhcp6 (
894 Instance->Service->ImageHandle,
895 Instance->Service->ControllerHandle,
896 &ServerListCount,
897 &ServerList
898 );
899 if (EFI_ERROR (Status)) {
900 goto ON_EXIT;
901 }
902
903 ASSERT(ServerList != NULL);
904
905 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
906
907 CopyMem (&Instance->SessionDnsServer.v6, &ServerList[0], sizeof (EFI_IPv6_ADDRESS));
908 } else {
909 CopyMem (&Instance->SessionDnsServer.v6, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv6_ADDRESS));
910 }
911
912 //
913 // Config UDP
914 //
915 Status = Dns6ConfigUdp (Instance, Instance->UdpIo);
916 if (EFI_ERROR (Status)) {
917 if (Instance->Dns6CfgData.DnsServerList != NULL) {
918 FreePool (Instance->Dns6CfgData.DnsServerList);
919 }
920 goto ON_EXIT;
921 }
922
923 //
924 // Add configured DNS server used by this instance to ServerList.
925 //
926 Status = AddDns6ServerIp (&mDriverData->Dns6ServerList, Instance->SessionDnsServer.v6);
927 if (EFI_ERROR (Status)) {
928 if (Instance->Dns6CfgData.DnsServerList != NULL) {
929 FreePool (Instance->Dns6CfgData.DnsServerList);
930 }
931 goto ON_EXIT;
932 }
933
934 Instance->State = DNS_STATE_CONFIGED;
935 }
936
937 ON_EXIT:
938 gBS->RestoreTPL (OldTpl);
939 return Status;
940 }
941
942 /**
943 The function is used to translate the host name to host IP address.
944 A type AAAA query is used to get the one or more IPv6 addresses for this host.
945
946 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
947 @param[in] HostName Pointer to caller-supplied buffer containing Host name to be translated.
948 This buffer contains 16 bit characters but these are translated to ASCII for use with
949 DNSv4 server and there is no requirement for driver to support non-ASCII Unicode characters.
950 @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.
951
952 @retval EFI_SUCCESS The operation completed successfully.
953 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
954 @retval EFI_INVALID_PARAMETER This is NULL.
955 Token is NULL.
956 Token.Event is.NULL
957 HostName is NULL
958 @retval EFI_NO_MAPPING There's no source address is available for use.
959 @retval EFI_NOT_STARTED This instance has not been started.
960
961 **/
962 EFI_STATUS
963 EFIAPI
964 Dns6HostNameToIp (
965 IN EFI_DNS6_PROTOCOL *This,
966 IN CHAR16 *HostName,
967 IN EFI_DNS6_COMPLETION_TOKEN *Token
968 )
969 {
970 EFI_STATUS Status;
971
972 DNS_INSTANCE *Instance;
973
974 EFI_DNS6_CONFIG_DATA *ConfigData;
975
976 UINTN Index;
977 DNS6_CACHE *Item;
978 LIST_ENTRY *Entry;
979 LIST_ENTRY *Next;
980
981 DNS6_TOKEN_ENTRY *TokenEntry;
982 NET_BUF *Packet;
983
984 EFI_TPL OldTpl;
985
986 Status = EFI_SUCCESS;
987 Item = NULL;
988 TokenEntry = NULL;
989 Packet = NULL;
990
991 //
992 // Validate the parameters
993 //
994 if ((This == NULL) || (HostName == NULL) || Token == NULL) {
995 return EFI_INVALID_PARAMETER;
996 }
997
998 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
999
1000 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);
1001
1002 ConfigData = &(Instance->Dns6CfgData);
1003
1004 Instance->MaxRetry = ConfigData->RetryCount;
1005
1006 Token->Status = EFI_NOT_READY;
1007 Token->RetryCount = 0;
1008 Token->RetryInterval = ConfigData->RetryInterval;
1009
1010 if (Instance->State != DNS_STATE_CONFIGED) {
1011 Status = EFI_NOT_STARTED;
1012 goto ON_EXIT;
1013 }
1014
1015 //
1016 // Check the MaxRetry and RetryInterval values.
1017 //
1018 if (Instance->MaxRetry == 0) {
1019 Instance->MaxRetry = DNS_DEFAULT_RETRY;
1020 }
1021
1022 if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {
1023 Token->RetryInterval = DNS_DEFAULT_TIMEOUT;
1024 }
1025
1026 //
1027 // Check cache
1028 //
1029 if (ConfigData->EnableDnsCache) {
1030 Index = 0;
1031 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
1032 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
1033 if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {
1034 Index++;
1035 }
1036 }
1037
1038 if (Index != 0) {
1039 Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));
1040 if (Token->RspData.H2AData == NULL) {
1041 Status = EFI_OUT_OF_RESOURCES;
1042 goto ON_EXIT;
1043 }
1044
1045 Token->RspData.H2AData->IpCount = (UINT32)Index;
1046 Token->RspData.H2AData->IpList = AllocatePool (sizeof (EFI_IPv6_ADDRESS) * Index);
1047 if (Token->RspData.H2AData->IpList == NULL) {
1048 if (Token->RspData.H2AData != NULL) {
1049 FreePool (Token->RspData.H2AData);
1050 }
1051
1052 Status = EFI_OUT_OF_RESOURCES;
1053 goto ON_EXIT;
1054 }
1055
1056 Index = 0;
1057 NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
1058 Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
1059 if ((UINT32)Index < Token->RspData.H2AData->IpCount && StrCmp (HostName, Item->DnsCache.HostName) == 0) {
1060 CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS));
1061 Index++;
1062 }
1063 }
1064
1065 Token->Status = EFI_SUCCESS;
1066
1067 if (Token->Event != NULL) {
1068 gBS->SignalEvent (Token->Event);
1069 DispatchDpc ();
1070 }
1071
1072 Status = Token->Status;
1073 goto ON_EXIT;
1074 }
1075 }
1076
1077 //
1078 // Construct DNS TokenEntry.
1079 //
1080 TokenEntry = AllocateZeroPool (sizeof (DNS6_TOKEN_ENTRY));
1081 if (TokenEntry == NULL) {
1082 Status = EFI_OUT_OF_RESOURCES;
1083 goto ON_EXIT;
1084 }
1085
1086 TokenEntry->PacketToLive = Token->RetryInterval;
1087 TokenEntry->QueryHostName = HostName;
1088 TokenEntry->Token = Token;
1089
1090 //
1091 // Construct DNS Query Packet.
1092 //
1093 Status = ConstructDNSQueryIp (Instance, TokenEntry->QueryHostName, DNS_TYPE_AAAA, &Packet);
1094 if (EFI_ERROR (Status)) {
1095 if (TokenEntry != NULL) {
1096 FreePool (TokenEntry);
1097 }
1098
1099 goto ON_EXIT;
1100 }
1101
1102 //
1103 // Save the token into the Dns6TxTokens map.
1104 //
1105 Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);
1106 if (EFI_ERROR (Status)) {
1107 if (TokenEntry != NULL) {
1108 FreePool (TokenEntry);
1109 }
1110
1111 NetbufFree (Packet);
1112
1113 goto ON_EXIT;
1114 }
1115
1116 //
1117 // Dns Query Ip
1118 //
1119 Status = DoDnsQuery (Instance, Packet);
1120 if (EFI_ERROR (Status)) {
1121 if (TokenEntry != NULL) {
1122 FreePool (TokenEntry);
1123 }
1124
1125 NetbufFree (Packet);
1126 }
1127
1128 ON_EXIT:
1129 gBS->RestoreTPL (OldTpl);
1130 return Status;
1131 }
1132
1133 /**
1134 The function is used to translate the host address to host name.
1135 A type PTR query is used to get the primary name of the host.
1136
1137 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
1138 @param[in] IpAddress IP address.
1139 @param[in] Token Pointer to the caller-allocated completion used token to translate host address to host name.
1140
1141 @retval EFI_SUCCESS The operation completed successfully.
1142 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
1143 @retval EFI_INVALID_PARAMETER This is NULL.
1144 Token is NULL.
1145 Token.Event is NULL.
1146 IpAddress is not valid IP address.
1147 @retval EFI_NO_MAPPING There's no source address is available for use.
1148 @retval EFI_NOT_STARTED This instance has not been started.
1149 @retval EFI_UNSUPPORTED This function is not supported.
1150
1151 **/
1152 EFI_STATUS
1153 EFIAPI
1154 Dns6IpToHostName (
1155 IN EFI_DNS6_PROTOCOL *This,
1156 IN EFI_IPv6_ADDRESS IpAddress,
1157 IN EFI_DNS6_COMPLETION_TOKEN *Token
1158 )
1159 {
1160 return EFI_UNSUPPORTED;
1161 }
1162
1163 /**
1164 This function retrieves arbitrary information from the DNS.
1165 The caller supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned.
1166 All RR content (e.g., Ttl) was returned.
1167 The caller need parse the returned RR to get required information. This function is optional.
1168
1169 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
1170 @param[in] QName Pointer to Query Name.
1171 @param[in] QType Query Type.
1172 @param[in] QClass Query Name.
1173 @param[in] Token Point to the caller-allocated completion token to retrieve arbitrary information.
1174
1175 @retval EFI_SUCCESS The operation completed successfully.
1176 @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
1177 @retval EFI_INVALID_PARAMETER This is NULL.
1178 Token is NULL.
1179 Token.Event is NULL.
1180 QName is NULL.
1181 @retval EFI_NO_MAPPING There's no source address is available for use.
1182 @retval EFI_NOT_STARTED This instance has not been started.
1183 @retval EFI_UNSUPPORTED This function is not supported. Or the requested QType is not supported
1184
1185 **/
1186 EFI_STATUS
1187 EFIAPI
1188 Dns6GeneralLookUp (
1189 IN EFI_DNS6_PROTOCOL *This,
1190 IN CHAR8 *QName,
1191 IN UINT16 QType,
1192 IN UINT16 QClass,
1193 IN EFI_DNS6_COMPLETION_TOKEN *Token
1194 )
1195 {
1196 return EFI_UNSUPPORTED;
1197 }
1198
1199 /**
1200 This function is used to add/delete/modify DNS cache entry.
1201 DNS cache can be normally dynamically updated after the DNS resolve succeeds.
1202 This function provided capability to manually add/delete/modify the DNS cache.
1203
1204 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
1205 @param[in] DeleteFlag If FALSE, this function is to add one entry to the DNS Cache.
1206 If TRUE, this function will delete matching DNS Cache entry.
1207 @param[in] Override If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.
1208 If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.
1209 @param[in] DnsCacheEntry Pointer to DNS Cache entry.
1210
1211 @retval EFI_SUCCESS The operation completed successfully.
1212 @retval EFI_INVALID_PARAMETER This is NULL.
1213 DnsCacheEntry.HostName is NULL.
1214 DnsCacheEntry.IpAddress is NULL.
1215 DnsCacheEntry.Timeout is zero.
1216 @retval EFI_ACCESS_DENIED The DNS cache entry already exists and Override is not TRUE.
1217
1218 **/
1219 EFI_STATUS
1220 EFIAPI
1221 Dns6UpdateDnsCache (
1222 IN EFI_DNS6_PROTOCOL *This,
1223 IN BOOLEAN DeleteFlag,
1224 IN BOOLEAN Override,
1225 IN EFI_DNS6_CACHE_ENTRY DnsCacheEntry
1226 )
1227 {
1228 EFI_STATUS Status;
1229 EFI_TPL OldTpl;
1230
1231 Status = EFI_SUCCESS;
1232
1233 if (DnsCacheEntry.HostName == NULL || DnsCacheEntry.IpAddress == NULL || DnsCacheEntry.Timeout == 0) {
1234 return EFI_INVALID_PARAMETER;
1235 }
1236
1237 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1238
1239 //
1240 // Update Dns6Cache here.
1241 //
1242 Status = UpdateDns6Cache (&mDriverData->Dns6CacheList, DeleteFlag, Override, DnsCacheEntry);
1243
1244 gBS->RestoreTPL (OldTpl);
1245
1246 return Status;
1247 }
1248
1249 /**
1250 This function can be used by network drivers and applications to increase the rate that data packets are moved between
1251 the communications device and the transmit and receive queues. In some systems, the periodic timer event in the managed
1252 network driver may not poll the underlying communications device fast enough to transmit and/or receive all data packets
1253 without missing incoming packets or dropping outgoing packets.
1254
1255 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
1256
1257 @retval EFI_SUCCESS Incoming or outgoing data was processed.
1258 @retval EFI_INVALID_PARAMETER This is NULL.
1259 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.
1260 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
1261 @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue.
1262 Consider increasing the polling rate.
1263
1264 **/
1265 EFI_STATUS
1266 EFIAPI
1267 Dns6Poll (
1268 IN EFI_DNS6_PROTOCOL *This
1269 )
1270 {
1271 DNS_INSTANCE *Instance;
1272 EFI_UDP6_PROTOCOL *Udp;
1273
1274 if (This == NULL) {
1275 return EFI_INVALID_PARAMETER;
1276 }
1277
1278 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);
1279
1280 if (Instance->State == DNS_STATE_UNCONFIGED) {
1281 return EFI_NOT_STARTED;
1282 } else if (Instance->State == DNS_STATE_DESTROY) {
1283 return EFI_DEVICE_ERROR;
1284 }
1285
1286 Udp = Instance->UdpIo->Protocol.Udp6;
1287
1288 return Udp->Poll (Udp);
1289 }
1290
1291 /**
1292 This function is used to abort a pending resolution request.
1293 After calling this function, Token.Status will be set to EFI_ABORTED and then Token.
1294
1295 @param[in] This Pointer to EFI_DNS6_PROTOCOL instance.
1296 @param[in] Token Pointer to a token that has been issued by EFI_DNS6_PROTOCOL.HostNameToIp(),
1297 EFI_DNS6_PROTOCOL.IpToHostName() or EFI_DNS6_PROTOCOL.GeneralLookup().
1298 If NULL, all pending tokens are aborted.
1299
1300 @retval EFI_SUCCESS Incoming or outgoing data was processed.
1301 @retval EFI_INVALID_PARAMETER This is NULL.
1302 @retval EFI_NOT_STARTED This EFI DNS Protocol instance has not been started.
1303 @retval EFI_NOT_FOUND When Token is not NULL, and the asynchronous DNS operation was not found in the transmit queue.
1304 It was either completed or was not issued by HostNameToIp(), IpToHostName() or GeneralLookup().
1305
1306 **/
1307 EFI_STATUS
1308 EFIAPI
1309 Dns6Cancel (
1310 IN EFI_DNS6_PROTOCOL *This,
1311 IN EFI_DNS6_COMPLETION_TOKEN *Token
1312 )
1313 {
1314 EFI_STATUS Status;
1315 DNS_INSTANCE *Instance;
1316 EFI_TPL OldTpl;
1317
1318 if (This == NULL) {
1319 return EFI_INVALID_PARAMETER;
1320 }
1321
1322 Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);
1323
1324 if (Instance->State == DNS_STATE_UNCONFIGED) {
1325 return EFI_NOT_STARTED;
1326 }
1327
1328 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
1329
1330 //
1331 // Cancle the tokens specified by Token for this instance.
1332 //
1333 Status = Dns6InstanceCancelToken (Instance, Token);
1334
1335 //
1336 // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
1337 //
1338 DispatchDpc ();
1339
1340 gBS->RestoreTPL (OldTpl);
1341
1342 return Status;
1343 }
1344