/** @file
Implementation of EFI_DNS4_PROTOCOL and EFI_DNS6_PROTOCOL interfaces.

Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DnsImpl.h"

EFI_DNS4_PROTOCOL  mDns4Protocol = {
  Dns4GetModeData,
  Dns4Configure,
  Dns4HostNameToIp,
  Dns4IpToHostName,
  Dns4GeneralLookUp,
  Dns4UpdateDnsCache,
  Dns4Poll,
  Dns4Cancel
};

EFI_DNS6_PROTOCOL  mDns6Protocol = {
  Dns6GetModeData,
  Dns6Configure,
  Dns6HostNameToIp,
  Dns6IpToHostName,
  Dns6GeneralLookUp,
  Dns6UpdateDnsCache,
  Dns6Poll,
  Dns6Cancel
};

/**
  Retrieve mode data of this DNS instance.

  This function is used to retrieve DNS mode data for this DNS instance.

  @param[in]   This               Pointer to EFI_DNS4_PROTOCOL instance.
  @param[out]  DnsModeData        Point to the mode data.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_NOT_STARTED         When DnsConfigData is queried, no configuration data
                                  is available because this instance has not been
                                  configured.
  @retval EFI_INVALID_PARAMETER   This is NULL or DnsModeData is NULL.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns4GetModeData (
  IN  EFI_DNS4_PROTOCOL   *This,
  OUT EFI_DNS4_MODE_DATA  *DnsModeData
  )
{
  DNS_INSTANCE  *Instance;

  EFI_TPL  OldTpl;

  UINTN  Index;

  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Next;

  DNS4_SERVER_IP        *ServerItem;
  EFI_IPv4_ADDRESS      *ServerList;
  DNS4_CACHE            *CacheItem;
  EFI_DNS4_CACHE_ENTRY  *CacheList;
  EFI_STATUS            Status;

  ServerItem = NULL;
  ServerList = NULL;
  CacheItem  = NULL;
  CacheList  = NULL;
  Status     = EFI_SUCCESS;

  if ((This == NULL) || (DnsModeData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);
  if (Instance->State == DNS_STATE_UNCONFIGED) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  ZeroMem (DnsModeData, sizeof (EFI_DNS4_MODE_DATA));

  //
  // Get the current configuration data of this instance.
  //
  Status = Dns4CopyConfigure (&DnsModeData->DnsConfigData, &Instance->Dns4CfgData);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Get the DnsServerCount and DnsServerList
  //
  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4ServerList) {
    Index++;
  }
  DnsModeData->DnsServerCount = (UINT32)Index;
  ServerList                  = AllocatePool (sizeof (EFI_IPv4_ADDRESS) * DnsModeData->DnsServerCount);
  if (ServerList == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    Dns4CleanConfigure (&DnsModeData->DnsConfigData);
    goto ON_EXIT;
  }

  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4ServerList) {
    ServerItem = NET_LIST_USER_STRUCT (Entry, DNS4_SERVER_IP, AllServerLink);
    CopyMem (ServerList + Index, &ServerItem->Dns4ServerIp, sizeof (EFI_IPv4_ADDRESS));
    Index++;
  }
  DnsModeData->DnsServerList = ServerList;

  //
  // Get the DnsCacheCount and DnsCacheList
  //
  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
    Index++;
  }
  DnsModeData->DnsCacheCount = (UINT32)Index;
  CacheList                  = AllocatePool (sizeof (EFI_DNS4_CACHE_ENTRY) * DnsModeData->DnsCacheCount);
  if (CacheList == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    Dns4CleanConfigure (&DnsModeData->DnsConfigData);
    FreePool (ServerList);
    goto ON_EXIT;
  }

  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
    CacheItem = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
    CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS4_CACHE_ENTRY));
    Index++;
  }
  DnsModeData->DnsCacheList = CacheList;

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Configure this DNS instance.

  This function is used to configure DNS mode data for this DNS instance.

  @param[in]  This                Pointer to EFI_DNS4_PROTOCOL instance.
  @param[in]  DnsConfigData       Point to the Configuration data.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_UNSUPPORTED         The designated protocol is not supported.
  @retval EFI_INVALID_PARAMETER   This is NULL.
                                  The StationIp address provided in DnsConfigData is not a
                                  valid unicast.
                                  DnsServerList is NULL while DnsServerListCount
                                  is not ZERO.
                                  DnsServerListCount is ZERO while DnsServerList
                                  is not NULL
  @retval EFI_OUT_OF_RESOURCES    The DNS instance data or required space could not be
                                  allocated.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred. The
                                  EFI DNSv4 Protocol instance is not configured.
  @retval EFI_ALREADY_STARTED     Second call to Configure() with DnsConfigData. To
                                  reconfigure the instance the caller must call Configure()
                                  with NULL first to return driver to unconfigured state.
**/
EFI_STATUS
EFIAPI
Dns4Configure (
  IN EFI_DNS4_PROTOCOL     *This,
  IN EFI_DNS4_CONFIG_DATA  *DnsConfigData
  )
{
  EFI_STATUS    Status;
  DNS_INSTANCE  *Instance;

  EFI_TPL   OldTpl;
  IP4_ADDR  Ip;
  IP4_ADDR  Netmask;

  UINT32            ServerListCount;
  EFI_IPv4_ADDRESS  *ServerList;

  Status     = EFI_SUCCESS;
  ServerList = NULL;

  if ((This == NULL) ||
      ((DnsConfigData != NULL) && (((DnsConfigData->DnsServerListCount != 0) && (DnsConfigData->DnsServerList == NULL)) ||
                                   ((DnsConfigData->DnsServerListCount == 0) && (DnsConfigData->DnsServerList != NULL)))))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((DnsConfigData != NULL) && (DnsConfigData->Protocol != DNS_PROTOCOL_UDP)) {
    return EFI_UNSUPPORTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);

  if (DnsConfigData == NULL) {
    ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));

    //
    // Reset the Instance if ConfigData is NULL
    //
    if (!NetMapIsEmpty (&Instance->Dns4TxTokens)) {
      Dns4InstanceCancelToken (Instance, NULL);
    }

    if (Instance->UdpIo != NULL) {
      UdpIoCleanIo (Instance->UdpIo);
    }

    if (Instance->Dns4CfgData.DnsServerList != NULL) {
      FreePool (Instance->Dns4CfgData.DnsServerList);
    }

    ZeroMem (&Instance->Dns4CfgData, sizeof (EFI_DNS4_CONFIG_DATA));

    Instance->State = DNS_STATE_UNCONFIGED;
  } else {
    //
    // Configure the parameters for new operation.
    //
    CopyMem (&Ip, &DnsConfigData->StationIp, sizeof (IP4_ADDR));
    CopyMem (&Netmask, &DnsConfigData->SubnetMask, sizeof (IP4_ADDR));

    Ip      = NTOHL (Ip);
    Netmask = NTOHL (Netmask);

    if (!DnsConfigData->UseDefaultSetting &&
        ((!IP4_IS_VALID_NETMASK (Netmask) || ((Netmask != 0) && !NetIp4IsUnicast (Ip, Netmask)))))
    {
      Status = EFI_INVALID_PARAMETER;
      goto ON_EXIT;
    }

    Status = Dns4CopyConfigure (&Instance->Dns4CfgData, DnsConfigData);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    if (DnsConfigData->DnsServerListCount == 0) {
      gBS->RestoreTPL (OldTpl);

      //
      // The DNS instance will retrieve DNS server from DHCP Server
      //
      Status = GetDns4ServerFromDhcp4 (
                 Instance,
                 &ServerListCount,
                 &ServerList
                 );
      if (EFI_ERROR (Status)) {
        return Status;
      }

      ASSERT (ServerList != NULL);

      OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

      CopyMem (&Instance->SessionDnsServer.v4, &ServerList[0], sizeof (EFI_IPv4_ADDRESS));
    } else {
      CopyMem (&Instance->SessionDnsServer.v4, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv4_ADDRESS));
    }

    //
    // Config UDP
    //
    Status = Dns4ConfigUdp (Instance, Instance->UdpIo);
    if (EFI_ERROR (Status)) {
      if (Instance->Dns4CfgData.DnsServerList != NULL) {
        FreePool (Instance->Dns4CfgData.DnsServerList);
        Instance->Dns4CfgData.DnsServerList = NULL;
      }

      goto ON_EXIT;
    }

    //
    // Add configured DNS server used by this instance to ServerList.
    //
    Status = AddDns4ServerIp (&mDriverData->Dns4ServerList, Instance->SessionDnsServer.v4);
    if (EFI_ERROR (Status)) {
      if (Instance->Dns4CfgData.DnsServerList != NULL) {
        FreePool (Instance->Dns4CfgData.DnsServerList);
        Instance->Dns4CfgData.DnsServerList = NULL;
      }

      goto ON_EXIT;
    }

    Instance->State = DNS_STATE_CONFIGED;
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Host name to host address translation.

  The HostNameToIp () function is used to translate the host name to host IP address. A
  type A query is used to get the one or more IP addresses for this host.

  @param[in]  This                Pointer to EFI_DNS4_PROTOCOL instance.
  @param[in]  HostName            Host name.
  @param[in]  Token               Point to the completion token to translate host name
                                  to host address.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token.Event is NULL.
                                  HostName is NULL. HostName string is unsupported format.
  @retval EFI_NO_MAPPING          There's no source address is available for use.
  @retval EFI_NOT_STARTED         This instance has not been started.
