]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/HttpBootDxe/HttpBootClient.c
OvmfPkg/VirtioRngDxe: map host address to device address
[mirror_edk2.git] / NetworkPkg / HttpBootDxe / HttpBootClient.c
index 99db3d5505dc01c5f7a38e94aeeffa960464f7d8..5c871717da6288706fc241f063a2072752346288 100644 (file)
@@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "HttpBootDxe.h"\r
 \r
 /**\r
-  Update the IP and URL device path node to include the boot resource information.\r
+  Update the device path node to include the boot resource information.\r
 \r
   @param[in]    Private            The pointer to the driver's private data.\r
 \r
@@ -31,12 +31,14 @@ HttpBootUpdateDevicePath (
   )\r
 {\r
   EFI_DEV_PATH               *Node;\r
-  EFI_DEVICE_PATH_PROTOCOL   *TmpDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL   *TmpIpDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL   *TmpDnsDevicePath;\r
   EFI_DEVICE_PATH_PROTOCOL   *NewDevicePath;\r
   UINTN                      Length;\r
   EFI_STATUS                 Status;\r
 \r
-  TmpDevicePath = NULL;\r
+  TmpIpDevicePath  = NULL;\r
+  TmpDnsDevicePath = NULL;\r
   \r
   //\r
   // Update the IP node with DHCP assigned information.\r
@@ -72,29 +74,65 @@ HttpBootUpdateDevicePath (
     CopyMem (&Node->Ipv6.GatewayIpAddress, &Private->GatewayIp.v6, sizeof (EFI_IPv6_ADDRESS));\r
   }\r
   \r
-  TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
+  TmpIpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
   FreePool (Node);\r
-  if (TmpDevicePath == NULL) {\r
+  if (TmpIpDevicePath == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
+  //\r
+  // Update the DNS node with DNS server IP list if existed.\r
+  //\r
+  if (Private->DnsServerIp != NULL) {\r
+    Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (Node->Dns.IsIPv6) + Private->DnsServerCount * sizeof (EFI_IP_ADDRESS);\r
+    Node = AllocatePool (Length);\r
+    if (Node == NULL) {\r
+      FreePool (TmpIpDevicePath);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    Node->DevPath.Type    = MESSAGING_DEVICE_PATH;\r
+    Node->DevPath.SubType = MSG_DNS_DP;\r
+    SetDevicePathNodeLength (Node, Length);\r
+    Node->Dns.IsIPv6 = Private->UsingIpv6 ? 0x01 : 0x00;\r
+    CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (Node->Dns.IsIPv6), Private->DnsServerIp, Private->DnsServerCount * sizeof (EFI_IP_ADDRESS));\r
+    \r
+    TmpDnsDevicePath = AppendDevicePathNode (TmpIpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
+    FreePool (Node);\r
+    FreePool (TmpIpDevicePath);\r
+    TmpIpDevicePath = NULL;\r
+    if (TmpDnsDevicePath == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+\r
   //\r
   // Update the URI node with the boot file URI.\r
   //\r
   Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (Private->BootFileUri);\r
   Node = AllocatePool (Length);\r
   if (Node == NULL) {\r
-    FreePool (TmpDevicePath);\r
+    if (TmpIpDevicePath != NULL) {\r
+      FreePool (TmpIpDevicePath);\r
+    }\r
+    if (TmpDnsDevicePath != NULL) {\r
+      FreePool (TmpDnsDevicePath);\r
+    }\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   Node->DevPath.Type    = MESSAGING_DEVICE_PATH;\r
   Node->DevPath.SubType = MSG_URI_DP;\r
   SetDevicePathNodeLength (Node, Length);\r
   CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), Private->BootFileUri, AsciiStrSize (Private->BootFileUri));\r
-  \r
-  NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
+\r
+  if (TmpDnsDevicePath != NULL) {\r
+    NewDevicePath = AppendDevicePathNode (TmpDnsDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
+    FreePool (TmpDnsDevicePath);\r
+  } else {\r
+    ASSERT (TmpIpDevicePath != NULL);\r
+    NewDevicePath = AppendDevicePathNode (TmpIpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
+    FreePool (TmpIpDevicePath);\r
+  }\r
   FreePool (Node);\r
-  FreePool (TmpDevicePath);\r
   if (NewDevicePath == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -153,6 +191,7 @@ HttpBootDhcp4ExtractUriInfo (
   HTTP_BOOT_DHCP4_PACKET_CACHE    *HttpOffer;\r
   UINT32                          SelectIndex;\r
   UINT32                          ProxyIndex;\r
+  UINT32                          DnsServerIndex;\r
   EFI_DHCP4_PACKET_OPTION         *Option;\r
   EFI_STATUS                      Status;\r
 \r
@@ -161,6 +200,8 @@ HttpBootDhcp4ExtractUriInfo (
   SelectIndex = Private->SelectIndex - 1;\r
   ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);\r
 \r
+  DnsServerIndex = 0;\r
+  \r
   Status = EFI_SUCCESS;\r
 \r
   //\r
@@ -200,20 +241,37 @@ HttpBootDhcp4ExtractUriInfo (
     return Status;\r
   }\r
 \r
-  //\r
-  // Configure the default DNS server if server assigned.\r
-  //\r
   if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) || \r
       (SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||\r
       (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns)) {\r
     Option = SelectOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER];\r
     ASSERT (Option != NULL);\r
+\r
+    //\r
+    // Record the Dns Server address list.\r
+    //\r
+    Private->DnsServerCount = (Option->Length) / sizeof (EFI_IPv4_ADDRESS);\r
+\r
+    Private->DnsServerIp = AllocateZeroPool (Private->DnsServerCount * sizeof (EFI_IP_ADDRESS));\r
+    if (Private->DnsServerIp == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    for (DnsServerIndex = 0; DnsServerIndex < Private->DnsServerCount; DnsServerIndex++) {\r
+      CopyMem (&(Private->DnsServerIp[DnsServerIndex].v4), &(((EFI_IPv4_ADDRESS *) Option->Data)[DnsServerIndex]), sizeof (EFI_IPv4_ADDRESS));\r
+    }\r
+    \r
+    //\r
+    // Configure the default DNS server if server assigned.\r
+    //    \r
     Status = HttpBootRegisterIp4Dns (\r
                Private,\r
                Option->Length,\r
                Option->Data\r
                );\r
     if (EFI_ERROR (Status)) {\r
+      FreePool (Private->DnsServerIp);\r
+      Private->DnsServerIp = NULL;\r
       return Status;\r
     }\r
   }\r
@@ -233,12 +291,15 @@ HttpBootDhcp4ExtractUriInfo (
   //\r
   // All boot informations are valid here.\r
   //\r
-  AsciiPrint ("\n  URI: %a", Private->BootFileUri);\r
 \r
   //\r
-  // Update the device path to include the IP and boot URI information.\r
+  // Update the device path to include the boot resource information.\r
   //\r
   Status = HttpBootUpdateDevicePath (Private);\r
+  if (EFI_ERROR (Status) && Private->DnsServerIp != NULL) {\r
+    FreePool (Private->DnsServerIp);\r
+    Private->DnsServerIp = NULL;\r
+  }\r
 \r
   return Status;\r
 }\r
@@ -261,6 +322,7 @@ HttpBootDhcp6ExtractUriInfo (
   HTTP_BOOT_DHCP6_PACKET_CACHE    *HttpOffer;\r
   UINT32                          SelectIndex;\r
   UINT32                          ProxyIndex;\r
+  UINT32                          DnsServerIndex;\r
   EFI_DHCP6_PACKET_OPTION         *Option;\r
   EFI_IPv6_ADDRESS                IpAddr;\r
   CHAR8                           *HostName;\r
@@ -273,6 +335,8 @@ HttpBootDhcp6ExtractUriInfo (
   SelectIndex = Private->SelectIndex - 1;\r
   ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);\r
 \r
+  DnsServerIndex = 0;\r
+\r
   Status   = EFI_SUCCESS;\r
   HostName = NULL;\r
   //\r
@@ -327,22 +391,37 @@ HttpBootDhcp6ExtractUriInfo (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  \r
-  //\r
-  // Configure the default DNS server if server assigned.\r
-  //\r
+\r
   if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) || \r
       (SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||\r
       (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns)) {\r
     Option = SelectOffer->OptList[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];\r
     ASSERT (Option != NULL);\r
+\r
+    //\r
+    // Record the Dns Server address list.\r
+    //\r
+    Private->DnsServerCount = HTONS (Option->OpLen) / sizeof (EFI_IPv6_ADDRESS);\r
+\r
+    Private->DnsServerIp = AllocateZeroPool (Private->DnsServerCount * sizeof (EFI_IP_ADDRESS));\r
+    if (Private->DnsServerIp == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    for (DnsServerIndex = 0; DnsServerIndex < Private->DnsServerCount; DnsServerIndex++) {\r
+      CopyMem (&(Private->DnsServerIp[DnsServerIndex].v6), &(((EFI_IPv6_ADDRESS *) Option->Data)[DnsServerIndex]), sizeof (EFI_IPv6_ADDRESS));\r
+    }\r
+\r
+    //\r
+    // Configure the default DNS server if server assigned.\r
+    //\r
     Status = HttpBootSetIp6Dns (\r
                Private,\r
                HTONS (Option->OpLen),\r
                Option->Data\r
                );\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Error;\r
     }\r
   }\r
   \r
@@ -366,7 +445,7 @@ HttpBootDhcp6ExtractUriInfo (
                &HostName\r
                );\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Error;\r
     }\r
 \r
     HostNameSize = AsciiStrSize (HostName);\r
@@ -377,6 +456,11 @@ HttpBootDhcp6ExtractUriInfo (
     }\r
     \r
     AsciiStrToUnicodeStrS (HostName, HostNameStr, HostNameSize);\r
+\r
+    if (HostName != NULL) {\r
+      FreePool (HostName);\r
+    }\r
+    \r
     Status = HttpBootDns (Private, HostNameStr, &IpAddr);\r
     FreePool (HostNameStr);\r
     if (EFI_ERROR (Status)) {\r
@@ -401,18 +485,23 @@ HttpBootDhcp6ExtractUriInfo (
   //\r
   // All boot informations are valid here.\r
   //\r
-  AsciiPrint ("\n  URI: %a", Private->BootFileUri);\r
+\r
   //\r
-  // Update the device path to include the IP and boot URI information.\r
+  // Update the device path to include the boot resource information.\r
   //\r
   Status = HttpBootUpdateDevicePath (Private);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+  \r
+  return Status;\r
 \r
 Error:\r
-  \r
-  if (HostName != NULL) {\r
-    FreePool (HostName);\r
+  if (Private->DnsServerIp != NULL) {\r
+    FreePool (Private->DnsServerIp);\r
+    Private->DnsServerIp = NULL;\r
   }\r
-    \r
+  \r
   return Status;\r
 }\r
 \r
@@ -451,6 +540,40 @@ HttpBootDiscoverBootInfo (
   return Status;\r
 }\r
 \r
+/**\r
+  HttpIo Callback function which will be invoked when specified HTTP_IO_CALLBACK_EVENT happened.\r
+\r
+  @param[in]    EventType      Indicate the Event type that occurs in the current callback.\r
+  @param[in]    Message        HTTP message which will be send to, or just received from HTTP server.\r
+  @param[in]    Context        The Callback Context pointer.\r
+  \r
+  @retval EFI_SUCCESS          Tells the HttpIo to continue the HTTP process.\r
+  @retval Others               Tells the HttpIo to abort the current HTTP process.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HttpBootHttpIoCallback (\r
+  IN  HTTP_IO_CALLBACK_EVENT    EventType,\r
+  IN  EFI_HTTP_MESSAGE          *Message,\r
+  IN  VOID                      *Context\r
+  )\r
+{\r
+  HTTP_BOOT_PRIVATE_DATA       *Private;\r
+  EFI_STATUS                   Status;\r
+  Private = (HTTP_BOOT_PRIVATE_DATA *) Context;\r
+  if (Private->HttpBootCallback != NULL) {\r
+    Status = Private->HttpBootCallback->Callback (\r
+               Private->HttpBootCallback,\r
+               EventType == HttpIoRequest ? HttpBootHttpRequest : HttpBootHttpResponse,\r
+               EventType == HttpIoRequest ? FALSE : TRUE,\r
+               sizeof (EFI_HTTP_MESSAGE),\r
+               (VOID *) Message\r
+               );\r
+    return Status;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Create a HttpIo instance for the file download.\r
 \r
@@ -490,6 +613,8 @@ HttpBootCreateHttpIo (
              Private->Controller,\r
              Private->UsingIpv6 ? IP_VERSION_6 : IP_VERSION_4,\r
              &ConfigData,\r
+             HttpBootHttpIoCallback,\r
+             (VOID *) Private,\r
              &Private->HttpIo\r
              );\r
   if (EFI_ERROR (Status)) {\r
@@ -686,6 +811,8 @@ HttpBootGetBootFileCallback (
 {\r
   HTTP_BOOT_CALLBACK_DATA      *CallbackData;\r
   HTTP_BOOT_ENTITY_DATA        *NewEntityData;\r
+  EFI_STATUS                   Status;\r
+  EFI_HTTP_BOOT_CALLBACK_PROTOCOL   *HttpBootCallback;\r
 \r
   //\r
   // We only care about the entity data.\r
@@ -695,6 +822,19 @@ HttpBootGetBootFileCallback (
   }\r
 \r
   CallbackData = (HTTP_BOOT_CALLBACK_DATA *) Context;\r
+  HttpBootCallback = CallbackData->Private->HttpBootCallback;\r
+  if (HttpBootCallback != NULL) {\r
+    Status = HttpBootCallback->Callback (\r
+               HttpBootCallback,\r
+               HttpBootHttpEntityBody,\r
+               TRUE,\r
+               (UINT32)Length,\r
+               Data\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
   //\r
   // Copy data if caller has provided a buffer.\r
   //\r
@@ -977,6 +1117,7 @@ HttpBootGetBootFile (
   Context.Buffer     = Buffer;\r
   Context.BufferSize = *BufferSize;\r
   Context.Cache      = Cache;\r
+  Context.Private    = Private;\r
   Status = HttpInitMsgParser (\r
              HeaderOnly? HttpMethodHead : HttpMethodGet,\r
              ResponseData->Response.StatusCode,\r
@@ -1032,6 +1173,18 @@ HttpBootGetBootFile (
           goto ERROR_6;\r
         }\r
         ReceivedSize += ResponseBody.BodyLength;\r
+        if (Private->HttpBootCallback != NULL) {\r
+          Status = Private->HttpBootCallback->Callback (\r
+                     Private->HttpBootCallback,\r
+                     HttpBootHttpEntityBody,\r
+                     TRUE,\r
+                     (UINT32)ResponseBody.BodyLength,\r
+                     ResponseBody.Body\r
+                     );\r
+          if (EFI_ERROR (Status)) {\r
+            goto ERROR_6;\r
+          }\r
+        }\r
       }\r
     } else {\r
       //\r