]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/DnsDxe/DnsImpl.c
NetworkPkg: Clean up source files
[mirror_edk2.git] / NetworkPkg / DnsDxe / DnsImpl.c
index 42d51f0ed7a2c2972e53b231bd5b3540f047a3be..89ea755cb2b95b094f81e76e352cb771e18a0e44 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 DnsDxe support functions implementation.\r
-  \r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+\r
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -45,7 +45,7 @@ Dns4RemoveTokenEntry (
 \r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -57,7 +57,7 @@ Dns4RemoveTokenEntry (
 \r
   @retval EFI_SUCCESS           Remove TokenEntry from TokenMap sucessfully.\r
   @retval EFI_NOT_FOUND         TokenEntry is not found in TokenMap.\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 Dns6RemoveTokenEntry (\r
@@ -80,7 +80,7 @@ Dns6RemoveTokenEntry (
 \r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -219,24 +219,24 @@ EFI_STATUS
 EFIAPI\r
 GetDns4TokenEntry (\r
   IN     NET_MAP                   *TokensMap,\r
-  IN     EFI_DNS4_COMPLETION_TOKEN *Token, \r
+  IN     EFI_DNS4_COMPLETION_TOKEN *Token,\r
      OUT DNS4_TOKEN_ENTRY          **TokenEntry\r
   )\r
 {\r
   LIST_ENTRY              *Entry;\r
-  \r
+\r
   NET_MAP_ITEM            *Item;\r
-  \r
+\r
   NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
     Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-    *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);  \r
+    *TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
     if ((*TokenEntry)->Token == Token) {\r
       return EFI_SUCCESS;\r
     }\r
   }\r
-  \r
+\r
   *TokenEntry = NULL;\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -255,24 +255,24 @@ EFI_STATUS
 EFIAPI\r
 GetDns6TokenEntry (\r
   IN     NET_MAP                   *TokensMap,\r
-  IN     EFI_DNS6_COMPLETION_TOKEN *Token, \r
+  IN     EFI_DNS6_COMPLETION_TOKEN *Token,\r
      OUT DNS6_TOKEN_ENTRY          **TokenEntry\r
   )\r
 {\r
   LIST_ENTRY              *Entry;\r
-  \r
+\r
   NET_MAP_ITEM            *Item;\r
-  \r
+\r
   NET_LIST_FOR_EACH (Entry, &TokensMap->Used) {\r
     Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-    *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);  \r
+    *TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);\r
     if ((*TokenEntry)->Token == Token) {\r
       return EFI_SUCCESS;\r
     }\r
   }\r
-  \r
+\r
   *TokenEntry =NULL;\r
-  \r
+\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
@@ -325,7 +325,7 @@ Dns4InstanceCancelToken (
   }\r
 \r
   ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns4TxTokens)));\r
-  \r
+\r
   if (NetMapIsEmpty (&Instance->Dns4TxTokens)) {\r
     Instance->UdpIo->Protocol.Udp4->Cancel (Instance->UdpIo->Protocol.Udp4, &Instance->UdpIo->RecvRequest->Token.Udp4);\r
   }\r
@@ -382,7 +382,7 @@ Dns6InstanceCancelToken (
   }\r
 \r
   ASSERT ((TokenEntry != NULL) || (0 == NetMapGetCount (&Instance->Dns6TxTokens)));\r
-  \r
+\r
   if (NetMapIsEmpty (&Instance->Dns6TxTokens)) {\r
     Instance->UdpIo->Protocol.Udp6->Cancel (Instance->UdpIo->Protocol.Udp6, &Instance->UdpIo->RecvRequest->Token.Udp6);\r
   }\r
