This patch is used to support DNS4/6 GeneralLookUp feature.

Cc: Subramanian Sriram <[email protected]>
Cc: El-Haj-Mahmoud Samer <[email protected]>
Cc: Ye Ting <[email protected]>
Cc: Fu Siyuan <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <[email protected]>
---
 NetworkPkg/DnsDxe/DnsImpl.c     | 251 ++++++++++++++++++++++++++++++----------
 NetworkPkg/DnsDxe/DnsImpl.h     |  31 ++++-
 NetworkPkg/DnsDxe/DnsProtocol.c | 247 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 455 insertions(+), 74 deletions(-)

diff --git a/NetworkPkg/DnsDxe/DnsImpl.c b/NetworkPkg/DnsDxe/DnsImpl.c
index 4f7320e..7a89c4e 100644
--- a/NetworkPkg/DnsDxe/DnsImpl.c
+++ b/NetworkPkg/DnsDxe/DnsImpl.c
@@ -1012,10 +1012,59 @@ AddDns6ServerIp (
   
   return EFI_SUCCESS;
 }
 
 /**
+  Fill QName for IP querying. 
+
+  @param  HostName          Queried HostName    
+
+  @retval EFI_SUCCESS       QName filled successfully.
+  @retval Others            Failed to fill QName.
+  
+**/ 
+UINT8 *
+EFIAPI
+DnsFillQuerytIpQName (
+  IN  CHAR16              *HostName
+  )
+{
+  CHAR8                 *QueryName;
+  CHAR8                 *Header;
+  CHAR8                 *Tail;
+  UINTN                 Len;
+  UINTN                 Index;
+
+  QueryName  = NULL;
+  Header     = NULL;
+  Tail       = NULL;
+
+  QueryName = AllocateZeroPool (DNS_DEFAULT_BLKSIZE);
+  ASSERT (QueryName != NULL);
+  
+  Header = QueryName;
+  Tail = Header + 1;
+  Len = 0;
+  for (Index = 0; HostName[Index] != 0; Index++) {
+    *Tail = (CHAR8) HostName[Index];
+    if (*Tail == '.') {
+      *Header = (CHAR8) Len;
+      Header = Tail;
+      Tail ++;
+      Len = 0;
+    } else {
+      Tail++;
+      Len++;
+    }
+  }
+  *Header = (CHAR8) Len;
+  *Tail = 0;
+
+  return QueryName;
+}
+
+/**
   Find out whether the response is valid or invalid.
 
   @param  TokensMap       All DNS transmittal Tokens entry.  
   @param  Identification  Identification for queried packet.  
   @param  Type            Type for queried packet.
@@ -1098,34 +1147,42 @@ ParseDnsResponse (
   NET_MAP_ITEM          *Item;
   DNS4_TOKEN_ENTRY      *Dns4TokenEntry;
   DNS6_TOKEN_ENTRY      *Dns6TokenEntry;
   
   UINT32                IpCount;
+  UINT32                RRCount;
   UINT32                AnswerSectionNum;
   
   EFI_IPv4_ADDRESS      *HostAddr4;
   EFI_IPv6_ADDRESS      *HostAddr6;
 
   EFI_DNS4_CACHE_ENTRY  *Dns4CacheEntry;
   EFI_DNS6_CACHE_ENTRY  *Dns6CacheEntry;
 
+  DNS_RESOURCE_RECORD   *Dns4RR;
+  DNS6_RESOURCE_RECORD  *Dns6RR;
+
   EFI_STATUS            Status;
 
   EFI_TPL               OldTpl;
   
   Item             = NULL;
   Dns4TokenEntry   = NULL;
   Dns6TokenEntry   = NULL;
   
   IpCount          = 0;
+  RRCount          = 0;
   AnswerSectionNum = 0;
   
   HostAddr4        = NULL;
   HostAddr6        = NULL;
   
   Dns4CacheEntry   = NULL;
   Dns6CacheEntry   = NULL;
+  
+  Dns4RR           = NULL;
+  Dns6RR           = NULL;
 
   *Completed       = TRUE;
   Status           = EFI_SUCCESS;
   
   //
@@ -1195,33 +1252,61 @@ ParseDnsResponse (
   if (Item->Value != NULL) {
     NetbufFree ((NET_BUF *) (Item->Value));
   }
   
   //
-  // Check the Query type, do some buffer allocations.
+  // Do some buffer allocations.
   //
   if (Instance->Service->IpVersion == IP_VERSION_4) {
     ASSERT (Dns4TokenEntry != NULL);
-    if (QuerySection->Type == DNS_TYPE_A) {
-      Dns4TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof 
(DNS_HOST_TO_ADDR_DATA));
-      ASSERT (Dns4TokenEntry->Token->RspData.H2AData != NULL);
-      Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocatePool 
(DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));
-      ASSERT (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL);
+
+    if (Dns4TokenEntry->GeneralLookUp) {
+      //
+      // It's the GeneralLookUp querying.
+      //
+      Dns4TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof 
(DNS_RESOURCE_RECORD));
+      ASSERT (Dns4TokenEntry->Token->RspData.GLookupData != NULL);
+      Dns4TokenEntry->Token->RspData.GLookupData->RRList = AllocatePool 
(DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
+      ASSERT (Dns4TokenEntry->Token->RspData.GLookupData->RRList != NULL);
     } else {
-      Status = EFI_UNSUPPORTED;
-      goto ON_EXIT;
+      //
+      // It's not the GeneralLookUp querying. Check the Query type.
+      //
+      if (QuerySection->Type == DNS_TYPE_A) {
+        Dns4TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof 
(DNS_HOST_TO_ADDR_DATA));
+        ASSERT (Dns4TokenEntry->Token->RspData.H2AData != NULL);
+        Dns4TokenEntry->Token->RspData.H2AData->IpList = AllocatePool 
(DnsHeader->AnswersNum * sizeof (EFI_IPv4_ADDRESS));
+        ASSERT (Dns4TokenEntry->Token->RspData.H2AData->IpList != NULL);
+      } else {
+        Status = EFI_UNSUPPORTED;
+        goto ON_EXIT;
+      }
     }
   } else {
     ASSERT (Dns6TokenEntry != NULL);
-    if (QuerySection->Type == DNS_TYPE_AAAA) {
-      Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof 
(DNS6_HOST_TO_ADDR_DATA));
-      ASSERT (Dns6TokenEntry->Token->RspData.H2AData != NULL);
-      Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocatePool 
(DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));
-      ASSERT (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL);
+
+    if (Dns6TokenEntry->GeneralLookUp) {
+      //
+      // It's the GeneralLookUp querying.
+      //
+      Dns6TokenEntry->Token->RspData.GLookupData = AllocatePool (sizeof 
(DNS_RESOURCE_RECORD));
+      ASSERT (Dns6TokenEntry->Token->RspData.GLookupData != NULL);
+      Dns6TokenEntry->Token->RspData.GLookupData->RRList = AllocatePool 
(DnsHeader->AnswersNum * sizeof (DNS_RESOURCE_RECORD));
+      ASSERT (Dns6TokenEntry->Token->RspData.GLookupData->RRList != NULL);
     } else {
-      Status = EFI_UNSUPPORTED;
-      goto ON_EXIT;
+      //
+      // It's not the GeneralLookUp querying. Check the Query type.
+      //
+      if (QuerySection->Type == DNS_TYPE_AAAA) {
+        Dns6TokenEntry->Token->RspData.H2AData = AllocatePool (sizeof 
(DNS6_HOST_TO_ADDR_DATA));
+        ASSERT (Dns6TokenEntry->Token->RspData.H2AData != NULL);
+        Dns6TokenEntry->Token->RspData.H2AData->IpList = AllocatePool 
(DnsHeader->AnswersNum * sizeof (EFI_IPv6_ADDRESS));
+        ASSERT (Dns6TokenEntry->Token->RspData.H2AData->IpList != NULL);
+      } else {
+        Status = EFI_UNSUPPORTED;
+        goto ON_EXIT;
+      }
     }
   }
 
   //
   // Processing AnswerSection.
@@ -1239,13 +1324,60 @@ ParseDnsResponse (
     AnswerSection->Type = NTOHS (AnswerSection->Type);
     AnswerSection->Class = NTOHS (AnswerSection->Class);
     AnswerSection->Ttl = NTOHL (AnswerSection->Ttl);
     AnswerSection->DataLength = NTOHS (AnswerSection->DataLength);
 
-    ASSERT (AnswerSection->Class == DNS_CLASS_INET);
+    //
+    // Check whether it's the GeneralLookUp querying.
+    //
+    if (Instance->Service->IpVersion == IP_VERSION_4 && 
Dns4TokenEntry->GeneralLookUp) {
+        ASSERT (Dns4TokenEntry != NULL);
+        
+        Dns4RR = Dns4TokenEntry->Token->RspData.GLookupData->RRList;
+        AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
+
+        //
+        // Fill the ResouseRecord.
+        //
+        Dns4RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
+        ASSERT (Dns4RR[RRCount].QName != NULL);
+        CopyMem (Dns4RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
+        Dns4RR[RRCount].QType = AnswerSection->Type;
+        Dns4RR[RRCount].QClass = AnswerSection->Class;
+        Dns4RR[RRCount].TTL = AnswerSection->Ttl;
+        Dns4RR[RRCount].DataLength = AnswerSection->DataLength;
+        Dns4RR[RRCount].RData = AllocateZeroPool (Dns4RR[RRCount].DataLength);
+        ASSERT (Dns4RR[RRCount].RData != NULL);
+        CopyMem (Dns4RR[RRCount].RData, AnswerData, 
Dns4RR[RRCount].DataLength);
+        
+        RRCount ++;
+    } else if (Instance->Service->IpVersion == IP_VERSION_6 && 
Dns6TokenEntry->GeneralLookUp) {
+        ASSERT (Dns6TokenEntry != NULL);
+        
+        Dns6RR = Dns6TokenEntry->Token->RspData.GLookupData->RRList;
+        AnswerData = (UINT8 *) AnswerSection + sizeof (*AnswerSection);
 
-    if (AnswerSection->Type == QuerySection->Type) {
+        //
+        // Fill the ResouseRecord.
+        //
+        Dns6RR[RRCount].QName = AllocateZeroPool (AsciiStrLen (QueryName) + 1);
+        ASSERT (Dns6RR[RRCount].QName != NULL);
+        CopyMem (Dns6RR[RRCount].QName, QueryName, AsciiStrLen (QueryName));
+        Dns6RR[RRCount].QType = AnswerSection->Type;
+        Dns6RR[RRCount].QClass = AnswerSection->Class;
+        Dns6RR[RRCount].TTL = AnswerSection->Ttl;
+        Dns6RR[RRCount].DataLength = AnswerSection->DataLength;
+        Dns6RR[RRCount].RData = AllocateZeroPool (Dns6RR[RRCount].DataLength);
+        ASSERT (Dns6RR[RRCount].RData != NULL);
+        CopyMem (Dns6RR[RRCount].RData, AnswerData, 
Dns6RR[RRCount].DataLength);
+        
+        RRCount ++;
+    } else {
+      //
+      // It's not the GeneralLookUp querying. 
+      // Check the Query type, parse the response packet.
+      //
       switch (AnswerSection->Type) {
       case DNS_TYPE_A:
         //
         // This is address entry, get Data.
         //
@@ -1342,23 +1474,33 @@ ParseDnsResponse (
     AnswerSectionNum ++;
   }
 
   if (Instance->Service->IpVersion == IP_VERSION_4) {
     ASSERT (Dns4TokenEntry != NULL);
-    if (QuerySection->Type == DNS_TYPE_A) {
-      Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
+    
+    if (Dns4TokenEntry->GeneralLookUp) {
+      Dns4TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
     } else {
-      Status = EFI_UNSUPPORTED;
-      goto ON_EXIT;
+      if (QuerySection->Type == DNS_TYPE_A) {
+        Dns4TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
+      } else {
+        Status = EFI_UNSUPPORTED;
+        goto ON_EXIT;
+      }
     }
   } else {
     ASSERT (Dns6TokenEntry != NULL);
-    if (QuerySection->Type == DNS_TYPE_AAAA) {
-      Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
+
+    if (Dns6TokenEntry->GeneralLookUp) {
+      Dns6TokenEntry->Token->RspData.GLookupData->RRCount = RRCount;
     } else {
-      Status = EFI_UNSUPPORTED;
-      goto ON_EXIT;
+      if (QuerySection->Type == DNS_TYPE_AAAA) {
+        Dns6TokenEntry->Token->RspData.H2AData->IpCount = IpCount;
+      } else {
+        Status = EFI_UNSUPPORTED;
+        goto ON_EXIT;
+      }
     }
   }
 
   //
   // Parsing is complete, SignalEvent here.
@@ -1558,39 +1700,35 @@ DoDnsQuery (
   
   return Status;
 }
 
 /**
-  Construct the Packet to query Ip.
+  Construct the Packet according query section.
 
   @param  Instance              The DNS instance
-  @param  HostName              Queried HostName  
-  @param  Type                  DNS query Type
-  @param  Packet                The packet for querying Ip
+  @param  QueryName             Queried Name  
+  @param  Type                  Queried Type 
+  @param  Class                 Queried Class 
+  @param  Packet                The packet for query
 
   @retval EFI_SUCCESS           The packet is constructed.
   @retval Others                Failed to construct the Packet.
 
 **/
 EFI_STATUS