**/
EFI_STATUS
EFIAPI
Dns4HostNameToIp (
  IN  EFI_DNS4_PROTOCOL          *This,
  IN  CHAR16                     *HostName,
  IN  EFI_DNS4_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS  Status;

  DNS_INSTANCE  *Instance;

  EFI_DNS4_CONFIG_DATA  *ConfigData;

  UINTN       Index;
  DNS4_CACHE  *Item;
  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Next;

  CHAR8  *QueryName;

  DNS4_TOKEN_ENTRY  *TokenEntry;
  NET_BUF           *Packet;

  EFI_TPL  OldTpl;

  Status     = EFI_SUCCESS;
  Item       = NULL;
  QueryName  = NULL;
  TokenEntry = NULL;
  Packet     = NULL;

  //
  // Validate the parameters
  //
  if ((This == NULL) || (HostName == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);

  ConfigData = &(Instance->Dns4CfgData);

  if (Instance->State != DNS_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  Token->Status = EFI_NOT_READY;

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryCount == 0) {
    Token->RetryCount = ConfigData->RetryCount;
  }

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryInterval == 0) {
    Token->RetryInterval = ConfigData->RetryInterval;
  }

  //
  // Minimum interval of retry is 2 second. If the retry interval is less than 2 second, then use the 2 second.
  //
  if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {
    Token->RetryInterval = DNS_DEFAULT_TIMEOUT;
  }

  //
  // Check cache
  //
  if (ConfigData->EnableDnsCache) {
    Index = 0;
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
      Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
      if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {
        Index++;
      }
    }

    if (Index != 0) {
      Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));
      if (Token->RspData.H2AData == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Token->RspData.H2AData->IpCount = (UINT32)Index;
      Token->RspData.H2AData->IpList  = AllocatePool (sizeof (EFI_IPv4_ADDRESS) * Index);
      if (Token->RspData.H2AData->IpList == NULL) {
        if (Token->RspData.H2AData != NULL) {
          FreePool (Token->RspData.H2AData);
        }

        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Index = 0;
      NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns4CacheList) {
        Item = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);
        if (((UINT32)Index < Token->RspData.H2AData->IpCount) && (StrCmp (HostName, Item->DnsCache.HostName) == 0)) {
          CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv4_ADDRESS));
          Index++;
        }
      }

      Token->Status = EFI_SUCCESS;

      if (Token->Event != NULL) {
        gBS->SignalEvent (Token->Event);
        DispatchDpc ();
      }

      Status = Token->Status;
      goto ON_EXIT;
    }
  }

  //
  // Construct DNS TokenEntry.
  //
  TokenEntry = AllocateZeroPool (sizeof (DNS4_TOKEN_ENTRY));
  if (TokenEntry == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  TokenEntry->PacketToLive  = Token->RetryInterval;
  TokenEntry->Token         = Token;
  TokenEntry->QueryHostName = AllocateZeroPool (StrSize (HostName));
  if (TokenEntry->QueryHostName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  CopyMem (TokenEntry->QueryHostName, HostName, StrSize (HostName));

  //
  // Construct QName.
  //
  QueryName = NetLibCreateDnsQName (TokenEntry->QueryHostName);
  if (QueryName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Construct DNS Query Packet.
  //
  Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_A, DNS_CLASS_INET, &Packet);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  ASSERT (Packet != NULL);

  //
  // Save the token into the Dns4TxTokens map.
  //
  Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Dns Query Ip
  //
  Status = DoDnsQuery (Instance, Packet);
  if (EFI_ERROR (Status)) {
    Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, TokenEntry);
  }

ON_EXIT:

  if (EFI_ERROR (Status)) {
    if (TokenEntry != NULL) {
      if (TokenEntry->QueryHostName != NULL) {
        FreePool (TokenEntry->QueryHostName);
      }

      FreePool (TokenEntry);
    }

    if (Packet != NULL) {
      NetbufFree (Packet);
    }
  }

  if (QueryName != NULL) {
    FreePool (QueryName);
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  IPv4 address to host name translation also known as Reverse DNS lookup.

  The IpToHostName() function is used to translate the host address to host name. A type PTR
  query is used to get the primary name of the host. Support of this function is optional.

  @param[in]  This                Pointer to EFI_DNS4_PROTOCOL instance.
  @param[in]  IpAddress           Ip Address.
  @param[in]  Token               Point to the completion token to translate host
                                  address to host name.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_UNSUPPORTED         This function is not supported.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token.Event is NULL.
                                  IpAddress is not valid IP address .
  @retval EFI_NO_MAPPING          There's no source address is available for use.
  @retval EFI_ALREADY_STARTED     This Token is being used in another DNS session.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns4IpToHostName (
  IN  EFI_DNS4_PROTOCOL          *This,
  IN  EFI_IPv4_ADDRESS           IpAddress,
  IN  EFI_DNS4_COMPLETION_TOKEN  *Token
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Retrieve arbitrary information from the DNS server.

  This GeneralLookup() function retrieves arbitrary information from the DNS. The caller
  supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. All
  RR content (e.g., TTL) was returned. The caller need parse the returned RR to get
  required information. The function is optional.

  @param[in]  This                Pointer to EFI_DNS4_PROTOCOL instance.
  @param[in]  QName               Pointer to Query Name.
  @param[in]  QType               Query Type.
  @param[in]  QClass              Query Name.
  @param[in]  Token               Point to the completion token to retrieve arbitrary
                                  information.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_UNSUPPORTED         This function is not supported. Or the requested
                                  QType is not supported
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token.Event is NULL.
                                  QName is NULL.
  @retval EFI_NO_MAPPING          There's no source address is available for use.
  @retval EFI_ALREADY_STARTED     This Token is being used in another DNS session.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns4GeneralLookUp (
  IN  EFI_DNS4_PROTOCOL          *This,
  IN  CHAR8                      *QName,
  IN  UINT16                     QType,
  IN  UINT16                     QClass,
  IN  EFI_DNS4_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS  Status;

  DNS_INSTANCE  *Instance;

  EFI_DNS4_CONFIG_DATA  *ConfigData;

  DNS4_TOKEN_ENTRY  *TokenEntry;
  NET_BUF           *Packet;

  EFI_TPL  OldTpl;

  Status     = EFI_SUCCESS;
  TokenEntry = NULL;
  Packet     = NULL;

  //
  // Validate the parameters
  //
  if ((This == NULL) || (QName == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);

  ConfigData = &(Instance->Dns4CfgData);

  if (Instance->State != DNS_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  Token->Status = EFI_NOT_READY;

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryCount == 0) {
    Token->RetryCount = ConfigData->RetryCount;
  }

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryInterval == 0) {
    Token->RetryInterval = ConfigData->RetryInterval;
  }

  //
  // Minimum interval of retry is 2 second. If the retry interval is less than 2 second, then use the 2 second.
  //
  if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {
    Token->RetryInterval = DNS_DEFAULT_TIMEOUT;
  }

  //
  // Construct DNS TokenEntry.
  //
  TokenEntry = AllocateZeroPool (sizeof (DNS4_TOKEN_ENTRY));
  if (TokenEntry == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  TokenEntry->PacketToLive  = Token->RetryInterval;
  TokenEntry->GeneralLookUp = TRUE;
  TokenEntry->Token         = Token;

  //
  // Construct DNS Query Packet.
  //
  Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);
  if (EFI_ERROR (Status)) {
    if (TokenEntry != NULL) {
      FreePool (TokenEntry);
    }

    goto ON_EXIT;
  }

  ASSERT (Packet != NULL);

  //
  // Save the token into the Dns4TxTokens map.
  //
  Status = NetMapInsertTail (&Instance->Dns4TxTokens, TokenEntry, Packet);
  if (EFI_ERROR (Status)) {
    if (TokenEntry != NULL) {
      FreePool (TokenEntry);
    }

    NetbufFree (Packet);

    goto ON_EXIT;
  }

  //
  // Dns Query Ip
  //
  Status = DoDnsQuery (Instance, Packet);
  if (EFI_ERROR (Status)) {
    Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, TokenEntry);

    if (TokenEntry != NULL) {
      FreePool (TokenEntry);
    }

    NetbufFree (Packet);
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  This function is to update the DNS Cache.

  The UpdateDnsCache() function is used to add/delete/modify DNS cache entry. DNS cache
  can be normally dynamically updated after the DNS resolve succeeds. This function
  provided capability to manually add/delete/modify the DNS cache.

  @param[in]  This                Pointer to EFI_DNS4_PROTOCOL instance.
  @param[in]  DeleteFlag          If FALSE, this function is to add one entry to the
                                  DNS Cache. If TRUE, this function will delete
                                  matching DNS Cache entry.
  @param[in]  Override            If TRUE, the matching DNS cache entry will be
                                  overwritten with the supplied parameter. If FALSE,
                                  EFI_ACCESS_DENIED will be returned if the entry to
                                  be added is already existed.
  @param[in]  DnsCacheEntry       Pointer to DNS Cache entry.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  DnsCacheEntry.HostName is NULL.
                                  DnsCacheEntry.IpAddress is NULL.
                                  DnsCacheEntry.Timeout is zero.
  @retval EFI_ACCESS_DENIED       The DNS cache entry already exists and Override is
                                  not TRUE.
**/
EFI_STATUS
EFIAPI
Dns4UpdateDnsCache (
  IN EFI_DNS4_PROTOCOL     *This,
  IN BOOLEAN               DeleteFlag,
  IN BOOLEAN               Override,
  IN EFI_DNS4_CACHE_ENTRY  DnsCacheEntry
  )
{
  EFI_STATUS  Status;
  EFI_TPL     OldTpl;

  Status = EFI_SUCCESS;

  if ((DnsCacheEntry.HostName == NULL) || (DnsCacheEntry.IpAddress == NULL) || (DnsCacheEntry.Timeout == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Update Dns4Cache here.
  //
  Status = UpdateDns4Cache (&mDriverData->Dns4CacheList, DeleteFlag, Override, DnsCacheEntry);

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Polls for incoming data packets and processes outgoing data packets.

  The Poll() function can be used by network drivers and applications to increase the
  rate that data packets are moved between the communications device and the transmit
  and receive queues.
  In some systems, the periodic timer event in the managed network driver may not poll
  the underlying communications device fast enough to transmit and/or receive all data
  packets without missing incoming packets or dropping outgoing packets. Drivers and
  applications that are experiencing packet loss should try calling the Poll()
  function more often.

  @param[in]  This                Pointer to EFI_DNS4_PROTOCOL instance.

  @retval EFI_SUCCESS             Incoming or outgoing data was processed.
  @retval EFI_NOT_STARTED         This EFI DNS Protocol instance has not been started.
  @retval EFI_INVALID_PARAMETER   This is NULL.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
  @retval EFI_TIMEOUT             Data was dropped out of the transmit and/or receive
                                  queue. Consider increasing the polling rate.
**/
EFI_STATUS
EFIAPI
Dns4Poll (
  IN EFI_DNS4_PROTOCOL  *This
  )
{
  DNS_INSTANCE       *Instance;
  EFI_UDP4_PROTOCOL  *Udp;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);

  if (Instance->State == DNS_STATE_UNCONFIGED) {
    return EFI_NOT_STARTED;
  } else if (Instance->State == DNS_STATE_DESTROY) {
    return EFI_DEVICE_ERROR;
  }

  Udp = Instance->UdpIo->Protocol.Udp4;

  return Udp->Poll (Udp);
}

/**
  Abort an asynchronous DNS operation, including translation between IP and Host, and
  general look up behavior.

  The Cancel() function is used to abort a pending resolution request. After calling
  this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be
  signaled. If the token is not in one of the queues, which usually means that the
  asynchronous operation has completed, this function will not signal the token and
  EFI_NOT_FOUND is returned.

  @param[in]  This                Pointer to EFI_DNS4_PROTOCOL instance.
  @param[in]  Token               Pointer to a token that has been issued by
                                  EFI_DNS4_PROTOCOL.HostNameToIp (),
                                  EFI_DNS4_PROTOCOL.IpToHostName() or
                                  EFI_DNS4_PROTOCOL.GeneralLookup().
                                  If NULL, all pending tokens are aborted.

  @retval EFI_SUCCESS             Incoming or outgoing data was processed.
  @retval EFI_NOT_STARTED         This EFI DNS4 Protocol instance has not been started.
  @retval EFI_INVALID_PARAMETER   This is NULL.
  @retval EFI_NOT_FOUND           When Token is not NULL, and the asynchronous DNS
                                  operation was not found in the transmit queue. It
                                  was either completed or was not issued by
                                  HostNameToIp(), IpToHostName() or GeneralLookup().
**/
EFI_STATUS
EFIAPI
Dns4Cancel (
  IN  EFI_DNS4_PROTOCOL          *This,
  IN  EFI_DNS4_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS    Status;
  DNS_INSTANCE  *Instance;
  EFI_TPL       OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL4 (This);

  if (Instance->State == DNS_STATE_UNCONFIGED) {
    return EFI_NOT_STARTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Cancel the tokens specified by Token for this instance.
  //
  Status = Dns4InstanceCancelToken (Instance, Token);

  //
  // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
  //
  DispatchDpc ();

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Retrieve mode data of this DNS instance.

  This function is used to retrieve DNS mode data for this DNS instance.

  @param[in]   This                Pointer to EFI_DNS6_PROTOCOL instance.
  @param[out]  DnsModeData         Pointer to the caller-allocated storage for the
                                   EFI_DNS6_MODE_DATA data.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_NOT_STARTED         When DnsConfigData is queried, no configuration data
                                  is available because this instance has not been
                                  configured.
  @retval EFI_INVALID_PARAMETER   This is NULL or DnsModeData is NULL.
  @retval EFI_OUT_OF_RESOURCE     Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns6GetModeData (
  IN  EFI_DNS6_PROTOCOL   *This,
  OUT EFI_DNS6_MODE_DATA  *DnsModeData
  )
{
  DNS_INSTANCE  *Instance;

  EFI_TPL  OldTpl;

  UINTN  Index;

  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Next;

  DNS6_SERVER_IP        *ServerItem;
  EFI_IPv6_ADDRESS      *ServerList;
  DNS6_CACHE            *CacheItem;
  EFI_DNS6_CACHE_ENTRY  *CacheList;
  EFI_STATUS            Status;

  ServerItem = NULL;
  ServerList = NULL;
  CacheItem  = NULL;
  CacheList  = NULL;
  Status     = EFI_SUCCESS;

  if ((This == NULL) || (DnsModeData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);
  if (Instance->State == DNS_STATE_UNCONFIGED) {
    Status =  EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  ZeroMem (DnsModeData, sizeof (EFI_DNS6_MODE_DATA));

  //
  // Get the current configuration data of this instance.
  //
  Status = Dns6CopyConfigure (&DnsModeData->DnsConfigData, &Instance->Dns6CfgData);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Get the DnsServerCount and DnsServerList
  //
  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {
    Index++;
  }
  DnsModeData->DnsServerCount = (UINT32)Index;
  ServerList                  = AllocatePool (sizeof (EFI_IPv6_ADDRESS) * DnsModeData->DnsServerCount);
  if (ServerList == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    Dns6CleanConfigure (&DnsModeData->DnsConfigData);
    goto ON_EXIT;
  }

  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6ServerList) {
    ServerItem = NET_LIST_USER_STRUCT (Entry, DNS6_SERVER_IP, AllServerLink);
    CopyMem (ServerList + Index, &ServerItem->Dns6ServerIp, sizeof (EFI_IPv6_ADDRESS));
    Index++;
  }
  DnsModeData->DnsServerList = ServerList;

  //
  // Get the DnsCacheCount and DnsCacheList
  //
  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
    Index++;
  }
  DnsModeData->DnsCacheCount = (UINT32)Index;
  CacheList                  = AllocatePool (sizeof (EFI_DNS6_CACHE_ENTRY) * DnsModeData->DnsCacheCount);
  if (CacheList == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    Dns6CleanConfigure (&DnsModeData->DnsConfigData);
    FreePool (ServerList);
    goto ON_EXIT;
  }

  Index = 0;
  NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
    CacheItem = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
    CopyMem (CacheList + Index, &CacheItem->DnsCache, sizeof (EFI_DNS6_CACHE_ENTRY));
    Index++;
  }
  DnsModeData->DnsCacheList = CacheList;

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Configure this DNS instance.

  The Configure() function is used to set and change the configuration data for this
  EFI DNSv6 Protocol driver instance. Reset the DNS instance if DnsConfigData is NULL.

  @param[in]  This                Pointer to EFI_DNS6_PROTOCOL instance.
  @param[in]  DnsConfigData       Pointer to the configuration data structure. All associated
                                  storage to be allocated and released by caller.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_INVALID_PARAMETER    This is NULL.
                                  The StationIp address provided in DnsConfigData is not zero and not a valid unicast.
                                  DnsServerList is NULL while DnsServerList Count is not ZERO.
                                  DnsServerList Count is ZERO while DnsServerList is not NULL.
  @retval EFI_OUT_OF_RESOURCES    The DNS instance data or required space could not be allocated.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred. The
                                  EFI DNSv6 Protocol instance is not configured.
  @retval EFI_UNSUPPORTED         The designated protocol is not supported.
  @retval EFI_ALREADY_STARTED     Second call to Configure() with DnsConfigData. To
                                  reconfigure the instance the caller must call Configure() with
                                  NULL first to return driver to unconfigured state.
**/
EFI_STATUS
EFIAPI
Dns6Configure (
  IN EFI_DNS6_PROTOCOL     *This,
  IN EFI_DNS6_CONFIG_DATA  *DnsConfigData
  )
{
  EFI_STATUS    Status;
  DNS_INSTANCE  *Instance;

  EFI_TPL  OldTpl;

  UINT32            ServerListCount;
  EFI_IPv6_ADDRESS  *ServerList;

  Status     = EFI_SUCCESS;
  ServerList = NULL;

  if ((This == NULL) ||
      ((DnsConfigData != NULL) && (((DnsConfigData->DnsServerCount != 0) && (DnsConfigData->DnsServerList == NULL)) ||
                                   ((DnsConfigData->DnsServerCount == 0) && (DnsConfigData->DnsServerList != NULL)))))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((DnsConfigData != NULL) && (DnsConfigData->Protocol != DNS_PROTOCOL_UDP)) {
    return EFI_UNSUPPORTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);

  if (DnsConfigData == NULL) {
    ZeroMem (&Instance->SessionDnsServer, sizeof (EFI_IP_ADDRESS));

    //
    // Reset the Instance if ConfigData is NULL
    //
    if (!NetMapIsEmpty (&Instance->Dns6TxTokens)) {
      Dns6InstanceCancelToken (Instance, NULL);
    }

    if (Instance->UdpIo != NULL) {
      UdpIoCleanIo (Instance->UdpIo);
    }

    if (Instance->Dns6CfgData.DnsServerList != NULL) {
      FreePool (Instance->Dns6CfgData.DnsServerList);
    }

    ZeroMem (&Instance->Dns6CfgData, sizeof (EFI_DNS6_CONFIG_DATA));

    Instance->State = DNS_STATE_UNCONFIGED;
  } else {
    //
    // Configure the parameters for new operation.
    //
    if (!NetIp6IsUnspecifiedAddr (&DnsConfigData->StationIp) && !NetIp6IsValidUnicast (&DnsConfigData->StationIp)) {
      Status = EFI_INVALID_PARAMETER;
      goto ON_EXIT;
    }

    Status = Dns6CopyConfigure (&Instance->Dns6CfgData, DnsConfigData);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    if (DnsConfigData->DnsServerCount == 0) {
      gBS->RestoreTPL (OldTpl);

      //
      // The DNS instance will retrieve DNS server from DHCP Server.
      //
      Status = GetDns6ServerFromDhcp6 (
                 Instance->Service->ImageHandle,
                 Instance->Service->ControllerHandle,
                 &ServerListCount,
                 &ServerList
                 );
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      ASSERT (ServerList != NULL);

      OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

      CopyMem (&Instance->SessionDnsServer.v6, &ServerList[0], sizeof (EFI_IPv6_ADDRESS));
    } else {
      CopyMem (&Instance->SessionDnsServer.v6, &DnsConfigData->DnsServerList[0], sizeof (EFI_IPv6_ADDRESS));
    }

    //
    // Config UDP
    //
    gBS->RestoreTPL (OldTpl);
    Status = Dns6ConfigUdp (Instance, Instance->UdpIo);
    OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
    if (EFI_ERROR (Status)) {
      if (Instance->Dns6CfgData.DnsServerList != NULL) {
        FreePool (Instance->Dns6CfgData.DnsServerList);
        Instance->Dns6CfgData.DnsServerList = NULL;
      }

      goto ON_EXIT;
    }

    //
    // Add configured DNS server used by this instance to ServerList.
    //
    Status = AddDns6ServerIp (&mDriverData->Dns6ServerList, Instance->SessionDnsServer.v6);
    if (EFI_ERROR (Status)) {
      if (Instance->Dns6CfgData.DnsServerList != NULL) {
        FreePool (Instance->Dns6CfgData.DnsServerList);
        Instance->Dns6CfgData.DnsServerList = NULL;
      }

      goto ON_EXIT;
    }

    Instance->State = DNS_STATE_CONFIGED;
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Host name to host address translation.

  The HostNameToIp () function is used to translate the host name to host IP address. A
  type AAAA query is used to get the one or more IPv6 addresses for this host.

  @param[in]  This                Pointer to EFI_DNS6_PROTOCOL instance.
  @param[in]  HostName            Host name.
  @param[in]  Token               Point to the completion token to translate host name
                                  to host address.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token.Event is NULL.
                                  HostName is NULL or buffer contained unsupported characters.
  @retval EFI_NO_MAPPING          There's no source address is available for use.
  @retval EFI_ALREADY_STARTED     This Token is being used in another DNS session.
  @retval EFI_NOT_STARTED         This instance has not been started.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns6HostNameToIp (
  IN  EFI_DNS6_PROTOCOL          *This,
  IN  CHAR16                     *HostName,
  IN  EFI_DNS6_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS  Status;

  DNS_INSTANCE  *Instance;

  EFI_DNS6_CONFIG_DATA  *ConfigData;

  UINTN       Index;
  DNS6_CACHE  *Item;
  LIST_ENTRY  *Entry;
  LIST_ENTRY  *Next;

  CHAR8  *QueryName;

  DNS6_TOKEN_ENTRY  *TokenEntry;
  NET_BUF           *Packet;

  EFI_TPL  OldTpl;

  Status     = EFI_SUCCESS;
  Item       = NULL;
  QueryName  = NULL;
  TokenEntry = NULL;
  Packet     = NULL;

  //
  // Validate the parameters
  //
  if ((This == NULL) || (HostName == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);

  ConfigData = &(Instance->Dns6CfgData);

  if (Instance->State != DNS_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  Token->Status = EFI_NOT_READY;

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryCount == 0) {
    Token->RetryCount = ConfigData->RetryCount;
  }

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryInterval == 0) {
    Token->RetryInterval = ConfigData->RetryInterval;
  }

  //
  // Minimum interval of retry is 2 second. If the retry interval is less than 2 second, then use the 2 second.
  //
  if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {
    Token->RetryInterval = DNS_DEFAULT_TIMEOUT;
  }

  //
  // Check cache
  //
  if (ConfigData->EnableDnsCache) {
    Index = 0;
    NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
      Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
      if (StrCmp (HostName, Item->DnsCache.HostName) == 0) {
        Index++;
      }
    }

    if (Index != 0) {
      Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));
      if (Token->RspData.H2AData == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Token->RspData.H2AData->IpCount = (UINT32)Index;
      Token->RspData.H2AData->IpList  = AllocatePool (sizeof (EFI_IPv6_ADDRESS) * Index);
      if (Token->RspData.H2AData->IpList == NULL) {
        if (Token->RspData.H2AData != NULL) {
          FreePool (Token->RspData.H2AData);
        }

        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      Index = 0;
      NET_LIST_FOR_EACH_SAFE (Entry, Next, &mDriverData->Dns6CacheList) {
        Item = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);
        if (((UINT32)Index < Token->RspData.H2AData->IpCount) && (StrCmp (HostName, Item->DnsCache.HostName) == 0)) {
          CopyMem ((Token->RspData.H2AData->IpList) + Index, Item->DnsCache.IpAddress, sizeof (EFI_IPv6_ADDRESS));
          Index++;
        }
      }

      Token->Status = EFI_SUCCESS;

      if (Token->Event != NULL) {
        gBS->SignalEvent (Token->Event);
        DispatchDpc ();
      }

      Status = Token->Status;
      goto ON_EXIT;
    }
  }

  //
  // Construct DNS TokenEntry.
  //
  TokenEntry = AllocateZeroPool (sizeof (DNS6_TOKEN_ENTRY));
  if (TokenEntry == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  TokenEntry->PacketToLive  = Token->RetryInterval;
  TokenEntry->Token         = Token;
  TokenEntry->QueryHostName = AllocateZeroPool (StrSize (HostName));
  if (TokenEntry->QueryHostName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  CopyMem (TokenEntry->QueryHostName, HostName, StrSize (HostName));

  //
  // Construct QName.
  //
  QueryName = NetLibCreateDnsQName (TokenEntry->QueryHostName);
  if (QueryName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Construct DNS Query Packet.
  //
  Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_AAAA, DNS_CLASS_INET, &Packet);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  ASSERT (Packet != NULL);

  //
  // Save the token into the Dns6TxTokens map.
  //
  Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Dns Query Ip
  //
  Status = DoDnsQuery (Instance, Packet);
  if (EFI_ERROR (Status)) {
    Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, TokenEntry);
  }

ON_EXIT:

  if (EFI_ERROR (Status)) {
    if (TokenEntry != NULL) {
      if (TokenEntry->QueryHostName != NULL) {
        FreePool (TokenEntry->QueryHostName);
      }

      FreePool (TokenEntry);
    }

    if (Packet != NULL) {
      NetbufFree (Packet);
    }
  }

  if (QueryName != NULL) {
    FreePool (QueryName);
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Host address to host name translation.

  The IpToHostName () function is used to translate the host address to host name. A
  type PTR query is used to get the primary name of the host. Implementation can choose
  to support this function or not.

  @param[in]  This                Pointer to EFI_DNS6_PROTOCOL instance.
  @param[in]  IpAddress           Ip Address.
  @param[in]  Token               Point to the completion token to translate host
                                  address to host name.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_UNSUPPORTED         This function is not supported.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token.Event is NULL.
                                  IpAddress is not valid IP address.
  @retval EFI_NO_MAPPING          There's no source address is available for use.
  @retval EFI_NOT_STARTED         This instance has not been started.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns6IpToHostName (
  IN  EFI_DNS6_PROTOCOL          *This,
  IN  EFI_IPv6_ADDRESS           IpAddress,
  IN  EFI_DNS6_COMPLETION_TOKEN  *Token
  )
{
  return EFI_UNSUPPORTED;
}

/**
  This function provides capability to retrieve arbitrary information from the DNS
  server.

  This GeneralLookup() function retrieves arbitrary information from the DNS. The caller
  supplies a QNAME, QTYPE, and QCLASS, and all of the matching RRs are returned. All
  RR content (e.g., TTL) was returned. The caller need parse the returned RR to get
  required information. The function is optional. Implementation can choose to support
  it or not.

  @param[in]  This                Pointer to EFI_DNS6_PROTOCOL instance.
  @param[in]  QName               Pointer to Query Name.
  @param[in]  QType               Query Type.
  @param[in]  QClass              Query Name.
  @param[in]  Token               Point to the completion token to retrieve arbitrary
                                  information.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_UNSUPPORTED         This function is not supported. Or the requested
                                  QType is not supported
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token.Event is NULL.
                                  QName is NULL.
  @retval EFI_NO_MAPPING          There's no source address is available for use.
  @retval EFI_NOT_STARTED         This instance has not been started.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns6GeneralLookUp (
  IN  EFI_DNS6_PROTOCOL          *This,
  IN  CHAR8                      *QName,
  IN  UINT16                     QType,
  IN  UINT16                     QClass,
  IN  EFI_DNS6_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS  Status;

  DNS_INSTANCE  *Instance;

  EFI_DNS6_CONFIG_DATA  *ConfigData;

  DNS6_TOKEN_ENTRY  *TokenEntry;
  NET_BUF           *Packet;

  EFI_TPL  OldTpl;

  Status     = EFI_SUCCESS;
  TokenEntry = NULL;
  Packet     = NULL;

  //
  // Validate the parameters
  //
  if ((This == NULL) || (QName == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);

  ConfigData = &(Instance->Dns6CfgData);

  if (Instance->State != DNS_STATE_CONFIGED) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  Token->Status = EFI_NOT_READY;

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryCount == 0) {
    Token->RetryCount = ConfigData->RetryCount;
  }

  //
  // If zero, use the parameter configured through Dns.Configure() interface.
  //
  if (Token->RetryInterval == 0) {
    Token->RetryInterval = ConfigData->RetryInterval;
  }

  //
  // Minimum interval of retry is 2 second. If the retry interval is less than 2 second, then use the 2 second.
  //
  if (Token->RetryInterval < DNS_DEFAULT_TIMEOUT) {
    Token->RetryInterval = DNS_DEFAULT_TIMEOUT;
  }

  //
  // Construct DNS TokenEntry.
  //
  TokenEntry = AllocateZeroPool (sizeof (DNS6_TOKEN_ENTRY));
  if (TokenEntry == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  TokenEntry->PacketToLive  = Token->RetryInterval;
  TokenEntry->GeneralLookUp = TRUE;
  TokenEntry->Token         = Token;

  //
  // Construct DNS Query Packet.
  //
  Status = ConstructDNSQuery (Instance, QName, QType, QClass, &Packet);
  if (EFI_ERROR (Status)) {
    if (TokenEntry != NULL) {
      FreePool (TokenEntry);
    }

    goto ON_EXIT;
  }

  ASSERT (Packet != NULL);

  //
  // Save the token into the Dns6TxTokens map.
  //
  Status = NetMapInsertTail (&Instance->Dns6TxTokens, TokenEntry, Packet);
  if (EFI_ERROR (Status)) {
    if (TokenEntry != NULL) {
      FreePool (TokenEntry);
    }

    NetbufFree (Packet);

    goto ON_EXIT;
  }

  //
  // Dns Query Ip
  //
  Status = DoDnsQuery (Instance, Packet);
  if (EFI_ERROR (Status)) {
    Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, TokenEntry);

    if (TokenEntry != NULL) {
      FreePool (TokenEntry);
    }

    NetbufFree (Packet);
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  This function is to update the DNS Cache.

  The UpdateDnsCache() function is used to add/delete/modify DNS cache entry. DNS cache
  can be normally dynamically updated after the DNS resolve succeeds. This function
  provided capability to manually add/delete/modify the DNS cache.

  @param[in]  This                Pointer to EFI_DNS6_PROTOCOL instance.
  @param[in]  DeleteFlag          If FALSE, this function is to add one entry to the
                                  DNS Cache. If TRUE, this function will delete
                                  matching DNS Cache entry.
  @param[in]  Override            If TRUE, the matching DNS cache entry will be
                                  overwritten with the supplied parameter. If FALSE,
                                  EFI_ACCESS_DENIED will be returned if the entry to
                                  be added is already existed.
  @param[in]  DnsCacheEntry       Pointer to DNS Cache entry.

  @retval EFI_SUCCESS             The operation completed successfully.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  DnsCacheEntry.HostName is NULL.
                                  DnsCacheEntry.IpAddress is NULL.
                                  DnsCacheEntry.Timeout is zero.
  @retval EFI_ACCESS_DENIED       The DNS cache entry already exists and Override is
                                  not TRUE.
  @retval EFI_OUT_OF_RESOURCE     Failed to allocate needed resources.
**/
EFI_STATUS
EFIAPI
Dns6UpdateDnsCache (
  IN EFI_DNS6_PROTOCOL     *This,
  IN BOOLEAN               DeleteFlag,
  IN BOOLEAN               Override,
  IN EFI_DNS6_CACHE_ENTRY  DnsCacheEntry
  )
{
  EFI_STATUS  Status;
  EFI_TPL     OldTpl;

  Status = EFI_SUCCESS;

  if ((DnsCacheEntry.HostName == NULL) || (DnsCacheEntry.IpAddress == NULL) || (DnsCacheEntry.Timeout == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Update Dns6Cache here.
  //
  Status = UpdateDns6Cache (&mDriverData->Dns6CacheList, DeleteFlag, Override, DnsCacheEntry);

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Polls for incoming data packets and processes outgoing data packets.

  The Poll() function can be used by network drivers and applications to increase the
  rate that data packets are moved between the communications device and the transmit
  and receive queues.

  In some systems, the periodic timer event in the managed network driver may not poll
  the underlying communications device fast enough to transmit and/or receive all data
  packets without missing incoming packets or dropping outgoing packets. Drivers and
  applications that are experiencing packet loss should try calling the Poll()
  function more often.

  @param[in]  This                Pointer to EFI_DNS6_PROTOCOL instance.

  @retval EFI_SUCCESS             Incoming or outgoing data was processed.
  @retval EFI_NOT_STARTED         This EFI DNS Protocol instance has not been started.
  @retval EFI_INVALID_PARAMETER   This is NULL.
  @retval EFI_NO_MAPPING          There is no source address is available for use.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
  @retval EFI_TIMEOUT             Data was dropped out of the transmit and/or receive
                                  queue. Consider increasing the polling rate.
**/
EFI_STATUS
EFIAPI
Dns6Poll (
  IN EFI_DNS6_PROTOCOL  *This
  )
{
  DNS_INSTANCE       *Instance;
  EFI_UDP6_PROTOCOL  *Udp;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);

  if (Instance->State == DNS_STATE_UNCONFIGED) {
    return EFI_NOT_STARTED;
  } else if (Instance->State == DNS_STATE_DESTROY) {
    return EFI_DEVICE_ERROR;
  }

  Udp = Instance->UdpIo->Protocol.Udp6;

  return Udp->Poll (Udp);
}

/**
  Abort an asynchronous DNS operation, including translation between IP and Host, and
  general look up behavior.

  The Cancel() function is used to abort a pending resolution request. After calling
  this function, Token.Status will be set to EFI_ABORTED and then Token.Event will be
  signaled. If the token is not in one of the queues, which usually means that the
  asynchronous operation has completed, this function will not signal the token and
  EFI_NOT_FOUND is returned.

  @param[in]  This                Pointer to EFI_DNS6_PROTOCOL instance.
  @param[in]  Token               Pointer to a token that has been issued by
                                  EFI_DNS6_PROTOCOL.HostNameToIp (),
                                  EFI_DNS6_PROTOCOL.IpToHostName() or
                                  EFI_DNS6_PROTOCOL.GeneralLookup().
                                  If NULL, all pending tokens are aborted.

  @retval EFI_SUCCESS             Incoming or outgoing data was processed.
  @retval EFI_NOT_STARTED         This EFI DNS6 Protocol instance has not been started.
  @retval EFI_INVALID_PARAMETER   This is NULL.
  @retval EFI_NO_MAPPING          There's no source address is available for use.
  @retval EFI_NOT_FOUND           When Token is not NULL, and the asynchronous DNS
                                  operation was not found in the transmit queue. It
                                  was either completed or was not issued by
                                  HostNameToIp(), IpToHostName() or GeneralLookup().
**/
EFI_STATUS
EFIAPI
Dns6Cancel (
  IN  EFI_DNS6_PROTOCOL          *This,
  IN  EFI_DNS6_COMPLETION_TOKEN  *Token
  )
{
  EFI_STATUS    Status;
  DNS_INSTANCE  *Instance;
  EFI_TPL       OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = DNS_INSTANCE_FROM_THIS_PROTOCOL6 (This);

  if (Instance->State == DNS_STATE_UNCONFIGED) {
    return EFI_NOT_STARTED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Cancel the tokens specified by Token for this instance.
  //
  Status = Dns6InstanceCancelToken (Instance, Token);

  //
  // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
  //
  DispatchDpc ();

  gBS->RestoreTPL (OldTpl);

  return Status;
}