@@ -526,9 +526,9 @@ DnsDummyExtFree (
 \r
 /**\r
   Poll the UDP to get the IP4 default address, which may be retrieved\r
-  by DHCP. \r
-  \r
-  The default time out value is 5 seconds. If IP has retrieved the default address, \r
+  by DHCP.\r
+\r
+  The default time out value is 5 seconds. If IP has retrieved the default address,\r
   the UDP is reconfigured.\r
 \r
   @param  Instance               The DNS instance\r
@@ -565,7 +565,7 @@ Dns4GetMapping (
     return FALSE;\r
   }\r
 \r
-  while (!EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
+  while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
     Udp->Poll (Udp);\r
 \r
     if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip4Mode, NULL, NULL)) &&\r
@@ -615,14 +615,40 @@ Dns6GetMapping (
     return FALSE;\r
   }\r
 \r
-  while (!EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
+  while (EFI_ERROR (gBS->CheckEvent (Service->TimerToGetMap))) {\r
     Udp->Poll (Udp);\r
 \r
-    if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL)) &&\r
-        Ip6Mode.IsConfigured) {\r
+    if (!EFI_ERROR (Udp->GetModeData (Udp, NULL, &Ip6Mode, NULL, NULL))) {\r
+      if (Ip6Mode.AddressList != NULL) {\r
+        FreePool (Ip6Mode.AddressList);\r
+      }\r
 \r
-      Udp->Configure (Udp, NULL);\r
-      return (BOOLEAN) (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS);\r
+      if (Ip6Mode.GroupTable != NULL) {\r
+        FreePool (Ip6Mode.GroupTable);\r
+      }\r
+\r
+      if (Ip6Mode.RouteTable != NULL) {\r
+        FreePool (Ip6Mode.RouteTable);\r
+      }\r
+\r
+      if (Ip6Mode.NeighborCache != NULL) {\r
+        FreePool (Ip6Mode.NeighborCache);\r
+      }\r
+\r
+      if (Ip6Mode.PrefixTable != NULL) {\r
+        FreePool (Ip6Mode.PrefixTable);\r
+      }\r
+\r
+      if (Ip6Mode.IcmpTypeList != NULL) {\r
+        FreePool (Ip6Mode.IcmpTypeList);\r
+      }\r
+\r
+      if (!Ip6Mode.IsStarted || Ip6Mode.IsConfigured) {\r
+        Udp->Configure (Udp, NULL);\r
+        if (Udp->Configure (Udp, UdpCfgData) == EFI_SUCCESS) {\r
+          return TRUE;\r
+        }\r
+      }\r
     }\r
   }\r
 \r
@@ -631,10 +657,10 @@ Dns6GetMapping (
 \r
 /**\r
   Configure the UDP.\r
-  \r
+\r
   @param  Instance               The DNS session\r
   @param  UdpIo                  The UDP_IO instance\r
-  \r
+\r
   @retval EFI_SUCCESS            The UDP is successfully configured for the\r
                                  session.\r
 \r
@@ -673,13 +699,13 @@ Dns4ConfigUdp (
   if ((Status == EFI_NO_MAPPING) && Dns4GetMapping (Instance, UdpIo, &UdpConfig)) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return Status;\r
 }\r
 \r
 /**\r
   Configure the UDP.\r
-  \r
+\r
   @param  Instance               The DNS session\r
   @param  UdpIo                  The UDP_IO instance\r
 \r
@@ -716,24 +742,24 @@ Dns6ConfigUdp (
   if ((Status == EFI_NO_MAPPING) && Dns6GetMapping (Instance, UdpIo, &UdpConfig)) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   return Status;\r
 }\r
 \r
 /**\r
   Update Dns4 cache to shared list of caches of all DNSv4 instances.\r
-  \r
+\r
   @param  Dns4CacheList      All Dns4 cache list.\r
-  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache. \r
-                             If TRUE, this function will delete matching DNS Cache entry. \r
-  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
+  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache.\r
+                             If TRUE, this function will delete matching DNS Cache entry.\r
+  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.\r
                              If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
   @param  DnsCacheEntry      Entry Pointer to DNS Cache entry.\r
 \r
   @retval EFI_SUCCESS        Update Dns4 cache successfully.\r
-  @retval Others             Failed to update Dns4 cache.   \r
-  \r
-**/ \r
+  @retval Others             Failed to update Dns4 cache.\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 UpdateDns4Cache (\r
@@ -743,14 +769,14 @@ UpdateDns4Cache (
   IN EFI_DNS4_CACHE_ENTRY   DnsCacheEntry\r
   )\r
 {\r
-  DNS4_CACHE    *NewDnsCache;  \r
+  DNS4_CACHE    *NewDnsCache;\r
   DNS4_CACHE    *Item;\r
   LIST_ENTRY    *Entry;\r
   LIST_ENTRY    *Next;\r
 \r
   NewDnsCache = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching EFI_DNS_CACHE_ENTRY\r
   //\r
@@ -766,14 +792,18 @@ UpdateDns4Cache (
         // Delete matching DNS Cache entry\r
         //\r
         RemoveEntryList (&Item->AllCacheLink);\r
-        \r
+\r
+        FreePool (Item->DnsCache.HostName);\r
+        FreePool (Item->DnsCache.IpAddress);\r
+        FreePool (Item);\r
+\r
         return EFI_SUCCESS;\r
       } else if (Override) {\r
         //\r
         // Update this one\r
         //\r
         Item->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-        \r
+\r
         return EFI_SUCCESS;\r
       }else {\r
         return EFI_ACCESS_DENIED;\r
@@ -785,46 +815,49 @@ UpdateDns4Cache (
   // Add new one\r
   //\r
   NewDnsCache = AllocatePool (sizeof (DNS4_CACHE));\r
-  if (NewDnsCache == NULL) { \r
+  if (NewDnsCache == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewDnsCache->AllCacheLink);\r
-   \r
+\r
   NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
-  if (NewDnsCache->DnsCache.HostName == NULL) { \r
+  if (NewDnsCache->DnsCache.HostName == NULL) {\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));\r
 \r
   NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv4_ADDRESS));\r
-  if (NewDnsCache->DnsCache.IpAddress == NULL) { \r
+  if (NewDnsCache->DnsCache.IpAddress == NULL) {\r
+    FreePool (NewDnsCache->DnsCache.HostName);\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv4_ADDRESS));\r
 \r
   NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-  \r
+\r
   InsertTailList (Dns4CacheList, &NewDnsCache->AllCacheLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Update Dns6 cache to shared list of caches of all DNSv6 instances. \r
+  Update Dns6 cache to shared list of caches of all DNSv6 instances.\r
 \r
   @param  Dns6CacheList      All Dns6 cache list.\r
-  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache. \r
-                             If TRUE, this function will delete matching DNS Cache entry. \r
-  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter. \r
+  @param  DeleteFlag         If FALSE, this function is to add one entry to the DNS Cache.\r
+                             If TRUE, this function will delete matching DNS Cache entry.\r
+  @param  Override           If TRUE, the matching DNS cache entry will be overwritten with the supplied parameter.\r
                              If FALSE, EFI_ACCESS_DENIED will be returned if the entry to be added is already exists.\r
   @param  DnsCacheEntry      Entry Pointer to DNS Cache entry.\r
-  \r
+\r
   @retval EFI_SUCCESS        Update Dns6 cache successfully.\r
   @retval Others             Failed to update Dns6 cache.\r
-**/ \r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 UpdateDns6Cache (\r
@@ -834,14 +867,14 @@ UpdateDns6Cache (
   IN EFI_DNS6_CACHE_ENTRY   DnsCacheEntry\r
   )\r
 {\r
-  DNS6_CACHE    *NewDnsCache;  \r
+  DNS6_CACHE    *NewDnsCache;\r
   DNS6_CACHE    *Item;\r
   LIST_ENTRY    *Entry;\r
   LIST_ENTRY    *Next;\r
 \r
   NewDnsCache = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching EFI_DNS_CACHE_ENTRY\r
   //\r
@@ -857,14 +890,18 @@ UpdateDns6Cache (
         // Delete matching DNS Cache entry\r
         //\r
         RemoveEntryList (&Item->AllCacheLink);\r
-        \r
+\r
+        FreePool (Item->DnsCache.HostName);\r
+        FreePool (Item->DnsCache.IpAddress);\r
+        FreePool (Item);\r
+\r
         return EFI_SUCCESS;\r
       } else if (Override) {\r
         //\r
         // Update this one\r
         //\r
         Item->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-        \r
+\r
         return EFI_SUCCESS;\r
       }else {\r
         return EFI_ACCESS_DENIED;\r
@@ -876,43 +913,46 @@ UpdateDns6Cache (
   // Add new one\r
   //\r
   NewDnsCache = AllocatePool (sizeof (DNS6_CACHE));\r
-  if (NewDnsCache == NULL) { \r
+  if (NewDnsCache == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewDnsCache->AllCacheLink);\r
-   \r
+\r
   NewDnsCache->DnsCache.HostName = AllocatePool (StrSize (DnsCacheEntry.HostName));\r
-  if (NewDnsCache->DnsCache.HostName == NULL) { \r
+  if (NewDnsCache->DnsCache.HostName == NULL) {\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   CopyMem (NewDnsCache->DnsCache.HostName, DnsCacheEntry.HostName, StrSize (DnsCacheEntry.HostName));\r
 \r
   NewDnsCache->DnsCache.IpAddress = AllocatePool (sizeof (EFI_IPv6_ADDRESS));\r
-  if (NewDnsCache->DnsCache.IpAddress == NULL) { \r
+  if (NewDnsCache->DnsCache.IpAddress == NULL) {\r
+    FreePool (NewDnsCache->DnsCache.HostName);\r
+    FreePool (NewDnsCache);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   CopyMem (NewDnsCache->DnsCache.IpAddress, DnsCacheEntry.IpAddress, sizeof (EFI_IPv6_ADDRESS));\r
 \r
   NewDnsCache->DnsCache.Timeout = DnsCacheEntry.Timeout;\r
-  \r
+\r
   InsertTailList (Dns6CacheList, &NewDnsCache->AllCacheLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server. \r
+  Add Dns4 ServerIp to common list of addresses of all configured DNSv4 server.\r
 \r
-  @param  Dns4ServerList    Common list of addresses of all configured DNSv4 server.  \r
-  @param  ServerIp          DNS server Ip.  \r
+  @param  Dns4ServerList    Common list of addresses of all configured DNSv4 server.\r
+  @param  ServerIp          DNS server Ip.\r
 \r
   @retval EFI_SUCCESS       Add Dns4 ServerIp to common list successfully.\r
   @retval Others            Failed to add Dns4 ServerIp to common list.\r
-  \r
-**/ \r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 AddDns4ServerIp (\r
@@ -920,14 +960,14 @@ AddDns4ServerIp (
   IN EFI_IPv4_ADDRESS           ServerIp\r
   )\r
 {\r
-  DNS4_SERVER_IP    *NewServerIp;  \r
+  DNS4_SERVER_IP    *NewServerIp;\r
   DNS4_SERVER_IP    *Item;\r
   LIST_ENTRY        *Entry;\r
   LIST_ENTRY        *Next;\r
 \r
   NewServerIp = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching ServerIp\r
   //\r
@@ -936,7 +976,7 @@ AddDns4ServerIp (
     if (CompareMem (&Item->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS)) == 0) {\r
       //\r
       // Already done.\r
-      // \r
+      //\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -945,29 +985,29 @@ AddDns4ServerIp (
   // Add new one\r
   //\r
   NewServerIp = AllocatePool (sizeof (DNS4_SERVER_IP));\r
-  if (NewServerIp == NULL) { \r
+  if (NewServerIp == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewServerIp->AllServerLink);\r
-   \r
+\r
   CopyMem (&NewServerIp->Dns4ServerIp, &ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
-  \r
+\r
   InsertTailList (Dns4ServerList, &NewServerIp->AllServerLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server. \r
+  Add Dns6 ServerIp to common list of addresses of all configured DNSv6 server.\r
 \r
-  @param  Dns6ServerList    Common list of addresses of all configured DNSv6 server.  \r
-  @param  ServerIp          DNS server Ip.  \r
+  @param  Dns6ServerList    Common list of addresses of all configured DNSv6 server.\r
+  @param  ServerIp          DNS server Ip.\r
 \r
   @retval EFI_SUCCESS       Add Dns6 ServerIp to common list successfully.\r
   @retval Others            Failed to add Dns6 ServerIp to common list.\r
-  \r
-**/ \r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 AddDns6ServerIp (\r
@@ -975,14 +1015,14 @@ AddDns6ServerIp (
   IN EFI_IPv6_ADDRESS           ServerIp\r
   )\r
 {\r
-  DNS6_SERVER_IP    *NewServerIp;  \r
+  DNS6_SERVER_IP    *NewServerIp;\r
   DNS6_SERVER_IP    *Item;\r
   LIST_ENTRY        *Entry;\r
   LIST_ENTRY        *Next;\r
 \r
   NewServerIp = NULL;\r
   Item        = NULL;\r
-  \r
+\r
   //\r
   // Search the database for the matching ServerIp\r
   //\r
@@ -991,7 +1031,7 @@ AddDns6ServerIp (
     if (CompareMem (&Item->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS)) == 0) {\r
       //\r
       // Already done.\r
-      // \r
+      //\r
       return EFI_SUCCESS;\r
     }\r
   }\r
@@ -1000,36 +1040,38 @@ AddDns6ServerIp (
   // Add new one\r
   //\r
   NewServerIp = AllocatePool (sizeof (DNS6_SERVER_IP));\r
-  if (NewServerIp == NULL) { \r
+  if (NewServerIp == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   InitializeListHead (&NewServerIp->AllServerLink);\r
-   \r
+\r
   CopyMem (&NewServerIp->Dns6ServerIp, &ServerIp, sizeof (EFI_IPv6_ADDRESS));\r
-  \r
+\r
   InsertTailList (Dns6ServerList, &NewServerIp->AllServerLink);\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Find out whether the response is valid or invalid.\r
 \r
-  @param  TokensMap       All DNS transmittal Tokens entry.  \r
-  @param  Identification  Identification for queried packet.  \r
+  @param  TokensMap       All DNS transmittal Tokens entry.\r
+  @param  Identification  Identification for queried packet.\r
   @param  Type            Type for queried packet.\r
+  @param  Class           Class for queried packet.\r
   @param  Item            Return corresponding Token entry.\r
 \r
   @retval TRUE            The response is valid.\r
   @retval FALSE           The response is invalid.\r
-  \r
-**/ \r
+\r
+**/\r
 BOOLEAN\r
 IsValidDnsResponse (\r
   IN     NET_MAP      *TokensMap,\r
   IN     UINT16       Identification,\r
   IN     UINT16       Type,\r
+  IN     UINT16       Class,\r
      OUT NET_MAP_ITEM **Item\r
   )\r
 {\r
@@ -1045,7 +1087,7 @@ IsValidDnsResponse (
     *Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
     Packet = (NET_BUF *) ((*Item)->Value);\r
     if (Packet == NULL){\r
-      \r
+\r
       continue;\r
     } else {\r
       TxString = NetbufGetByte (Packet, 0, NULL);\r
@@ -1054,17 +1096,16 @@ IsValidDnsResponse (
       QueryName = (CHAR8 *) (TxString + sizeof (*DnsHeader));\r
       QuerySection = (DNS_QUERY_SECTION *) (QueryName + AsciiStrLen (QueryName) + 1);\r
 \r
-      DnsHeader->Identification = NTOHS (DnsHeader->Identification);\r
-      QuerySection->Type = NTOHS (QuerySection->Type);\r
-        \r
-      if (DnsHeader->Identification == Identification && QuerySection->Type == Type) {\r
+      if (NTOHS (DnsHeader->Identification) == Identification &&\r
+          NTOHS (QuerySection->Type) == Type &&\r
+          NTOHS (QuerySection->Class) == Class) {\r
         return TRUE;\r
       }\r
-    } \r
+    }\r
   }\r
-  \r
-  *Item =NULL;\r
-  \r
+\r
+  *Item = NULL;\r
+\r
   return FALSE;\r
 }\r
 \r
@@ -1073,12 +1114,12 @@ IsValidDnsResponse (
 \r
   @param  Instance              The DNS instance\r
   @param  RxString              Received buffer.\r
-  @param  Completed             Flag to indicate that Dns response is valid. \r
-  \r
+  @param  Completed             Flag to indicate that Dns response is valid.\r
+\r
   @retval EFI_SUCCESS           Parse Dns Response successfully.\r
   @retval Others                Failed to parse Dns Response.\r
-  \r
-**/ \r
+\r
+**/\r
 EFI_STATUS\r
 ParseDnsResponse (\r
   IN OUT DNS_INSTANCE              *Instance,\r
@@ -1087,10 +1128,10 @@ ParseDnsResponse (
   )\r
 {\r
   DNS_HEADER            *DnsHeader;\r
-  \r
+\r
   CHAR8                 *QueryName;\r
   DNS_QUERY_SECTION     *QuerySection;\r
-  \r
+\r
   CHAR8                 *AnswerName;\r
   DNS_ANSWER_SECTION    *AnswerSection;\r
   UINT8                 *AnswerData;\r
@@ -1098,41 +1139,51 @@ ParseDnsResponse (
   NET_MAP_ITEM          *Item;\r
   DNS4_TOKEN_ENTRY      *Dns4TokenEntry;\r
   DNS6_TOKEN_ENTRY      *Dns6TokenEntry;\r
-  \r
+\r
   UINT32                IpCount;\r
+  UINT32                RRCount;\r
   UINT32                AnswerSectionNum;\r
-  \r
+  UINT32                CNameTtl;\r
+\r
   EFI_IPv4_ADDRESS      *HostAddr4;\r
   EFI_IPv6_ADDRESS      *HostAddr6;\r
 \r
   EFI_DNS4_CACHE_ENTRY  *Dns4CacheEntry;\r
   EFI_DNS6_CACHE_ENTRY  *Dns6CacheEntry;\r
 \r
+  DNS_RESOURCE_RECORD   *Dns4RR;\r
+  DNS6_RESOURCE_RECORD  *Dns6RR;\r
+\r
   EFI_STATUS            Status;\r
 \r
   EFI_TPL               OldTpl;\r
-  \r
+\r
   Item             = NULL;\r
   Dns4TokenEntry   = NULL;\r
   Dns6TokenEntry   = NULL;\r
-  \r
+\r
   IpCount          = 0;\r
+  RRCount          = 0;\r
   AnswerSectionNum = 0;\r
-  \r
+  CNameTtl         = 0;\r
+\r
   HostAddr4        = NULL;\r
   HostAddr6        = NULL;\r
-  \r
+\r
   Dns4CacheEntry   = NULL;\r
   Dns6CacheEntry   = NULL;\r
 \r
+  Dns4RR           = NULL;\r
+  Dns6RR           = NULL;\r
+\r
   *Completed       = TRUE;\r
   Status           = EFI_SUCCESS;\r
-  \r
+\r
   //\r
   // Get header\r
   //\r
   DnsHeader = (DNS_HEADER *) RxString;\r
-  \r
+\r
   DnsHeader->Identification = NTOHS (DnsHeader->Identification);\r
   DnsHeader->Flags.Uint16 = NTOHS (DnsHeader->Flags.Uint16);\r
   DnsHeader->QuestionsNum = NTOHS (DnsHeader->QuestionsNum);\r
@@ -1163,7 +1214,13 @@ ParseDnsResponse (
   // Check DnsResponse Validity, if so, also get a valid NET_MAP_ITEM.\r
   //\r
   if (Instance->Service->IpVersion == IP_VERSION_4) {\r
-    if (!IsValidDnsResponse (&Instance->Dns4TxTokens, DnsHeader->Identification, QuerySection->Type, &Item)) {\r
+    if (!IsValidDnsResponse (\r
+           &Instance->Dns4TxTokens,\r
+           DnsHeader->Identification,\r
+           QuerySection->Type,\r
+           QuerySection->Class,\r
+           &Item\r
+           )) {\r
       *Completed = FALSE;\r
       Status = EFI_ABORTED;\r
       goto ON_EXIT;\r
@@ -1171,7 +1228,13 @@ ParseDnsResponse (
     ASSERT (Item != NULL);\r
     Dns4TokenEntry = (DNS4_TOKEN_ENTRY *) (Item->Key);\r
   } else {\r
-    if (!IsValidDnsResponse (&Instance->Dns6TxTokens, DnsHeader->Identification, QuerySection->Type, &Item)) {\r
+    if (!IsValidDnsResponse (\r
+           &Instance->Dns6TxTokens,\r
+           DnsHeader->Identification,\r
+           QuerySection->Type,\r
+           QuerySection->Class,\r
+           &Item\r
+           )) {\r
       *Completed = FALSE;\r
       Status = EFI_ABORTED;\r
       goto ON_EXIT;\r
@@ -1179,50 +1242,117 @@ ParseDnsResponse (
     ASSERT (Item != NULL);\r
     Dns6TokenEntry = (DNS6_TOKEN_ENTRY *) (Item->Key);\r
   }\r
-   \r
+\r
   //\r
   // Continue Check Some Errors.\r
   //\r
   if (DnsHeader->Flags.Bits.RCode != DNS_FLAGS_RCODE_NO_ERROR || DnsHeader->AnswersNum < 1 || \\r
-      DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE || QuerySection->Class != DNS_CLASS_INET) {\r
-      Status = EFI_ABORTED;\r
-      goto ON_EXIT;\r
+      DnsHeader->Flags.Bits.QR != DNS_FLAGS_QR_RESPONSE) {\r
+    //\r
+    // The domain name referenced in the query does not exist.\r
+    //\r
+    if (DnsHeader->Flags.Bits.RCode == DNS_FLAGS_RCODE_NAME_ERROR) {\r
+      Status = EFI_NOT_FOUND;\r
+    } else {\r
+      Status = EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    goto ON_COMPLETE;\r
   }\r
 \r
   //\r
-  // Free the sending packet.\r
+  // Do some buffer allocations.\r
   //\r
-  if (Item->Value != NULL) {\r
-    NetbufFree ((NET_BUF *) (Item->Value));\r
-  }\r
-  \r
-  //\r
-  // Check the Query type, do some buffer allocations.\r
-  //\r
-  if (QuerySection->Type == DNS_TYPE_A) {\r
-    Dns4TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
-    ASSERT (Dns4TokenEntry->Token->RspData.H2AData != NULL);\r
-    Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));\r
-    ASSERT (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL);\r
-  } else if (QuerySection->Type == DNS_TYPE_AAAA) {\r
-    Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
-    ASSERT (Dns6TokenEntry->Token->RspData.H2AData != NULL);\r
-    Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocatePool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));\r
-    ASSERT (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL);\r
+  if (Instance->Service->IpVersion == IP_VERSION_4) {\r
+    ASSERT (Dns4TokenEntry != NULL);\r
+\r
+    if (Dns4TokenEntry->GeneralLookUp) {\r
+      //\r
+      // It's the GeneralLookUp querying.\r
+      //\r
+      Dns4TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));\r
+      if (Dns4TokenEntry->Token->RspData.GLookupData == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+      Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
+      if (Dns4TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+    } else {\r
+      //\r
+      // It's not the GeneralLookUp querying. Check the Query type.\r
+      //\r
+      if (QuerySection->Type == DNS_TYPE_A) {\r
+        Dns4TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS_HOST_TO_ADDR_DATA));\r
+        if (Dns4TokenEntry->Token->RspData.H2AData == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
+        Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));\r
+        if (Dns4TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
+      } else {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto ON_EXIT;\r
+      }\r
+    }\r
   } else {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto ON_EXIT;\r
+    ASSERT (Dns6TokenEntry != NULL);\r
+\r
+    if (Dns6TokenEntry->GeneralLookUp) {\r
+      //\r
+      // It's the GeneralLookUp querying.\r
+      //\r
+      Dns6TokenEntry->Token->RspData.GLookupData = AllocateZeroPool (sizeof (DNS_RESOURCE_RECORD));\r
+      if (Dns6TokenEntry->Token->RspData.GLookupData == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+      Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));\r
+      if (Dns6TokenEntry->Token->RspData.GLookupData->RRList == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+    } else {\r
+      //\r
+      // It's not the GeneralLookUp querying. Check the Query type.\r
+      //\r
+      if (QuerySection->Type == DNS_TYPE_AAAA) {\r
+        Dns6TokenEntry->Token->RspData.H2AData = AllocateZeroPool (sizeof (DNS6_HOST_TO_ADDR_DATA));\r
+        if (Dns6TokenEntry->Token->RspData.H2AData == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
+        Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocateZeroPool (DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));\r
+        if (Dns6TokenEntry->Token->RspData.H2AData->IpList == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
+      } else {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto ON_EXIT;\r
+      }\r
+    }\r
   }\r
 \r
+  Status = EFI_NOT_FOUND;\r
+\r
   //\r
   // Processing AnswerSection.\r
   //\r
   while (AnswerSectionNum < DnsHeader->AnswersNum) {\r
     //\r
-    // Answer name should be PTR.\r
+    // Answer name should be PTR, else EFI_UNSUPPORTED returned.\r
     //\r
-    ASSERT ((*(UINT8 *) AnswerName & 0xC0) == 0xC0);\r
-    \r
+    if ((*(UINT8 *) AnswerName & 0xC0) != 0xC0) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto ON_EXIT;\r
+    }\r
+\r
     //\r
     // Get Answer section.\r
     //\r
@@ -1232,100 +1362,199 @@ ParseDnsResponse (
     AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);\r
     AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);\r
 \r
-    ASSERT (AnswerSection->Class == DNS_CLASS_INET);\r
+    //\r
+    // Check whether it's the GeneralLookUp querying.\r
+    //\r
+    if (Instance->Service->IpVersion == IP_VERSION_4 && Dns4TokenEntry->GeneralLookUp) {\r
+      Dns4RR = Dns4TokenEntry->Token->RspData.GLookupData->RRList;\r
+      AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
+\r
+      //\r
+      // Fill the ResourceRecord.\r
+      //\r
+      Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
+      if (Dns4RR[RRCount].QName == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+      CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
+      Dns4RR[RRCount].QType = AnswerSection->Type;\r
+      Dns4RR[RRCount].QClass = AnswerSection->Class;\r
+      Dns4RR[RRCount].TTL = AnswerSection->Ttl;\r
+      Dns4RR[RRCount].DataLength = AnswerSection->DataLength;\r
+      Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);\r
+      if (Dns4RR[RRCount].RData == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+      CopyMem (Dns4RR[RRCount].RData, AnswerData, Dns4RR[RRCount].DataLength);\r
 \r
-    if (AnswerSection->Type == QuerySection->Type) {\r
+      RRCount ++;\r
+      Status = EFI_SUCCESS;\r
+    } else if (Instance->Service->IpVersion == IP_VERSION_6 && Dns6TokenEntry->GeneralLookUp) {\r
+      Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;\r
+      AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
+\r
+      //\r
+      // Fill the ResourceRecord.\r
+      //\r
+      Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);\r
+      if (Dns6RR[RRCount].QName == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+      CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));\r
+      Dns6RR[RRCount].QType = AnswerSection->Type;\r
+      Dns6RR[RRCount].QClass = AnswerSection->Class;\r
+      Dns6RR[RRCount].TTL = AnswerSection->Ttl;\r
+      Dns6RR[RRCount].DataLength = AnswerSection->DataLength;\r
+      Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);\r
+      if (Dns6RR[RRCount].RData == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+      CopyMem (Dns6RR[RRCount].RData, AnswerData, Dns6RR[RRCount].DataLength);\r
+\r
+      RRCount ++;\r
+      Status = EFI_SUCCESS;\r
+    } else {\r
+      //\r
+      // It's not the GeneralLookUp querying.\r
+      // Check the Query type, parse the response packet.\r
+      //\r
       switch (AnswerSection->Type) {\r
       case DNS_TYPE_A:\r
         //\r
         // This is address entry, get Data.\r
         //\r
-        ASSERT (AnswerSection->DataLength == 4);\r
-        \r
+        ASSERT (Dns4TokenEntry != NULL);\r
+\r
+        if (AnswerSection->DataLength != 4) {\r
+          Status = EFI_ABORTED;\r
+          goto ON_EXIT;\r
+        }\r
+\r
         HostAddr4 = Dns4TokenEntry->Token->RspData.H2AData->IpList;\r
         AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
         CopyMem (&HostAddr4[IpCount], AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
 \r
         //\r
-        // Update DNS cache dynamically.\r
-        //\r
-        if (Dns4CacheEntry != NULL) {\r
-          if (Dns4CacheEntry->HostName != NULL) {\r
-            FreePool (Dns4CacheEntry->HostName);\r
-          }\r
-\r
-          if (Dns4CacheEntry->IpAddress != NULL) {\r
-            FreePool (Dns4CacheEntry->IpAddress);\r
-          }\r
-          \r
-          FreePool (Dns4CacheEntry);\r
-        }\r
-\r
-        // \r
-        // Allocate new CacheEntry pool.\r
+        // Allocate new CacheEntry pool to update DNS cache dynamically.\r
         //\r
         Dns4CacheEntry = AllocateZeroPool (sizeof (EFI_DNS4_CACHE_ENTRY));\r
-        ASSERT (Dns4CacheEntry != NULL);\r
+        if (Dns4CacheEntry == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
         Dns4CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
-        ASSERT (Dns4CacheEntry->HostName != NULL);\r
+        if (Dns4CacheEntry->HostName == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
         CopyMem (Dns4CacheEntry->HostName, Dns4TokenEntry->QueryHostName, 2 * (StrLen(Dns4TokenEntry->QueryHostName) + 1));\r
         Dns4CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));\r
-        ASSERT (Dns4CacheEntry->IpAddress != NULL);\r
+        if (Dns4CacheEntry->IpAddress == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
         CopyMem (Dns4CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv4_ADDRESS));\r
-        Dns4CacheEntry->Timeout = AnswerSection->Ttl;\r
-        \r
-        UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);  \r
 \r
-        IpCount ++; \r
+        if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
+          Dns4CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
+        } else {\r
+          Dns4CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
+        }\r
+\r
+        UpdateDns4Cache (&mDriverData->Dns4CacheList, FALSE, TRUE, *Dns4CacheEntry);\r
+\r
+        //\r
+        // Free allocated CacheEntry pool.\r
+        //\r
+        FreePool (Dns4CacheEntry->HostName);\r
+        Dns4CacheEntry->HostName = NULL;\r
+\r
+        FreePool (Dns4CacheEntry->IpAddress);\r
+        Dns4CacheEntry->IpAddress = NULL;\r
+\r
+        FreePool (Dns4CacheEntry);\r
+        Dns4CacheEntry = NULL;\r
+\r
+        IpCount ++;\r
+        Status = EFI_SUCCESS;\r
         break;\r
       case DNS_TYPE_AAAA:\r
         //\r
         // This is address entry, get Data.\r
         //\r
-        ASSERT (AnswerSection->DataLength == 16);\r
-        \r
+        ASSERT (Dns6TokenEntry != NULL);\r
+\r
+        if (AnswerSection->DataLength != 16) {\r
+          Status = EFI_ABORTED;\r
+          goto ON_EXIT;\r
+        }\r
+\r
         HostAddr6 = Dns6TokenEntry->Token->RspData.H2AData->IpList;\r
         AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);\r
         CopyMem (&HostAddr6[IpCount], AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
 \r
         //\r
-        // Update DNS cache dynamically.\r
-        //\r
-        if (Dns6CacheEntry != NULL) {\r
-          if (Dns6CacheEntry->HostName != NULL) {\r
-            FreePool (Dns6CacheEntry->HostName);\r
-          }\r
-\r
-          if (Dns6CacheEntry->IpAddress != NULL) {\r
-            FreePool (Dns6CacheEntry->IpAddress);\r
-          }\r
-          \r
-          FreePool (Dns6CacheEntry);\r
-        }\r
-\r
-        // \r
-        // Allocate new CacheEntry pool.\r
+        // Allocate new CacheEntry pool to update DNS cache dynamically.\r
         //\r
         Dns6CacheEntry = AllocateZeroPool (sizeof (EFI_DNS6_CACHE_ENTRY));\r
-        ASSERT (Dns6CacheEntry != NULL);\r
+        if (Dns6CacheEntry == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
         Dns6CacheEntry->HostName = AllocateZeroPool (2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
-        ASSERT (Dns6CacheEntry->HostName != NULL);\r
+        if (Dns6CacheEntry->HostName == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
         CopyMem (Dns6CacheEntry->HostName, Dns6TokenEntry->QueryHostName, 2 * (StrLen(Dns6TokenEntry->QueryHostName) + 1));\r
         Dns6CacheEntry->IpAddress = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));\r
-        ASSERT (Dns6CacheEntry->IpAddress != NULL);\r
+        if (Dns6CacheEntry->IpAddress == NULL) {\r
+          Status = EFI_OUT_OF_RESOURCES;\r
+          goto ON_EXIT;\r
+        }\r
         CopyMem (Dns6CacheEntry->IpAddress, AnswerData, sizeof (EFI_IPv6_ADDRESS));\r
-        Dns6CacheEntry->Timeout = AnswerSection->Ttl;\r
-        \r
-        UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);  \r
-        \r
+\r
+        if (CNameTtl != 0 && AnswerSection->Ttl != 0) {\r
+          Dns6CacheEntry->Timeout = MIN (CNameTtl, AnswerSection->Ttl);\r
+        } else {\r
+          Dns6CacheEntry->Timeout = MAX (CNameTtl, AnswerSection->Ttl);\r
+        }\r
+\r
+        UpdateDns6Cache (&mDriverData->Dns6CacheList, FALSE, TRUE, *Dns6CacheEntry);\r
+\r
+        //\r
+        // Free allocated CacheEntry pool.\r
+        //\r
+        FreePool (Dns6CacheEntry->HostName);\r
+        Dns6CacheEntry->HostName = NULL;\r
+\r
+        FreePool (Dns6CacheEntry->IpAddress);\r
+        Dns6CacheEntry->IpAddress = NULL;\r
+\r
+        FreePool (Dns6CacheEntry);\r
+        Dns6CacheEntry = NULL;\r
+\r
         IpCount ++;\r
+        Status = EFI_SUCCESS;\r
+        break;\r
+      case DNS_TYPE_CNAME:\r
+        //\r
+        // According RFC 1034 - 3.6.2, if the query name is an alias, the name server will include the CNAME\r
+        // record in the response and restart the query at the domain name specified in the data field of the\r
+        // CNAME record. So, just record the TTL value of the CNAME, then skip to parse the next record.\r
+        //\r
+        CNameTtl = AnswerSection->Ttl;\r
         break;\r
       default:\r
         Status = EFI_UNSUPPORTED;\r
         goto ON_EXIT;\r
       }\r
     }\r
-    \r
+\r
     //\r
     // Find next one\r
     //\r
@@ -1333,59 +1562,152 @@ ParseDnsResponse (
     AnswerSectionNum ++;\r
   }\r
 \r
-  if (QuerySection->Type == DNS_TYPE_A) {\r
-    Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
-  } else if (QuerySection->Type == DNS_TYPE_AAAA) {\r
-    Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
+  if (Instance->Service->IpVersion == IP_VERSION_4) {\r
+    ASSERT (Dns4TokenEntry != NULL);\r
+\r
+    if (Dns4TokenEntry->GeneralLookUp) {\r
+      Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;\r
+    } else {\r
+      if (QuerySection->Type == DNS_TYPE_A) {\r
+        Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
+      } else {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto ON_EXIT;\r
+      }\r
+    }\r
+  } else {\r
+    ASSERT (Dns6TokenEntry != NULL);\r
+\r
+    if (Dns6TokenEntry->GeneralLookUp) {\r
+      Dns6TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;\r
+    } else {\r
+      if (QuerySection->Type == DNS_TYPE_AAAA) {\r
+        Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;\r
+      } else {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto ON_EXIT;\r
+      }\r
+    }\r
   }\r
 \r
+ON_COMPLETE:\r
   //\r
-  // Parsing is complete, SignalEvent here.\r
+  // Parsing is complete, free the sending packet and signal Event here.\r
   //\r
+  if (Item != NULL && Item->Value != NULL) {\r
+    NetbufFree ((NET_BUF *) (Item->Value));\r
+  }\r
+\r
   if (Instance->Service->IpVersion == IP_VERSION_4) {\r
+    ASSERT (Dns4TokenEntry != NULL);\r
     Dns4RemoveTokenEntry (&Instance->Dns4TxTokens, Dns4TokenEntry);\r
-    Dns4TokenEntry->Token->Status = EFI_SUCCESS;\r
+    Dns4TokenEntry->Token->Status = Status;\r
     if (Dns4TokenEntry->Token->Event != NULL) {\r
       gBS->SignalEvent (Dns4TokenEntry->Token->Event);\r
       DispatchDpc ();\r
     }\r
   } else {\r
+    ASSERT (Dns6TokenEntry != NULL);\r
     Dns6RemoveTokenEntry (&Instance->Dns6TxTokens, Dns6TokenEntry);\r
-    Dns6TokenEntry->Token->Status = EFI_SUCCESS;\r
+    Dns6TokenEntry->Token->Status = Status;\r
     if (Dns6TokenEntry->Token->Event != NULL) {\r
       gBS->SignalEvent (Dns6TokenEntry->Token->Event);\r
       DispatchDpc ();\r
     }\r
   }\r
 \r
-  // \r
-  // Free allocated CacheEntry pool.\r
+ON_EXIT:\r
   //\r
-  if (Dns4CacheEntry != NULL) {\r
-    if (Dns4CacheEntry->HostName != NULL) {\r
-      FreePool (Dns4CacheEntry->HostName);\r
+  // Free the allocated buffer if error happen.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    if (Dns4TokenEntry != NULL) {\r
+      if (Dns4TokenEntry->GeneralLookUp) {\r
+        if (Dns4TokenEntry->Token->RspData.GLookupData != NULL) {\r
+          if (Dns4TokenEntry->Token->RspData.GLookupData->RRList != NULL) {\r
+            while (RRCount != 0) {\r
+              RRCount --;\r
+              if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {\r
+                FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);\r
+              }\r
+\r
+              if (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {\r
+                FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);\r
+              }\r
+            }\r
+\r
+            FreePool (Dns4TokenEntry->Token->RspData.GLookupData->RRList);\r
+          }\r
+\r
+          FreePool (Dns4TokenEntry->Token->RspData.GLookupData);\r
+        }\r
+      } else {\r
+        if (QuerySection->Type == DNS_TYPE_A && Dns4TokenEntry->Token->RspData.H2AData != NULL) {\r
+          if (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL) {\r
+            FreePool (Dns4TokenEntry->Token->RspData.H2AData->IpList);\r
+          }\r
+\r
+          FreePool (Dns4TokenEntry->Token->RspData.H2AData);\r
+        }\r
+      }\r
     }\r
 \r
-    if (Dns4CacheEntry->IpAddress != NULL) {\r
-      FreePool (Dns4CacheEntry->IpAddress);\r
+    if (Dns6TokenEntry != NULL) {\r
+      if (Dns6TokenEntry->GeneralLookUp) {\r
+        if (Dns6TokenEntry->Token->RspData.GLookupData != NULL) {\r
+          if (Dns6TokenEntry->Token->RspData.GLookupData->RRList != NULL) {\r
+            while (RRCount != 0) {\r
+              RRCount --;\r
+              if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName != NULL) {\r
+                FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].QName);\r
+              }\r
+\r
+              if (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData != NULL) {\r
+                FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList[RRCount].RData);\r
+              }\r
+            }\r
+\r
+            FreePool (Dns6TokenEntry->Token->RspData.GLookupData->RRList);\r
+          }\r
+\r
+          FreePool (Dns6TokenEntry->Token->RspData.GLookupData);\r
+        }\r
+      } else {\r
+        if (QuerySection->Type == DNS_TYPE_AAAA && Dns6TokenEntry->Token->RspData.H2AData != NULL) {\r
+          if (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL) {\r
+            FreePool (Dns6TokenEntry->Token->RspData.H2AData->IpList);\r
+          }\r
+\r
+          FreePool (Dns6TokenEntry->Token->RspData.H2AData);\r
+        }\r
+      }\r
     }\r
 \r
-    FreePool (Dns4CacheEntry);\r
-  }\r
-  \r
-  if (Dns6CacheEntry != NULL) {\r
-    if (Dns6CacheEntry->HostName != NULL) {\r
-      FreePool (Dns6CacheEntry->HostName);\r
+    if (Dns4CacheEntry != NULL) {\r
+      if (Dns4CacheEntry->HostName != NULL) {\r
+        FreePool (Dns4CacheEntry->HostName);\r
+      }\r
+\r
+      if (Dns4CacheEntry->IpAddress != NULL) {\r
+        FreePool (Dns4CacheEntry->IpAddress);\r
+      }\r
+\r
+      FreePool (Dns4CacheEntry);\r
     }\r
 \r
-    if (Dns6CacheEntry->IpAddress != NULL) {\r
-      FreePool (Dns6CacheEntry->IpAddress);\r
+    if (Dns6CacheEntry != NULL) {\r
+      if (Dns6CacheEntry->HostName != NULL) {\r
+        FreePool (Dns6CacheEntry->HostName);\r
+      }\r
+\r
+      if (Dns6CacheEntry->IpAddress != NULL) {\r
+        FreePool (Dns6CacheEntry->IpAddress);\r
+      }\r
+\r
+      FreePool (Dns6CacheEntry);\r
     }\r
-  \r
-    FreePool (Dns6CacheEntry);\r
   }\r
 \r
-ON_EXIT:\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
@@ -1398,7 +1720,7 @@ ON_EXIT:
   @param  IoStatus              The status of the UDP receive\r
   @param  Context               The opaque parameter to the function.\r
 \r
-**/  \r
+**/\r
 VOID\r
 EFIAPI\r
 DnsOnPacketReceived (\r
@@ -1413,7 +1735,7 @@ DnsOnPacketReceived (
   UINT8                     *RcvString;\r
 \r
   BOOLEAN                   Completed;\r
-  \r
+\r
   Instance  = (DNS_INSTANCE *) Context;\r
   NET_CHECK_SIGNATURE (Instance, DNS_INSTANCE_SIGNATURE);\r
 \r
@@ -1425,24 +1747,28 @@ DnsOnPacketReceived (
   }\r
 \r
   ASSERT (Packet != NULL);\r
-  \r
+\r
+  if (Packet->TotalSize <= sizeof (DNS_HEADER)) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
   RcvString = NetbufGetByte (Packet, 0, NULL);\r
   ASSERT (RcvString != NULL);\r
-  \r
+\r
   //\r
   // Parse Dns Response\r
   //\r
   ParseDnsResponse (Instance, RcvString, &Completed);\r
 \r
-  ON_EXIT:\r
+ON_EXIT:\r
 \r
-    if (Packet != NULL) {\r
-      NetbufFree (Packet);\r
-    }\r
+  if (Packet != NULL) {\r
+    NetbufFree (Packet);\r
+  }\r
 \r
-    if (!Completed) {\r
-      UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
-    }\r
+  if (!Completed) {\r
+    UdpIoRecvDatagram (Instance->UdpIo, DnsOnPacketReceived, Instance, 0);\r
+  }\r
 }\r
 \r
 /**\r
@@ -1494,7 +1820,7 @@ DnsOnPacketSent (
       }\r
     }\r
   }\r
-  \r
+\r
   NetbufFree (Packet);\r
 }\r
 \r
@@ -1525,48 +1851,48 @@ DoDnsQuery (
       return Status;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Transmit the DNS packet.\r
   //\r
   NET_GET_REF (Packet);\r
 \r
   Status = UdpIoSendDatagram (Instance->UdpIo, Packet, NULL, NULL, DnsOnPacketSent, Instance);\r
-  \r
+\r
   return Status;\r
 }\r
 \r
 /**\r
-  Construct the Packet to query Ip.\r
+  Construct the Packet according query section.\r
 \r
   @param  Instance              The DNS instance\r
-  @param  HostName              Queried HostName  \r
-  @param  Type                  DNS query Type\r
-  @param  Packet                The packet for querying Ip\r
+  @param  QueryName             Queried Name\r
+  @param  Type                  Queried Type\r
+  @param  Class                 Queried Class\r
+  @param  Packet                The packet for query\r
 \r
   @retval EFI_SUCCESS           The packet is constructed.\r
   @retval Others                Failed to construct the Packet.\r
 \r
 **/\r
 EFI_STATUS\r
-ConstructDNSQueryIp (\r
+ConstructDNSQuery (\r
   IN  DNS_INSTANCE              *Instance,\r
-  IN  CHAR16                    *HostName,\r
+  IN  CHAR8                     *QueryName,\r
   IN  UINT16                    Type,\r
+  IN  UINT16                    Class,\r
   OUT NET_BUF                   **Packet\r
   )\r
 {\r
   NET_FRAGMENT        Frag;\r
   DNS_HEADER          *DnsHeader;\r
-  CHAR8               *QueryName;\r
-  DNS_QUERY_SECTION   *QuerySection;\r
-  CHAR8               *Header;\r
-  CHAR8               *Tail;\r
-  UINTN               Len;\r
-  UINTN               Index;\r
-  \r
-\r
-  Frag.Bulk = AllocatePool (DNS_DEFAULT_BLKSIZE * sizeof (UINT8));\r
+  DNS_QUERY_SECTION   *DnsQuery;\r
+\r
+  //\r
+  // Messages carried by UDP are restricted to 512 bytes (not counting the IP\r
+  // or UDP headers).\r
+  //\r
+  Frag.Bulk = AllocatePool (DNS_MAX_MESSAGE_SIZE * sizeof (UINT8));\r
   if (Frag.Bulk == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -1574,7 +1900,7 @@ ConstructDNSQueryIp (
   //\r
   // Fill header\r
   //\r
-  DnsHeader = (DNS_HEADER *) Frag.Bulk; \r
+  DnsHeader = (DNS_HEADER *) Frag.Bulk;\r
   DnsHeader->Identification = (UINT16)NET_RANDOM (NetRandomInitSeed());\r
   DnsHeader->Flags.Uint16 = 0x0000;\r
   DnsHeader->Flags.Bits.RD = 1;\r
@@ -1597,37 +1923,20 @@ ConstructDNSQueryIp (
   //\r
   // Fill Query name\r
   //\r
-  QueryName = (CHAR8 *) (Frag.Bulk + Frag.Len);\r
-  Header = QueryName;\r
-  Tail = Header + 1;\r
-  Len = 0;\r
-  for (Index = 0; HostName[Index] != 0; Index++) {\r
-    *Tail = (CHAR8) HostName[Index];\r
-    if (*Tail == '.') {\r
-      *Header = (CHAR8) Len;\r
-      Header = Tail;\r
-      Tail ++;\r
-      Len = 0;\r
-    } else {\r
-      Tail++;\r
-      Len++;\r
-    }\r
-  }\r
-  *Header = (CHAR8) Len;\r
-  *Tail = 0;\r
-  Frag.Len = (UINT32) (Frag.Len + StrLen (HostName) + 2); /// 1 for header, 1 for tail.\r
+  CopyMem (Frag.Bulk + Frag.Len, QueryName, AsciiStrLen (QueryName));\r
+  Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));\r
+  *(Frag.Bulk + Frag.Len) = 0;\r
+  Frag.Len ++;\r
 \r
   //\r
   // Rest query section\r
   //\r
-  QuerySection = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);\r
-  QuerySection->Type = Type;\r
-  QuerySection->Class = DNS_CLASS_INET;\r
+  DnsQuery = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);\r
 \r
-  QuerySection->Type = HTONS (QuerySection->Type);\r
-  QuerySection->Class = HTONS (QuerySection->Class);\r
+  DnsQuery->Type = HTONS (Type);\r
+  DnsQuery->Class = HTONS (Class);\r
 \r
-  Frag.Len += sizeof (*QuerySection);\r
+  Frag.Len += sizeof (*DnsQuery);\r
 \r
   //\r
   // Wrap the Frag in a net buffer.\r
@@ -1637,7 +1946,7 @@ ConstructDNSQueryIp (
     FreePool (Frag.Bulk);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   //\r
   // Store the UdpIo in ProtoData.\r
   //\r
@@ -1650,7 +1959,7 @@ ConstructDNSQueryIp (
   Retransmit the packet.\r
 \r
   @param  Instance              The DNS instance\r
-  @param  Packet                Retransmit the packet \r
+  @param  Packet                Retransmit the packet\r
 \r
   @retval EFI_SUCCESS           The packet is retransmitted.\r
   @retval Others                Failed to retransmit.\r
@@ -1663,7 +1972,7 @@ DnsRetransmit (
   )\r
 {\r
   EFI_STATUS      Status;\r
-  \r
+\r
   UINT8           *Buffer;\r
 \r
   ASSERT (Packet != NULL);\r
@@ -1744,7 +2053,7 @@ DnsOnTimerRetransmit (
         // Retransmit the packet if haven't reach the maxmium retry count,\r
         // otherwise exit the transfer.\r
         //\r
-        if (++Dns4TokenEntry->Token->RetryCount < Instance->MaxRetry) {\r
+        if (++Dns4TokenEntry->RetryCounting <= Dns4TokenEntry->Token->RetryCount) {\r
           DnsRetransmit (Instance, (NET_BUF *)ItemNetMap->Value);\r
           EntryNetMap = EntryNetMap->ForwardLink;\r
         } else {\r
@@ -1755,7 +2064,7 @@ DnsOnTimerRetransmit (
           Dns4TokenEntry->Token->Status = EFI_TIMEOUT;\r
           gBS->SignalEvent (Dns4TokenEntry->Token->Event);\r
           DispatchDpc ();\r
-          \r
+\r
           //\r
           // Free the sending packet.\r
           //\r
@@ -1766,7 +2075,7 @@ DnsOnTimerRetransmit (
           EntryNetMap = Instance->Dns4TxTokens.Used.ForwardLink;\r
         }\r
       }\r
-    } \r
+    }\r
   }else {\r
     //\r
     // Iterate through all the children of the DNS service instance. Time\r
@@ -1774,7 +2083,7 @@ DnsOnTimerRetransmit (
     //\r
     NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Dns6ChildrenList) {\r
       Instance = NET_LIST_USER_STRUCT (Entry, DNS_INSTANCE, Link);\r
-      \r
+\r
       EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;\r
       while (EntryNetMap != &Instance->Dns6TxTokens.Used) {\r
         ItemNetMap = NET_LIST_USER_STRUCT (EntryNetMap, NET_MAP_ITEM, Link);\r
@@ -1788,7 +2097,7 @@ DnsOnTimerRetransmit (
         // Retransmit the packet if haven't reach the maxmium retry count,\r
         // otherwise exit the transfer.\r
         //\r
-        if (++Dns6TokenEntry->Token->RetryCount < Instance->MaxRetry) {\r
+        if (++Dns6TokenEntry->RetryCounting <= Dns6TokenEntry->Token->RetryCount) {\r
           DnsRetransmit (Instance, (NET_BUF *) ItemNetMap->Value);\r
           EntryNetMap = EntryNetMap->ForwardLink;\r
         } else {\r
@@ -1799,7 +2108,7 @@ DnsOnTimerRetransmit (
           Dns6TokenEntry->Token->Status = EFI_TIMEOUT;\r
           gBS->SignalEvent (Dns6TokenEntry->Token->Event);\r
           DispatchDpc ();\r
-          \r
+\r
           //\r
           // Free the sending packet.\r
           //\r
@@ -1808,10 +2117,10 @@ DnsOnTimerRetransmit (
           }\r
 \r
           EntryNetMap = Instance->Dns6TxTokens.Used.ForwardLink;\r
-        } \r
+        }\r
       }\r
     }\r
-  } \r
+  }\r
 }\r
 \r
 /**\r
@@ -1843,18 +2152,21 @@ DnsOnTimerUpdate (
     Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
     Item4->DnsCache.Timeout--;\r
   }\r
-  \r
+\r
   Entry = mDriverData->Dns4CacheList.ForwardLink;\r
   while (Entry != &mDriverData->Dns4CacheList) {\r
     Item4 = NET_LIST_USER_STRUCT (Entry, DNS4_CACHE, AllCacheLink);\r
-    if (Item4->DnsCache.Timeout<=0) {\r
+    if (Item4->DnsCache.Timeout == 0) {\r
       RemoveEntryList (&Item4->AllCacheLink);\r
+      FreePool (Item4->DnsCache.HostName);\r
+      FreePool (Item4->DnsCache.IpAddress);\r
+      FreePool (Item4);\r
       Entry = mDriverData->Dns4CacheList.ForwardLink;\r
     } else {\r
       Entry = Entry->ForwardLink;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Iterate through all the DNS6 cache list.\r
   //\r
@@ -1862,12 +2174,15 @@ DnsOnTimerUpdate (
     Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
     Item6->DnsCache.Timeout--;\r
   }\r
-  \r
+\r
   Entry = mDriverData->Dns6CacheList.ForwardLink;\r
   while (Entry != &mDriverData->Dns6CacheList) {\r
     Item6 = NET_LIST_USER_STRUCT (Entry, DNS6_CACHE, AllCacheLink);\r
-    if (Item6->DnsCache.Timeout<=0) {\r
+    if (Item6->DnsCache.Timeout == 0) {\r
       RemoveEntryList (&Item6->AllCacheLink);\r
+      FreePool (Item6->DnsCache.HostName);\r
+      FreePool (Item6->DnsCache.IpAddress);\r
+      FreePool (Item6);\r
       Entry = mDriverData->Dns6CacheList.ForwardLink;\r
     } else {\r
       Entry = Entry->ForwardLink;\r