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