-ConstructDNSQueryIp (
+ConstructDNSQuery (
   IN  DNS_INSTANCE              *Instance,
-  IN  CHAR16                    *HostName,
+  IN  CHAR8                     *QueryName,
   IN  UINT16                    Type,
+  IN  UINT16                    Class,
   OUT NET_BUF                   **Packet
   )
 {
   NET_FRAGMENT        Frag;
   DNS_HEADER          *DnsHeader;
-  CHAR8               *QueryName;
-  DNS_QUERY_SECTION   *QuerySection;
-  CHAR8               *Header;
-  CHAR8               *Tail;
-  UINTN               Len;
-  UINTN               Index;
+  DNS_QUERY_SECTION   *DnsQuery;
   
-
   Frag.Bulk = AllocatePool (DNS_DEFAULT_BLKSIZE * sizeof (UINT8));
   if (Frag.Bulk == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
@@ -1618,41 +1756,26 @@ ConstructDNSQueryIp (
   Frag.Len = sizeof (*DnsHeader);
 
   //
   // Fill Query name
   //
-  QueryName = (CHAR8 *) (Frag.Bulk + Frag.Len);
-  Header = QueryName;
-  Tail = Header + 1;
-  Len = 0;
-  for (Index = 0; HostName[Index] != 0; Index++) {
-    *Tail = (CHAR8) HostName[Index];
-    if (*Tail == '.') {
-      *Header = (CHAR8) Len;
-      Header = Tail;
-      Tail ++;
-      Len = 0;
-    } else {
-      Tail++;
-      Len++;
-    }
-  }
-  *Header = (CHAR8) Len;
-  *Tail = 0;
-  Frag.Len = (UINT32) (Frag.Len + StrLen (HostName) + 2); /// 1 for header, 1 
for tail.
-
+  CopyMem (Frag.Bulk + Frag.Len, QueryName, AsciiStrLen (QueryName));
+  Frag.Len = (UINT32) (Frag.Len + AsciiStrLen (QueryName));
+  *(Frag.Bulk + Frag.Len) = 0;
+  Frag.Len ++;
+  
   //
   // Rest query section
   //
-  QuerySection = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);
-  QuerySection->Type = Type;
-  QuerySection->Class = DNS_CLASS_INET;
+  DnsQuery = (DNS_QUERY_SECTION *) (Frag.Bulk + Frag.Len);
+  DnsQuery->Type = Type;
+  DnsQuery->Class = Class;
 
-  QuerySection->Type = HTONS (QuerySection->Type);
-  QuerySection->Class = HTONS (QuerySection->Class);
+  DnsQuery->Type = HTONS (DnsQuery->Type);
+  DnsQuery->Class = HTONS (DnsQuery->Class);
 
-  Frag.Len += sizeof (*QuerySection);
+  Frag.Len += sizeof (*DnsQuery);
 
   //
   // Wrap the Frag in a net buffer.
   //
   *Packet = NetbufFromExt (&Frag, 1, 0, 0, DnsDummyExtFree, NULL);
diff --git a/NetworkPkg/DnsDxe/DnsImpl.h b/NetworkPkg/DnsDxe/DnsImpl.h
index c3a889b..0bfa966 100644
--- a/NetworkPkg/DnsDxe/DnsImpl.h
+++ b/NetworkPkg/DnsDxe/DnsImpl.h
@@ -117,17 +117,19 @@ typedef struct {
 
 typedef struct {
   UINT32                     PacketToLive;
   CHAR16                     *QueryHostName;
   EFI_IPv4_ADDRESS           QueryIpAddress;
+  BOOLEAN                    GeneralLookUp;
   EFI_DNS4_COMPLETION_TOKEN  *Token;
 } DNS4_TOKEN_ENTRY;
 
 typedef struct {
   UINT32                     PacketToLive;
   CHAR16                     *QueryHostName;
   EFI_IPv6_ADDRESS           QueryIpAddress;
+  BOOLEAN                    GeneralLookUp;
   EFI_DNS6_COMPLETION_TOKEN  *Token;
 } DNS6_TOKEN_ENTRY;
 
 union _DNS_FLAGS{
   struct {
@@ -566,10 +568,25 @@ AddDns6ServerIp (
   IN LIST_ENTRY                *Dns6ServerList,
   IN EFI_IPv6_ADDRESS           ServerIp
   );
 
 /**
+  Fill QueryName for IP querying. 
+
+  @param  HostName          Queried HostName    
+
+  @retval EFI_SUCCESS       QName filled successfully.
+  @retval Others            Failed to fill QName.
+  
+**/ 
+UINT8 *
+EFIAPI
+DnsFillQuerytIpQName (
+  IN  CHAR16              *HostName
+  );
+
+/**
   Find out whether the response is valid or invalid.
 
   @param  TokensMap       All DNS transmittal Tokens entry.  
   @param  Identification  Identification for queried packet.  
   @param  Type            Type for queried packet.
@@ -656,26 +673,28 @@ DoDnsQuery (
   IN  DNS_INSTANCE              *Instance,
   IN  NET_BUF                   *Packet
   );
 
 /**
-  Construct the Packet to query Ip.
+  Construct the Packet according query section.
 
   @param  Instance              The DNS instance
-  @param  HostName              Queried HostName  
-  @param  Type                  DNS query Type
-  @param  Packet                The packet for querying Ip
+  @param  QueryName             Queried Name  
+  @param  Type                  Queried Type 
+  @param  Class                 Queried Class 
+  @param  Packet                The packet for query
 
   @retval EFI_SUCCESS           The packet is constructed.
   @retval Others                Failed to construct the Packet.
 
 **/
 EFI_STATUS
-ConstructDNSQueryIp (
+ConstructDNSQuery (
   IN  DNS_INSTANCE              *Instance,
-  IN  CHAR16                    *HostName,
+  IN  CHAR8                     *QueryName,
   IN  UINT16                    Type,
+  IN  UINT16                    Class,
   OUT NET_BUF                   **Packet
   );
 
 /**
   Retransmit the packet.
diff --git a/NetworkPkg/DnsDxe/DnsProtocol.c b/NetworkPkg/DnsDxe/DnsProtocol.c
index 70857c2..d94b755 100644
--- a/NetworkPkg/DnsDxe/DnsProtocol.c
+++ b/NetworkPkg/DnsDxe/DnsProtocol.c
@@ -327,17 +327,20 @@ Dns4HostNameToIp (
   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
@@ -437,13 +440,22 @@ Dns4HostNameToIp (
   TokenEntry->PacketToLive = Token->RetryInterval;
   TokenEntry->QueryHostName = HostName;
   TokenEntry->Token = Token;
 
   //
+  // Construct QName, QType and QClass.
+  //
+  QueryName = DnsFillQuerytIpQName (TokenEntry->QueryHostName);
+  if (QueryName == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+  
+  //
   // Construct DNS Query Packet.
   //
-  Status = ConstructDNSQueryIp (Instance, TokenEntry->QueryHostName, 
DNS_TYPE_A, &Packet);
+  Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_A, DNS_CLASS_INET, 
&Packet);
   if (EFI_ERROR (Status)) {
     if (TokenEntry != NULL) {
       FreePool (TokenEntry);
     }
     
@@ -475,10 +487,14 @@ Dns4HostNameToIp (
     
     NetbufFree (Packet);
   }
   
 ON_EXIT:
+  if (QueryName != NULL) {
+    FreePool (QueryName);
+  }
+  
   gBS->RestoreTPL (OldTpl);
   return Status;
 }
 
 /**
@@ -542,11 +558,114 @@ Dns4GeneralLookUp (
   IN  UINT16                           QType, 
   IN  UINT16                           QClass,
   IN  EFI_DNS4_COMPLETION_TOKEN        *Token
   )
 {
-  return EFI_UNSUPPORTED;
+  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);
+  
+  Instance->MaxRetry = ConfigData->RetryCount;
+  
+  Token->Status = EFI_NOT_READY;
+  Token->RetryCount = 0;
+  Token->RetryInterval = ConfigData->RetryInterval;
+
+  if (Instance->State != DNS_STATE_CONFIGED) {
+    Status = EFI_NOT_STARTED;
+    goto ON_EXIT;
+  }
+
+  //
+  // Check the MaxRetry and RetryInterval values.
+  //
+  if (Instance->MaxRetry == 0) {
+    Instance->MaxRetry = DNS_DEFAULT_RETRY;
+  }
+
+  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;
+  }
+
+  //
+  // 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)) {
+    if (TokenEntry != NULL) {
+      FreePool (TokenEntry);
+    }
+    
+    NetbufFree (Packet);
+  }
+  
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
 }
 
 /**
   This function is used to add/delete/modify DNS cache entry. 
   DNS cache can be normally dynamically updated after the DNS resolve 
succeeds. 
@@ -976,17 +1095,20 @@ Dns6HostNameToIp (
   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
@@ -1085,14 +1207,24 @@ Dns6HostNameToIp (
   
   TokenEntry->PacketToLive = Token->RetryInterval;
   TokenEntry->QueryHostName = HostName;
   TokenEntry->Token = Token;
 
+
+  //
+  // Construct QName, QType and QClass.
+  //
+  QueryName = DnsFillQuerytIpQName (TokenEntry->QueryHostName);
+  if (QueryName == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+  
   //
   // Construct DNS Query Packet.
   //
-  Status = ConstructDNSQueryIp (Instance, TokenEntry->QueryHostName, 
DNS_TYPE_AAAA, &Packet);
+  Status = ConstructDNSQuery (Instance, QueryName, DNS_TYPE_AAAA, 
DNS_CLASS_INET, &Packet);
   if (EFI_ERROR (Status)) {
     if (TokenEntry != NULL) {
       FreePool (TokenEntry);
     }
     
@@ -1124,10 +1256,14 @@ Dns6HostNameToIp (
     
     NetbufFree (Packet);
   }
   
 ON_EXIT:
+  if (QueryName != NULL) {
+    FreePool (QueryName);
+  }
+  
   gBS->RestoreTPL (OldTpl);
   return Status;
 }
 
 /**
@@ -1191,11 +1327,114 @@ Dns6GeneralLookUp (
   IN  UINT16                            QType, 
   IN  UINT16                            QClass,
   IN  EFI_DNS6_COMPLETION_TOKEN         *Token
   )
 {
-  return EFI_UNSUPPORTED;
+  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);
+  
+  Instance->MaxRetry = ConfigData->RetryCount;
+  
+  Token->Status = EFI_NOT_READY;
+  Token->RetryCount = 0;
+  Token->RetryInterval = ConfigData->RetryInterval;
+
+  if (Instance->State != DNS_STATE_CONFIGED) {
+    Status = EFI_NOT_STARTED;
+    goto ON_EXIT;
+  }
+
+  //
+  // Check the MaxRetry and RetryInterval values.
+  //
+  if (Instance->MaxRetry == 0) {
+    Instance->MaxRetry = DNS_DEFAULT_RETRY;
+  }
+
+  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;
+  }
+
+  //
+  // 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)) {
+    if (TokenEntry != NULL) {
+      FreePool (TokenEntry);
+    }
+    
+    NetbufFree (Packet);
+  }
+  
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
 }
 
 /**
   This function is used to add/delete/modify DNS cache entry. 
   DNS cache can be normally dynamically updated after the DNS resolve 
succeeds. 
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to