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 1592