Add DNS support for target URL directly configuration in UI.

Besides, When we enable the option (Get target info via DHCP) ,
the dhcp server will return target info include the  rootpath,
like the format
"iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>
According to the RFC 4173,the server name region is expressed as
IPv4(192.168.10.20 )or IPv6 ([2000:bbbb::3]) or domain name,
but currently we only support the IP address format.
To enable this feature, we can support both.

Another enhancement is that we can deal with the data received from
the iSCSI login response with an target redirection status,
in which contains the Target Address in the format
domainname[:port][,portal-group-tag] required by RFC 3720.

Cc: Ye Ting <ting...@intel.com>
Cc: Fu Siyuan <siyuan...@intel.com>
Cc: Wu Jiaxin <jiaxin...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Zhang Lubo <lubo.zh...@intel.com>
---
 NetworkPkg/IScsiDxe/IScsiConfig.c            |  76 +++--
 NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h |   4 +-
 NetworkPkg/IScsiDxe/IScsiConfigStrings.uni   |   5 +-
 NetworkPkg/IScsiDxe/IScsiConfigVfr.vfr       |  10 +-
 NetworkPkg/IScsiDxe/IScsiDhcp.c              |  18 +-
 NetworkPkg/IScsiDxe/IScsiDhcp6.c             |  20 +-
 NetworkPkg/IScsiDxe/IScsiDns.c               | 435 +++++++++++++++++++++++++++
 NetworkPkg/IScsiDxe/IScsiDns.h               |  59 ++++
 NetworkPkg/IScsiDxe/IScsiDriver.c            |  18 +-
 NetworkPkg/IScsiDxe/IScsiDxe.inf             |  18 +-
 NetworkPkg/IScsiDxe/IScsiImpl.h              |   6 +
 NetworkPkg/IScsiDxe/IScsiMisc.h              |   4 +
 NetworkPkg/IScsiDxe/IScsiProto.c             |  67 ++++-
 13 files changed, 682 insertions(+), 58 deletions(-)
 create mode 100644 NetworkPkg/IScsiDxe/IScsiDns.c
 create mode 100644 NetworkPkg/IScsiDxe/IScsiDns.h

diff --git a/NetworkPkg/IScsiDxe/IScsiConfig.c 
b/NetworkPkg/IScsiDxe/IScsiConfig.c
index 57571ad..bf4947b 100644
--- a/NetworkPkg/IScsiDxe/IScsiConfig.c
+++ b/NetworkPkg/IScsiDxe/IScsiConfig.c
@@ -364,17 +364,19 @@ IScsiConvertAttemptConfigDataToIfrNvData (
   )
 {
   ISCSI_SESSION_CONFIG_NVDATA   *SessionConfigData;
   ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfigData;
   EFI_IP_ADDRESS                Ip;
+  BOOLEAN                       DnsMode;
 
   //
   // Normal session configuration parameters.
   //
   SessionConfigData                 = &Attempt->SessionConfigData;
   IfrNvData->Enabled                = SessionConfigData->Enabled;
   IfrNvData->IpMode                 = SessionConfigData->IpMode;
+  DnsMode                           = SessionConfigData->DnsMode;
 
   IfrNvData->InitiatorInfoFromDhcp  = SessionConfigData->InitiatorInfoFromDhcp;
   IfrNvData->TargetInfoFromDhcp     = SessionConfigData->TargetInfoFromDhcp;
   IfrNvData->TargetPort             = SessionConfigData->TargetPort;
 
@@ -383,23 +385,37 @@ IScsiConvertAttemptConfigDataToIfrNvData (
     IScsiIpToStr (&Ip, FALSE, IfrNvData->LocalIp);
     CopyMem (&Ip.v4, &SessionConfigData->SubnetMask, sizeof 
(EFI_IPv4_ADDRESS));
     IScsiIpToStr (&Ip, FALSE, IfrNvData->SubnetMask);
     CopyMem (&Ip.v4, &SessionConfigData->Gateway, sizeof (EFI_IPv4_ADDRESS));
     IScsiIpToStr (&Ip, FALSE, IfrNvData->Gateway);
-    CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));
-    IScsiIpToStr (&Ip, FALSE, IfrNvData->TargetIp);
+    if (SessionConfigData->TargetIp.v4.Addr[0] != '\0') {
+      CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof 
(EFI_IPv4_ADDRESS));
+      IScsiIpToStr (&Ip, FALSE, IfrNvData->TargetIp);
+    }
+
   } else if (IfrNvData->IpMode == IP_MODE_IP6) {
     ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));
-    IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);
-    IScsiIpToStr (&Ip, TRUE, IfrNvData->TargetIp);
+    if (SessionConfigData->TargetIp.v6.Addr[0] != '\0') {
+      IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);
+      IScsiIpToStr (&Ip, TRUE, IfrNvData->TargetIp);
+    }
   }
 
   AsciiStrToUnicodeStrS (
     SessionConfigData->TargetName,
     IfrNvData->TargetName,
     sizeof (IfrNvData->TargetName) / sizeof (IfrNvData->TargetName[0])
     );
+
+  if (DnsMode) {
+    AsciiStrToUnicodeStrS (
+      SessionConfigData->TargetUrl,
+      IfrNvData->TargetIp,
+      sizeof (IfrNvData->TargetIp) / sizeof (IfrNvData->TargetIp[0])
+      );
+  }
+
   IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->BootLun);
   IScsiConvertIsIdToString (IfrNvData->IsId, SessionConfigData->IsId);
 
   IfrNvData->ConnectRetryCount = SessionConfigData->ConnectRetryCount;
   IfrNvData->ConnectTimeout    = SessionConfigData->ConnectTimeout;
