]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpDxe/HttpDns.c
FmpDevicePkg FmpDxe: Return UNSUPPORTED if device has been locked
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpDns.c
index daebc173b5e9a971f115845228936d6d47657540..d0d57a5b2d0d3989d9b0e826c4292200771b7fd6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Routines for HttpDxe driver to perform DNS resolution based on UEFI DNS protocols.\r
 \r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017 - 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
@@ -25,13 +25,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.\r
   @retval EFI_DEVICE_ERROR        An unexpected network error occurred.\r
   @retval Others                  Other errors as indicated.\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 HttpDns4 (\r
   IN     HTTP_PROTOCOL            *HttpInstance,\r
   IN     CHAR16                   *HostName,\r
-     OUT EFI_IPv4_ADDRESS         *IpAddress                \r
+     OUT EFI_IPv4_ADDRESS         *IpAddress\r
   )\r
 {\r
   EFI_STATUS                      Status;\r
@@ -45,7 +45,7 @@ HttpDns4 (
   UINTN                           DnsServerListCount;\r
   EFI_IPv4_ADDRESS                *DnsServerList;\r
   UINTN                           DataSize;\r
-  \r
+\r
 \r
   Service = HttpInstance->Service;\r
   ASSERT (Service != NULL);\r
@@ -82,25 +82,25 @@ HttpDns4 (
 \r
   Dns4Handle = NULL;\r
   Dns4       = NULL;\r
-  \r
+\r
   //\r
   // Create a DNS child instance and get the protocol.\r
   //\r
   Status = NetLibCreateServiceChild (\r
              Service->ControllerHandle,\r
-             Service->ImageHandle,\r
+             Service->Ip4DriverBindingHandle,\r
              &gEfiDns4ServiceBindingProtocolGuid,\r
              &Dns4Handle\r
              );\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
-  }  \r
+  }\r
 \r
   Status = gBS->OpenProtocol (\r
                   Dns4Handle,\r
                   &gEfiDns4ProtocolGuid,\r
                   (VOID **) &Dns4,\r
-                  Service->ImageHandle,\r
+                  Service->Ip4DriverBindingHandle,\r
                   Service->ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
@@ -128,7 +128,7 @@ HttpDns4 (
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
-  \r
+\r
   //\r
   // Create event to set the is done flag when name resolution is finished.\r
   //\r
@@ -161,7 +161,7 @@ HttpDns4 (
   //\r
   // Name resolution is done, check result.\r
   //\r
-  Status = Token.Status;  \r
+  Status = Token.Status;\r
   if (!EFI_ERROR (Status)) {\r
     if (Token.RspData.H2AData == NULL) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -179,7 +179,7 @@ HttpDns4 (
   }\r
 \r
 Exit:\r
-  \r
+\r
   if (Token.Event != NULL) {\r
     gBS->CloseEvent (Token.Event);\r
   }\r
@@ -192,19 +192,19 @@ Exit:
 \r
   if (Dns4 != NULL) {\r
     Dns4->Configure (Dns4, NULL);\r
-    \r
+\r
     gBS->CloseProtocol (\r
-          Dns4Handle,\r
-          &gEfiDns4ProtocolGuid,\r
-          Service->ImageHandle,\r
-          Service->ControllerHandle\r
-          );\r
+           Dns4Handle,\r
+           &gEfiDns4ProtocolGuid,\r
+           Service->Ip4DriverBindingHandle,\r
+           Service->ControllerHandle\r
+           );\r
   }\r
 \r
   if (Dns4Handle != NULL) {\r
     NetLibDestroyServiceChild (\r
       Service->ControllerHandle,\r
-      Service->ImageHandle,\r
+      Service->Ip4DriverBindingHandle,\r
       &gEfiDns4ServiceBindingProtocolGuid,\r
       Dns4Handle\r
       );\r
@@ -213,6 +213,203 @@ Exit:
   if (DnsServerList != NULL) {\r
     FreePool (DnsServerList);\r
   }\r
-  \r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Retrieve the host address using the EFI_DNS6_PROTOCOL.\r
+\r
+  @param[in]  HttpInstance        Pointer to HTTP_PROTOCOL instance.\r
+  @param[in]  HostName            Pointer to buffer containing hostname.\r
+  @param[out] IpAddress           On output, pointer to buffer containing IPv6 address.\r
+\r
+  @retval EFI_SUCCESS             Operation succeeded.\r
+  @retval EFI_OUT_OF_RESOURCES    Failed to allocate needed resources.\r
+  @retval EFI_DEVICE_ERROR        An unexpected network error occurred.\r
+  @retval Others                  Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpDns6 (\r
+  IN     HTTP_PROTOCOL            *HttpInstance,\r
+  IN     CHAR16                   *HostName,\r
+     OUT EFI_IPv6_ADDRESS         *IpAddress\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  HTTP_SERVICE                    *Service;\r
+  EFI_DNS6_PROTOCOL               *Dns6;\r
+  EFI_DNS6_CONFIG_DATA            Dns6ConfigData;\r
+  EFI_DNS6_COMPLETION_TOKEN       Token;\r
+  EFI_HANDLE                      Dns6Handle;\r
+  EFI_IP6_CONFIG_PROTOCOL         *Ip6Config;\r
+  EFI_IPv6_ADDRESS                *DnsServerList;\r
+  UINTN                           DnsServerListCount;\r
+  UINTN                           DataSize;\r
+  BOOLEAN                         IsDone;\r
+\r
+\r
+  Service = HttpInstance->Service;\r
+  ASSERT (Service != NULL);\r
+\r
+  DnsServerList       = NULL;\r
+  DnsServerListCount  = 0;\r
+  Dns6                = NULL;\r
+  Dns6Handle          = NULL;\r
+  ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));\r
+\r
+  //\r
+  // Get DNS server list from EFI IPv6 Configuration protocol.\r
+  //\r
+  Status = gBS->HandleProtocol (Service->ControllerHandle, &gEfiIp6ConfigProtocolGuid, (VOID **) &Ip6Config);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Get the required size.\r
+    //\r
+    DataSize = 0;\r
+    Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, NULL);\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      DnsServerList = AllocatePool (DataSize);\r
+      if (DnsServerList == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      Status = Ip6Config->GetData (Ip6Config, Ip6ConfigDataTypeDnsServer, &DataSize, DnsServerList);\r
+      if (EFI_ERROR (Status)) {\r
+        FreePool (DnsServerList);\r
+        DnsServerList = NULL;\r
+      } else {\r
+        DnsServerListCount = DataSize / sizeof (EFI_IPv6_ADDRESS);\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Create a DNSv6 child instance and get the protocol.\r
+  //\r
+  Status = NetLibCreateServiceChild (\r
+             Service->ControllerHandle,\r
+             Service->Ip6DriverBindingHandle,\r
+             &gEfiDns6ServiceBindingProtocolGuid,\r
+             &Dns6Handle\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Dns6Handle,\r
+                  &gEfiDns6ProtocolGuid,\r
+                  (VOID **) &Dns6,\r
+                  Service->Ip6DriverBindingHandle,\r
+                  Service->ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Configure DNS6 instance for the DNS server address and protocol.\r
+  //\r
+  ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));\r
+  Dns6ConfigData.DnsServerCount = (UINT32)DnsServerListCount;\r
+  Dns6ConfigData.DnsServerList  = DnsServerList;\r
+  Dns6ConfigData.EnableDnsCache = TRUE;\r
+  Dns6ConfigData.Protocol       = EFI_IP_PROTO_UDP;\r
+  IP6_COPY_ADDRESS (&Dns6ConfigData.StationIp, &HttpInstance->Ipv6Node.LocalAddress);\r
+  Status = Dns6->Configure (\r
+                   Dns6,\r
+                   &Dns6ConfigData\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  Token.Status = EFI_NOT_READY;\r
+  IsDone       = FALSE;\r
+  //\r
+  // Create event to set the  IsDone flag when name resolution is finished.\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  HttpCommonNotify,\r
+                  &IsDone,\r
+                  &Token.Event\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Start asynchronous name resolution.\r
+  //\r
+  Status = Dns6->HostNameToIp (Dns6, HostName, &Token);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  while (!IsDone) {\r
+    Dns6->Poll (Dns6);\r
+  }\r
+\r
+  //\r
+  // Name resolution is done, check result.\r
+  //\r
+  Status = Token.Status;\r
+  if (!EFI_ERROR (Status)) {\r
+    if (Token.RspData.H2AData == NULL) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+    if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+    //\r
+    // We just return the first IPv6 address from DNS protocol.\r
+    //\r
+    IP6_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
+Exit:\r
+\r
+  if (Token.Event != NULL) {\r
+    gBS->CloseEvent (Token.Event);\r
+  }\r
+  if (Token.RspData.H2AData != NULL) {\r
+    if (Token.RspData.H2AData->IpList != NULL) {\r
+      FreePool (Token.RspData.H2AData->IpList);\r
+    }\r
+    FreePool (Token.RspData.H2AData);\r
+  }\r
+\r
+  if (Dns6 != NULL) {\r
+    Dns6->Configure (Dns6, NULL);\r
+\r
+    gBS->CloseProtocol (\r
+           Dns6Handle,\r
+           &gEfiDns6ProtocolGuid,\r
+           Service->Ip6DriverBindingHandle,\r
+           Service->ControllerHandle\r
+           );\r
+  }\r
+\r
+  if (Dns6Handle != NULL) {\r
+    NetLibDestroyServiceChild (\r
+      Service->ControllerHandle,\r
+      Service->Ip6DriverBindingHandle,\r
+      &gEfiDns6ServiceBindingProtocolGuid,\r
+      Dns6Handle\r
+      );\r
+  }\r
+\r
+  if (DnsServerList != NULL) {\r
+    FreePool (DnsServerList);\r
+  }\r
+\r
   return Status;\r
 }\r