@@ -557,18 +573,30 @@ IScsiConvertIfrNvDataToAttemptConfigData (
     }
     //
     // Validate target configuration if DHCP isn't deployed.
     //
     if (!Attempt->SessionConfigData.TargetInfoFromDhcp && 
Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {
-      if (!IpIsUnicast (&Attempt->SessionConfigData.TargetIp, 
IfrNvData->IpMode)) {
-        CreatePopUp (
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
-          &Key,
-          L"Target IP is invalid!",
-          NULL
-          );
-        return EFI_INVALID_PARAMETER;
+      if (!Attempt->SessionConfigData.DnsMode) {
+        if (!IpIsUnicast (&Attempt->SessionConfigData.TargetIp, 
IfrNvData->IpMode)) {
+          CreatePopUp (
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+            &Key,
+            L"Target IP is invalid!",
+            NULL
+            );
+          return EFI_INVALID_PARAMETER;
+        }
+      } else {
+        if (Attempt->SessionConfigData.TargetUrl[0] == '\0') {
+          CreatePopUp (
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+            &Key,
+            L"iSCSI target Url should not be NULL!",
+            NULL
+            );
+          return EFI_INVALID_PARAMETER;
+        }
       }
 
       //
       // Validate iSCSI target name configuration again:
       // The format of iSCSI target name is already verified in 
IScsiFormCallback() when
@@ -2134,11 +2162,11 @@ IScsiFormCallback (
   )
 {
   ISCSI_FORM_CALLBACK_INFO    *Private;
   UINTN                       BufferSize;
   CHAR8                       *IScsiName;
-  CHAR8                       IpString[IP_STR_MAX_SIZE];
+  CHAR8                       IpString[ISCSI_NAME_MAX_SIZE];
   CHAR8                       LunString[ISCSI_LUN_STR_MAX_LEN];
   UINT64                      Lun;
   EFI_IP_ADDRESS              HostIp;
   EFI_IP_ADDRESS              SubnetMask;
   EFI_IP_ADDRESS              Gateway;
@@ -2333,18 +2361,12 @@ IScsiFormCallback (
       break;
 
     case KEY_IP_MODE:
       switch (Value->u8) {
       case IP_MODE_IP6:
-        ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));
-        IScsiIpToStr (&Private->Current->SessionConfigData.TargetIp, TRUE, 
IfrNvData->TargetIp);
-        Private->Current->AutoConfigureMode = 0;
-        break;
-
       case IP_MODE_IP4:
         ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));
-        IScsiIpToStr (&Private->Current->SessionConfigData.TargetIp, FALSE, 
IfrNvData->TargetIp);
         Private->Current->AutoConfigureMode = 0;
 
         break;
       }
 
@@ -2406,19 +2428,19 @@ IScsiFormCallback (
       break;
 
     case KEY_TARGET_IP:
       UnicodeStrToAsciiStrS (IfrNvData->TargetIp, IpString, sizeof (IpString));
       Status = IScsiAsciiStrToIp (IpString, IfrNvData->IpMode, &HostIp);
-      if (EFI_ERROR (Status) || IP4_IS_LOCAL_BROADCAST (EFI_NTOHL(HostIp.v4)) 
|| IP4_IS_UNSPECIFIED (EFI_NTOHL(HostIp.v4))) {
-        CreatePopUp (
-          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
-          &Key,
-          L"Invalid IP address!",
-          NULL
-          );       
-        Status = EFI_INVALID_PARAMETER;
+      if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, IfrNvData->IpMode)) {
+      //
+      // The target is expressed in URL format or an invalid Ip address, just 
save.
+      //
+      Private->Current->SessionConfigData.DnsMode = TRUE;
+      ZeroMem (&Private->Current->SessionConfigData.TargetIp, sizeof 
(Private->Current->SessionConfigData.TargetIp));
+      UnicodeStrToAsciiStrS (IfrNvData->TargetIp, 
Private->Current->SessionConfigData.TargetUrl, ISCSI_NAME_MAX_SIZE);
       } else {
+        Private->Current->SessionConfigData.DnsMode = FALSE;
         CopyMem (&Private->Current->SessionConfigData.TargetIp, &HostIp, 
sizeof (HostIp));
       }
 
       break;
 
diff --git a/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h 
b/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h
index 56ebb50..3223582 100644
--- a/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h
+++ b/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h
@@ -1,9 +1,9 @@
 /** @file
   Define NVData structures used by the iSCSI configuration component.
 
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
 http://opensource.org/licenses/bsd-license.php
 
@@ -152,11 +152,11 @@ typedef struct _ISCSI_CONFIG_IFR_NVDATA {
   CHAR16  LocalIp[IP4_STR_MAX_SIZE];
   CHAR16  SubnetMask[IP4_STR_MAX_SIZE];
   CHAR16  Gateway[IP4_STR_MAX_SIZE];
 
   CHAR16  TargetName[ISCSI_NAME_MAX_SIZE];
-  CHAR16  TargetIp[IP_STR_MAX_SIZE];
+  CHAR16  TargetIp[ISCSI_NAME_MAX_SIZE];
   UINT16  TargetPort;
   CHAR16  BootLun[ISCSI_LUN_STR_MAX_LEN];
 
   UINT8   AuthenticationType;
 
diff --git a/NetworkPkg/IScsiDxe/IScsiConfigStrings.uni 
b/NetworkPkg/IScsiDxe/IScsiConfigStrings.uni
index 7a80fab..8ebdae2 100644
--- a/NetworkPkg/IScsiDxe/IScsiConfigStrings.uni
+++ b/NetworkPkg/IScsiDxe/IScsiConfigStrings.uni
@@ -1,8 +1,8 @@
 // *++
 //
-// Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
 // This program and the accompanying materials
 // are licensed and made available under the terms and conditions of the BSD 
License
 // which accompanies this distribution.  The full text of the license may be 
found at
 // http://opensource.org/licenses/bsd-license.php
 //
@@ -61,11 +61,12 @@
 #string STR_ISCSI_LOCAL_MASK            #language en-US "  Initiator Subnet 
Mask"
 #string STR_ISCSI_LOCAL_GATEWAY         #language en-US "  Gateway"
 #string STR_ISCSI_IP_ADDRESS_HELP       #language en-US "Enter IP address in 
dotted-decimal notation."
 #string STR_ISCSI_TARGET_NAME           #language en-US "  Target Name"
 #string STR_ISCSI_TARGET_NAME_HELP      #language en-US "The worldwide unique 
name of the target. Only iqn. format is accepted."
-#string STR_ISCSI_TARGET_IP_ADDRESS     #language en-US "  Target IP Address"
+#string STR_ISCSI_TARGET_ADDRESS        #language en-US "  Target Address"
+#string STR_ISCSI_TARGET_ADDRESS_HELP   #language en-US "Enter Target address 
in dotted-decimal notation or URL format.You need to configure DNS server 
address in advance if input a URL format."
 #string STR_ISCSI_TARGET_PORT           #language en-US "  Target Port"
 #string STR_ISCSI_BOOT_LUN              #language en-US "  Boot LUN"
 #string STR_ISCSI_BOOT_LUN_HELP         #language en-US "Hexadecimal 
representation of the LU number. Examples are: 4752-3A4F-6b7e-2F99, 
6734-9-156f-127, 4186-9"
 #string STR_ISCSI_ENABLE_DHCP           #language en-US "Enable DHCP"         
 #string STR_ISCSI_ENABLE_DHCP_ON_TARGET #language en-US "Get target info via 
DHCP"
diff --git a/NetworkPkg/IScsiDxe/IScsiConfigVfr.vfr 
b/NetworkPkg/IScsiDxe/IScsiConfigVfr.vfr
index db77c0f..89d1e39 100644
--- a/NetworkPkg/IScsiDxe/IScsiConfigVfr.vfr
+++ b/NetworkPkg/IScsiDxe/IScsiConfigVfr.vfr
@@ -1,9 +1,9 @@
 /** @file
   VFR file used by the iSCSI configuration component.
   
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
 http://opensource.org/licenses/bsd-license.php
 
@@ -247,16 +247,16 @@ formset
             minsize = ISCSI_NAME_IFR_MIN_SIZE,
             maxsize = ISCSI_NAME_IFR_MAX_SIZE,
     endstring;
 
     string  varid   = ISCSI_CONFIG_IFR_NVDATA.TargetIp,
-            prompt  = STRING_TOKEN(STR_ISCSI_TARGET_IP_ADDRESS),
-            help    = STRING_TOKEN(STR_ISCSI_IP_ADDRESS_HELP),
+            prompt  = STRING_TOKEN(STR_ISCSI_TARGET_ADDRESS),
+            help    = STRING_TOKEN(STR_ISCSI_TARGET_ADDRESS_HELP),
             flags   = INTERACTIVE,
             key     = KEY_TARGET_IP,
-            minsize = IP_MIN_SIZE,
-            maxsize = IP_MAX_SIZE,
+            minsize = ISCSI_NAME_IFR_MIN_SIZE,
+            maxsize = ISCSI_NAME_IFR_MAX_SIZE,
     endstring;
 
     numeric varid   = ISCSI_CONFIG_IFR_NVDATA.TargetPort,
             prompt  = STRING_TOKEN(STR_ISCSI_TARGET_PORT),
             help    = STRING_TOKEN(STR_ISCSI_TARGET_PORT),
diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp.c b/NetworkPkg/IScsiDxe/IScsiDhcp.c
index 0e42805..fc41148 100644
--- a/NetworkPkg/IScsiDxe/IScsiDhcp.c
+++ b/NetworkPkg/IScsiDxe/IScsiDhcp.c
@@ -121,15 +121,25 @@ IScsiDhcpExtractRootPath (
     IpMode = ConfigNvData->IpMode;
   } else {
     IpMode = ConfigData->AutoConfigureMode;
   }
 
-  Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
-  CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));
+  //
+  // Server name is expressed as domain name, just save it.
+  //
+  if ((!NET_IS_DIGIT (*(Field->Str))) && (*(Field->Str) != '[')) {
+    ConfigNvData->DnsMode = TRUE;
+    CopyMem (&ConfigNvData->TargetUrl, Field->Str, Field->Len);
+    ConfigNvData->TargetUrl[Field->Len + 1] = '\0';
+  } else {
+    ZeroMem(ConfigNvData->TargetUrl, sizeof (ConfigNvData->TargetUrl));
+    Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
+    CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));
 
-  if (EFI_ERROR (Status)) {
-    goto ON_EXIT;
+    if (EFI_ERROR (Status)) {
+      goto ON_EXIT;
+    }
   }
   //
   // Check the protocol type.
   //
   Field = &Fields[RP_FIELD_IDX_PROTOCOL];
diff --git a/NetworkPkg/IScsiDxe/IScsiDhcp6.c b/NetworkPkg/IScsiDxe/IScsiDhcp6.c
index 0cd0bd8..9c6fc0e 100644
--- a/NetworkPkg/IScsiDxe/IScsiDhcp6.c
+++ b/NetworkPkg/IScsiDxe/IScsiDhcp6.c
@@ -148,17 +148,27 @@ IScsiDhcp6ExtractRootPath (
     IpMode = ConfigNvData->IpMode;
   } else {
     IpMode = ConfigData->AutoConfigureMode;
   }
 
-  Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
-  CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));
-
+  //
+  // Server name is expressed as domain name, just save it.
+  //
+  if ((!NET_IS_DIGIT (*(Field->Str))) && (*(Field->Str) != '[')) {
+    ConfigNvData->DnsMode = TRUE;
+    CopyMem (&ConfigNvData->TargetUrl, Field->Str, Field->Len);
+    ConfigNvData->TargetUrl[Field->Len + 1] = '\0';
+  } else {
+    ZeroMem(&ConfigNvData->TargetUrl, sizeof (ConfigNvData->TargetUrl));
+    Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);
+    CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));
 
-  if (EFI_ERROR (Status)) {
-    goto ON_EXIT;
+    if (EFI_ERROR (Status)) {
+      goto ON_EXIT;
+    }
   }
+
   //
   // Check the protocol type.
   //
   Field = &Fields[RP_FIELD_IDX_PROTOCOL];
   if ((Field->Str != NULL) && ((*(Field->Str) - '0') != EFI_IP_PROTO_TCP)) {
diff --git a/NetworkPkg/IScsiDxe/IScsiDns.c b/NetworkPkg/IScsiDxe/IScsiDns.c
new file mode 100644
index 0000000..9a5f83e
--- /dev/null
+++ b/NetworkPkg/IScsiDxe/IScsiDns.c
@@ -0,0 +1,435 @@
+/** @file
+ Perform DNS resolution based on UEFI DNS protocols.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IScsiImpl.h"
+
+/**
+  Notify the callback function when an event is triggered.
+
+  @param[in]  Event           The triggered event.
+  @param[in]  Context         The opaque parameter to the function.
+
+**/
+VOID
+EFIAPI
+IScsiCommonNotify (
+  IN EFI_EVENT           Event,
+  IN VOID                *Context
+  )
+{
+  *((BOOLEAN *) Context) = TRUE;
+}
+
+/**
+  Retrieve the host address using the EFI_DNS4_PROTOCOL.
+
+  @param[in]  Image               The handle of the driver image.
+  @param[in]  Controller          The handle of the controller.
+  @param[in]  NvData              The Session config data structure.
+
+  @retval EFI_SUCCESS             Operation succeeded.
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
+  @retval EFI_DEVICE_ERROR        An unexpected network error occurred.
+  @retval Others                  Other errors as indicated.
+
+**/
+EFI_STATUS
+IScsiDns4 (
+  IN     EFI_HANDLE                      Image,
+  IN     EFI_HANDLE                      Controller,
+  IN OUT ISCSI_SESSION_CONFIG_NVDATA     *NvData
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_DNS4_PROTOCOL               *Dns4;
+  EFI_DNS4_CONFIG_DATA            Dns4CfgData;
+  EFI_DNS4_COMPLETION_TOKEN       Token;
+  BOOLEAN                         IsDone;
+  EFI_HANDLE                      Dns4Handle;
+  EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2;
+  EFI_IPv4_ADDRESS                *DnsServerList;
+  UINTN                           DnsServerListCount;
+  UINTN                           DataSize;
+  CHAR16                          *HostName;
+
+  DnsServerList      = NULL;
+  DnsServerListCount = 0;
+  Dns4Handle         = NULL;
+  Dns4               = NULL;
+  ZeroMem (&Token, sizeof (EFI_DNS4_COMPLETION_TOKEN));
+
+  //
+  // Get DNS server list from EFI IPv4 Configuration II protocol.
+  //
+  Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID 
**) &Ip4Config2);
+  if (!EFI_ERROR (Status)) {
+    //
+    // Get the required size.
+    //
+    DataSize = 0;
+    Status   = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, 
&DataSize, NULL);
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+      DnsServerList = AllocatePool (DataSize);
+      if (DnsServerList == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      Status   = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeDnsServer, 
&DataSize, DnsServerList);
+      if (EFI_ERROR (Status)) {
+        FreePool (DnsServerList);
+        DnsServerList = NULL;
+      } else {
+        DnsServerListCount = DataSize / sizeof (EFI_IPv4_ADDRESS);
+      }
+    }
+  }
+
+
+  //
+  // Create a DNS child instance and get the protocol.
+  //
+  Status = NetLibCreateServiceChild (
+             Controller,
+             Image,
+             &gEfiDns4ServiceBindingProtocolGuid,
+             &Dns4Handle
+             );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Status = gBS->OpenProtocol (
+                  Dns4Handle,
+                  &gEfiDns4ProtocolGuid,
+                  (VOID **) &Dns4,
+                  Image,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // Configure DNS4 instance for the DNS server address and protocol.
+  //
+  ZeroMem (&Dns4CfgData, sizeof (Dns4CfgData));
+  Dns4CfgData.DnsServerListCount = DnsServerListCount;
+  Dns4CfgData.DnsServerList      = DnsServerList;
+  Dns4CfgData.EnableDnsCache     = TRUE;
+  IP4_COPY_ADDRESS (&Dns4CfgData.StationIp, &NvData->LocalIp);
+  IP4_COPY_ADDRESS (&Dns4CfgData.SubnetMask, &NvData->SubnetMask);
+  Dns4CfgData.Protocol           = EFI_IP_PROTO_UDP;
+  Status = Dns4->Configure (
+                   Dns4,
+                   &Dns4CfgData
+                   );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // Create event to set the is done flag when name resolution is finished.
+  //
+  ZeroMem (&Token, sizeof (Token));
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  IScsiCommonNotify,
+                  &IsDone,
+                  &Token.Event
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // Start asynchronous name resolution.
+  //
+  Token.Status = EFI_NOT_READY;
+  IsDone       = FALSE;
+
+  HostName = (CHAR16 *) AllocateZeroPool (ISCSI_NAME_MAX_SIZE);
+  if (HostName == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  AsciiStrToUnicodeStrS (
+    NvData->TargetUrl,
+    HostName,
+    ISCSI_NAME_MAX_SIZE
+    );
+
+  Status = Dns4->HostNameToIp (Dns4, HostName, &Token);
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  while (!IsDone) {
+    Dns4->Poll (Dns4);
+  }
+
+  //
+  // Name resolution is done, check result.
+  //
+  Status = Token.Status;
+  if (!EFI_ERROR (Status)) {
+    if (Token.RspData.H2AData == NULL) {
+      Status = EFI_DEVICE_ERROR;
+      goto Exit;
+    }
+    if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList 
== NULL) {
+      Status = EFI_DEVICE_ERROR;
+      goto Exit;
+    }
+    //
+    // We just return the first IP address from DNS protocol.
+    //
+    IP4_COPY_ADDRESS (&NvData->TargetIp.v4, Token.RspData.H2AData->IpList);
+    Status = EFI_SUCCESS;
+  }
+
+Exit:
+
+  if (Token.Event != NULL) {
+    gBS->CloseEvent (Token.Event);
+  }
+  if (Token.RspData.H2AData != NULL) {
+    if (Token.RspData.H2AData->IpList != NULL) {
+      FreePool (Token.RspData.H2AData->IpList);
+    }
+    FreePool (Token.RspData.H2AData);
+  }
+
+  if (Dns4 != NULL) {
+    Dns4->Configure (Dns4, NULL);
+
+    gBS->CloseProtocol (
+           Dns4Handle,
+           &gEfiDns4ProtocolGuid,
+           Image,
+           Controller
+           );
+  }
+
+  if (Dns4Handle != NULL) {
+    NetLibDestroyServiceChild (
+      Controller,
+      Image,
+      &gEfiDns4ServiceBindingProtocolGuid,
+      Dns4Handle
+      );
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the host address using the EFI_DNS6_PROTOCOL.
+
+  @param[in]  Image               The handle of the driver image.
+  @param[in]  Controller          The handle of the controller.
+  @param[in]  NvData              The Session config data structure.
+
+  @retval EFI_SUCCESS             Operation succeeded.
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
+  @retval EFI_DEVICE_ERROR        An unexpected network error occurred.
+  @retval Others                  Other errors as indicated.
+
+**/
+EFI_STATUS
+IScsiDns6 (
+  IN     EFI_HANDLE                      Image,
+  IN     EFI_HANDLE                      Controller,
+  IN OUT ISCSI_SESSION_CONFIG_NVDATA     *NvData
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_DNS6_PROTOCOL               *Dns6;
+  EFI_DNS6_CONFIG_DATA            Dns6ConfigData;
+  EFI_DNS6_COMPLETION_TOKEN       Token;
+  EFI_HANDLE                      Dns6Handle;
+  EFI_IP6_CONFIG_PROTOCOL         *Ip6Config;
+  EFI_IPv6_ADDRESS                *DnsServerList;
+  UINTN                           DnsServerListCount;
+  UINTN                           DataSize;
+  BOOLEAN                         IsDone;
+  CHAR16                          *HostName;
+
+  DnsServerList       = NULL;
+  DnsServerListCount  = 0;
+  Dns6                = NULL;
+  Dns6Handle          = NULL;
+  ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));
+
+  //
+  // Get DNS server list from EFI IPv6 Configuration protocol.
+  //
+  Status = gBS->HandleProtocol (Controller, &gEfiIp6ConfigProtocolGuid, (VOID 
**) &Ip6Config);
+  if (!EFI_ERROR (Status)) {
+    //
+    // Get the required size.
+    //
+    DataSize = 0;
+    Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, 
&DataSize, NULL);
+    if (Status == EFI_BUFFER_TOO_SMALL) {
+      DnsServerList = AllocatePool (DataSize);
+      if (DnsServerList == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, 
&DataSize, DnsServerList);
+      if (EFI_ERROR (Status)) {
+        FreePool (DnsServerList);
+        DnsServerList = NULL;
+      } else {
+        DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);
+      }
+    }
+  }
+
+  //
+  // Create a DNSv6 child instance and get the protocol.
+  //
+  Status = NetLibCreateServiceChild (
+             Controller,
+             Image,
+             &gEfiDns6ServiceBindingProtocolGuid,
+             &Dns6Handle
+             );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Status = gBS->OpenProtocol (
+                  Dns6Handle,
+                  &gEfiDns6ProtocolGuid,
+                  (VOID **) &Dns6,
+                  Image,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // Configure DNS6 instance for the DNS server address and protocol.
+  //
+  ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));
+  Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;
+  Dns6ConfigData.DnsServerList  = DnsServerList;
+  Dns6ConfigData.EnableDnsCache = TRUE;
+  Dns6ConfigData.Protocol       = EFI_IP_PROTO_UDP;
+  Status = Dns6->Configure (
+                   Dns6,
+                   &Dns6ConfigData
+                   );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  Token.Status = EFI_NOT_READY;
+  IsDone       = FALSE;
+  //
+  // Create event to set the  IsDone flag when name resolution is finished.
+  //
+  Status = gBS->CreateEvent (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  IScsiCommonNotify,
+                  &IsDone,
+                  &Token.Event
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  //
+  // Start asynchronous name resolution.
+  //
+  HostName = (CHAR16 *) AllocateZeroPool (ISCSI_NAME_MAX_SIZE);
+  if (HostName == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  AsciiStrToUnicodeStrS (
+    NvData->TargetUrl,
+    HostName,
+    ISCSI_NAME_MAX_SIZE
+    );
+  Status = Dns6->HostNameToIp (Dns6, HostName, &Token);
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  while (!IsDone) {
+    Dns6->Poll (Dns6);
+  }
+
+  //
+  // Name resolution is done, check result.
+  //
+  Status = Token.Status;
+  if (!EFI_ERROR (Status)) {
+    if (Token.RspData.H2AData == NULL) {
+      Status = EFI_DEVICE_ERROR;
+      goto Exit;
+    }
+    if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList 
== NULL) {
+      Status = EFI_DEVICE_ERROR;
+      goto Exit;
+    }
+    //
+    // We just return the first IPv6 address from DNS protocol.
+    //
+    IP6_COPY_ADDRESS (&NvData->TargetIp.v6, Token.RspData.H2AData->IpList);
+    Status = EFI_SUCCESS;
+  }
+
+Exit:
+
+  if (Token.Event != NULL) {
+    gBS->CloseEvent (Token.Event);
+  }
+  if (Token.RspData.H2AData != NULL) {
+    if (Token.RspData.H2AData->IpList != NULL) {
+      FreePool (Token.RspData.H2AData->IpList);
+    }
+    FreePool (Token.RspData.H2AData);
+  }
+
+  if (Dns6 != NULL) {
+    Dns6->Configure (Dns6, NULL);
+
+    gBS->CloseProtocol (
+           Dns6Handle,
+           &gEfiDns6ProtocolGuid,
+           Image,
+           Controller
+           );
+  }
+
+  if (Dns6Handle != NULL) {
+    NetLibDestroyServiceChild (
+      Controller,
+      Image,
+      &gEfiDns6ServiceBindingProtocolGuid,
+      Dns6Handle
+      );
+  }
+
+  return Status;
+}
+
diff --git a/NetworkPkg/IScsiDxe/IScsiDns.h b/NetworkPkg/IScsiDxe/IScsiDns.h
new file mode 100644
index 0000000..b9da210
--- /dev/null
+++ b/NetworkPkg/IScsiDxe/IScsiDns.h
@@ -0,0 +1,59 @@
+/** @file
+ The header file of routines for IScsi driver to perform DNS
+ resolution based on UEFI DNS protocols.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _ISCSI_DNS_H_
+#define _ISCSI_DNS_H_
+
+/**
+  Retrieve the host address using the EFI_DNS4_PROTOCOL.
+
+  @param[in]  Image               The handle of the driver image.
+  @param[in]  Controller          The handle of the controller.
+  @param[in]  NvData              The Session config data structure.
+
+  @retval EFI_SUCCESS             Operation succeeded.
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
+  @retval EFI_DEVICE_ERROR        An unexpected network error occurred.
+  @retval Others                  Other errors as indicated.
+
+**/
+EFI_STATUS
+IScsiDns4 (
+  IN     EFI_HANDLE                      Image,
+  IN     EFI_HANDLE                      Controller,
+  IN OUT ISCSI_SESSION_CONFIG_NVDATA     *NvData
+  );
+
+/**
+  Retrieve the host address using the EFI_DNS6_PROTOCOL.
+
+  @param[in]  Image               The handle of the driver image.
+  @param[in]  Controller          The handle of the controller.
+  @param[in]  NvData              The Session config data structure.
+
+  @retval EFI_SUCCESS             Operation succeeded.
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.
+  @retval EFI_DEVICE_ERROR        An unexpected network error occurred.
+  @retval Others                  Other errors as indicated.
+
+**/
+EFI_STATUS
+IScsiDns6 (
+  IN     EFI_HANDLE                      Image,
+  IN     EFI_HANDLE                      Controller,
+  IN OUT ISCSI_SESSION_CONFIG_NVDATA     *NvData
+  );
+
+#endif
\ No newline at end of file
diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.c 
b/NetworkPkg/IScsiDxe/IScsiDriver.c
index ac10fa2..b1f3cf9 100644
--- a/NetworkPkg/IScsiDxe/IScsiDriver.c
+++ b/NetworkPkg/IScsiDxe/IScsiDriver.c
@@ -250,19 +250,23 @@ IScsiSupported (
 {
   EFI_STATUS                Status;
   EFI_GUID                  *IScsiServiceBindingGuid;
   EFI_GUID                  *TcpServiceBindingGuid;
   EFI_GUID                  *DhcpServiceBindingGuid;
+  EFI_GUID                  *DnsServiceBindingGuid;
 
   if (IpVersion == IP_VERSION_4) {
     IScsiServiceBindingGuid  = &gIScsiV4PrivateGuid;
     TcpServiceBindingGuid    = &gEfiTcp4ServiceBindingProtocolGuid;
     DhcpServiceBindingGuid   = &gEfiDhcp4ServiceBindingProtocolGuid;
+    DnsServiceBindingGuid    = &gEfiDns4ServiceBindingProtocolGuid;
+
   } else {
     IScsiServiceBindingGuid  = &gIScsiV6PrivateGuid;
     TcpServiceBindingGuid    = &gEfiTcp6ServiceBindingProtocolGuid;
     DhcpServiceBindingGuid   = &gEfiDhcp6ServiceBindingProtocolGuid;
+    DnsServiceBindingGuid    = &gEfiDns6ServiceBindingProtocolGuid;
   }
 
   Status = gBS->OpenProtocol (
                   ControllerHandle,
                   IScsiServiceBindingGuid,
@@ -303,11 +307,23 @@ IScsiSupported (
                     );
     if (EFI_ERROR (Status)) {
       return EFI_UNSUPPORTED;
     }
   }
-  
+
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  DnsServiceBindingGuid,
+                  NULL,
+                  This->DriverBindingHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
   return EFI_SUCCESS;
 }
 
 
 /**
diff --git a/NetworkPkg/IScsiDxe/IScsiDxe.inf b/NetworkPkg/IScsiDxe/IScsiDxe.inf
index 8952120..df825bc 100644
--- a/NetworkPkg/IScsiDxe/IScsiDxe.inf
+++ b/NetworkPkg/IScsiDxe/IScsiDxe.inf
@@ -2,11 +2,11 @@
 #  Client-side iSCSI service.
 #
 #  The iSCSI driver provides iSCSI service in the preboot environment and 
supports
 #  booting over iSCSI.
 #                                                    
-# Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
 # This program and the accompanying materials
 # are licensed and made available under the terms and conditions of the BSD 
License
 # which accompanies this distribution.  The full text of the license may be 
found at
 # http://opensource.org/licenses/bsd-license.php
 #
@@ -48,10 +48,12 @@
   IScsiConfigVfr.vfr
   IScsiDhcp.c
   IScsiDhcp.h
   IScsiDhcp6.c
   IScsiDhcp6.h
+  IScsiDns.c
+  IScsiDns.h
   IScsiDriver.c
   IScsiDriver.h
   IScsiExtScsiPassThru.c
   IScsiIbft.c
   IScsiIbft.h
@@ -88,17 +90,23 @@
 [Protocols]
   gEfiAcpiTableProtocolGuid                     ## SOMETIMES_CONSUMES ## 
SystemTable
   gEfiDriverBindingProtocolGuid                 ## SOMETIMES_PRODUCES
   gEfiPciIoProtocolGuid                         ## SOMETIMES_CONSUMES
   gEfiDhcp4ProtocolGuid                         ## TO_START
-  gEfiDhcp6ProtocolGuid                         ## TO_START  
+  gEfiDhcp6ProtocolGuid                         ## TO_START
   gEfiDhcp4ServiceBindingProtocolGuid           ## TO_START
-  gEfiDhcp6ServiceBindingProtocolGuid           ## TO_START  
+  gEfiDhcp6ServiceBindingProtocolGuid           ## TO_START
+  gEfiDns4ServiceBindingProtocolGuid            ## TO_START
+  gEfiDns4ProtocolGuid                          ## TO_START
+  gEfiDns6ServiceBindingProtocolGuid            ## TO_START
+  gEfiDns6ProtocolGuid                          ## TO_START
+  gEfiIp4Config2ProtocolGuid                    ## SOMETIMES_CONSUMES
+  gEfiIp6ConfigProtocolGuid                     ## SOMETIMES_CONSUMES
   gEfiTcp4ProtocolGuid                          ## TO_START
-  gEfiTcp6ProtocolGuid                          ## TO_START  
+  gEfiTcp6ProtocolGuid                          ## TO_START
   gEfiTcp4ServiceBindingProtocolGuid            ## TO_START
-  gEfiTcp6ServiceBindingProtocolGuid            ## TO_START  
+  gEfiTcp6ServiceBindingProtocolGuid            ## TO_START
   gEfiExtScsiPassThruProtocolGuid               ## BY_START
   gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
   ## TO_START
   ## PRODUCES
   gEfiDevicePathProtocolGuid
diff --git a/NetworkPkg/IScsiDxe/IScsiImpl.h b/NetworkPkg/IScsiDxe/IScsiImpl.h
index af46871..9221b83 100644
--- a/NetworkPkg/IScsiDxe/IScsiImpl.h
+++ b/NetworkPkg/IScsiDxe/IScsiImpl.h
@@ -26,12 +26,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include <Protocol/HiiConfigAccess.h>
 
 #include <Protocol/Ip6.h>
 #include <Protocol/Dhcp4.h>
 #include <Protocol/Dhcp6.h>
+#include <Protocol/Dns4.h>
+#include <Protocol/Dns6.h>
 #include <Protocol/Tcp4.h>
 #include <Protocol/Tcp6.h>
+#include <Protocol/Ip4Config2.h>
+#include <Protocol/Ip6Config.h>
 
 #include <Protocol/AuthenticationInfo.h>
 #include <Protocol/IScsiInitiatorName.h>
 #include <Protocol/ScsiPassThruExt.h>
 #include <Protocol/AdapterInformation.h>
@@ -60,12 +64,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 #include "IScsiDriver.h"
 #include "IScsiProto.h"
 #include "IScsiCHAP.h"
 #include "IScsiDhcp.h"
 #include "IScsiDhcp6.h"
+
 #include "IScsiIbft.h"
 #include "IScsiMisc.h"
+#include "IScsiDns.h"
 #include "IScsiConfig.h"
 
 #define ISCSI_AUTH_INITIAL        0
 
 #define ISCSI_SESSION_SIGNATURE   SIGNATURE_32 ('I', 'S', 'S', 'N')
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h
index 912a871..7d30197 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.h
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.h
@@ -43,10 +43,11 @@ typedef struct _ISCSI_SESSION_CONFIG_NVDATA {
   EFI_IPv4_ADDRESS  SubnetMask;
   EFI_IP_ADDRESS    Gateway;
 
   BOOLEAN           InitiatorInfoFromDhcp;
   BOOLEAN           TargetInfoFromDhcp;
+
   CHAR8             TargetName[ISCSI_NAME_MAX_SIZE];
   EFI_IP_ADDRESS    TargetIp;
   UINT8             PrefixLength;
   UINT8             BootLun[8];
 
@@ -55,10 +56,13 @@ typedef struct _ISCSI_SESSION_CONFIG_NVDATA {
   UINT8             IsId[6];
 
   BOOLEAN           RedirectFlag;
   UINT16            OriginalTargetPort;     // The port of proxy/virtual 
target.
   EFI_IP_ADDRESS    OriginalTargetIp;       // The address of proxy/virtual 
target.
+
+  BOOLEAN           DnsMode;  // Flag indicate whether the Target address is 
expressed as URL format.
+  CHAR8             TargetUrl[ISCSI_NAME_MAX_SIZE];
   
 } ISCSI_SESSION_CONFIG_NVDATA;
 #pragma pack()
 
 /**
diff --git a/NetworkPkg/IScsiDxe/IScsiProto.c b/NetworkPkg/IScsiDxe/IScsiProto.c
index a67bbd5..e2b5349 100644
--- a/NetworkPkg/IScsiDxe/IScsiProto.c
+++ b/NetworkPkg/IScsiDxe/IScsiProto.c
@@ -211,10 +211,11 @@ IScsiCreateConnection (
   ISCSI_CONNECTION             *Conn;
   TCP_IO_CONFIG_DATA           TcpIoConfig;
   TCP4_IO_CONFIG_DATA          *Tcp4IoConfig;
   TCP6_IO_CONFIG_DATA          *Tcp6IoConfig;
   EFI_STATUS                   Status;
+  EFI_INPUT_KEY                Key;
 
   Private = Session->Private;
   NvData  = &Session->ConfigData->SessionConfigData;
 
   Conn = AllocateZeroPool (sizeof (ISCSI_CONNECTION));
@@ -253,10 +254,31 @@ IScsiCreateConnection (
   //
   Conn->MaxRecvDataSegmentLength  = DEFAULT_MAX_RECV_DATA_SEG_LEN;
   Conn->HeaderDigest              = IScsiDigestNone;
   Conn->DataDigest                = IScsiDigestNone;
 
+  if (NvData->DnsMode) {
+    //
+    // perform dns process if target address expressed by domain name.
+    //
+    if (!Conn->Ipv6Flag) {
+      Status = IScsiDns4 (Private->Image, Private->Controller, NvData);
+    } else {
+      Status = IScsiDns6 (Private->Image, Private->Controller, NvData);
+    }
+
+    if (EFI_ERROR(Status)) {
+      CreatePopUp (
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+        &Key,
+        L"The configuration of Target address or DNS server address is 
invalid",
+        NULL
+        );
+      return NULL;
+    }
+  }
+
   if (!Conn->Ipv6Flag) {
     Tcp4IoConfig = &TcpIoConfig.Tcp4IoConfigData;
     
     CopyMem (&Tcp4IoConfig->LocalIp, &NvData->LocalIp, sizeof 
(EFI_IPv4_ADDRESS));
     CopyMem (&Tcp4IoConfig->SubnetMask, &NvData->SubnetMask, sizeof 
(EFI_IPv4_ADDRESS));
@@ -1074,16 +1096,19 @@ IScsiUpdateTargetAddress (
   CHAR8                        *IpStr;
   EFI_STATUS                   Status;
   UINTN                        Number;
   UINT8                        IpMode;
   ISCSI_SESSION_CONFIG_NVDATA  *NvData;
+  EFI_INPUT_KEY                Key;
+  BOOLEAN                      IsExpressedIp;
 
   KeyValueList = IScsiBuildKeyValueList (Data, Len);
   if (KeyValueList == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
 
+  IsExpressedIp = TRUE;
   Status = EFI_NOT_FOUND;
   NvData = &Session->ConfigData->SessionConfigData;
  
   while (TRUE) {
     TargetAddress = IScsiGetValueByKeyFromList (KeyValueList, 
ISCSI_KEY_TARGET_ADDRESS);
@@ -1129,12 +1154,17 @@ IScsiUpdateTargetAddress (
       TargetAddress ++;
 
     } else {
       //
       // The domainname of the target is presented in the format of a DNS host 
name.
-      // Temporary not supported.
-      continue;
+      //
+      IpStr = TargetAddress;
+
+      while ((*TargetAddress != '\0') && (*TargetAddress != ':') && 
(*TargetAddress != ',')) {
+        TargetAddress++;
+      }
+      IsExpressedIp = FALSE;
     }
 
     //
     // Save the origial user setting which specifies the proxy/virtual iSCSI 
target.
     //
@@ -1176,15 +1206,38 @@ IScsiUpdateTargetAddress (
       IpMode = NvData->IpMode;
     } else {
       IpMode = Session->ConfigData->AutoConfigureMode;
     }
 
-    Status = IScsiAsciiStrToIp (
-               IpStr,
-               IpMode,
-               &Session->ConfigData->SessionConfigData.TargetIp
-               );
+    if (!IsExpressedIp) {
+      //
+      // Perform the DNS resolution.
+      //
+      CopyMem (&Session->ConfigData->SessionConfigData.TargetUrl, IpStr, 
AsciiStrSize (IpStr));
+      if (NvData->IpMode == IP_MODE_IP4 ||
+          Session->ConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4) {
+        Status = IScsiDns4 (Session->Private->Image, 
Session->Private->Controller, NvData);
+      } else if (NvData->IpMode == IP_MODE_IP6 ||
+                 Session->ConfigData->AutoConfigureMode == 
IP_MODE_AUTOCONFIG_IP6){
+        Status = IScsiDns6 (Session->Private->Image, 
Session->Private->Controller, NvData);
+      }
+
+      if (EFI_ERROR(Status)) {
+        CreatePopUp (
+          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+          &Key,
+          L"The configuration of Target or DNS server address is invalid",
+          NULL
+          );
+      }
+    } else {
+      Status = IScsiAsciiStrToIp (
+                 IpStr,
+                 IpMode,
+                 &Session->ConfigData->SessionConfigData.TargetIp
+                 );
+    }
 
     if (EFI_ERROR (Status)) {
       continue;
     } else {
       NvData->RedirectFlag = TRUE;
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to