/** @file\r
Implementation of the boot file download function.\r
\r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
This program and the accompanying materials are licensed and made available under \r
the terms and conditions of the BSD License that accompanies this distribution. \r
#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
)\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
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
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
SelectIndex = Private->SelectIndex - 1;\r
ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);\r
\r
+ DnsServerIndex = 0;\r
+ \r
Status = EFI_SUCCESS;\r
\r
//\r
Status = HttpBootCheckUriScheme (Private->BootFileUri);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "HttpBootDhcp4ExtractUriInfo: %r.\n", Status));\r
+ if (Status == EFI_INVALID_PARAMETER) {\r
+ AsciiPrint ("\n Error: Invalid URI address.\n");\r
+ } else if (Status == EFI_ACCESS_DENIED) {\r
+ AsciiPrint ("\n Error: Access forbidden, only HTTPS connection is allowed.\n");\r
+ }\r
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
//\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
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
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
Status = HttpBootCheckUriScheme (Private->BootFileUri);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "HttpBootDhcp6ExtractUriInfo: %r.\n", Status));\r
+ if (Status == EFI_INVALID_PARAMETER) {\r
+ AsciiPrint ("\n Error: Invalid URI address.\n");\r
+ } else if (Status == EFI_ACCESS_DENIED) {\r
+ AsciiPrint ("\n Error: Access forbidden, only HTTPS connection is allowed.\n");\r
+ }\r
return Status;\r
}\r
\r
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
//\r
- // Extract the HTTP server Ip frome URL. This is used to Check route table \r
+ // Extract the HTTP server Ip from URL. This is used to Check route table \r
// whether can send message to HTTP Server Ip through the GateWay.\r
//\r
Status = HttpUrlGetIp6 (\r
&HostName\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Error;\r
}\r
\r
HostNameSize = AsciiStrSize (HostName);\r
}\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
+ AsciiPrint ("\n Error: Could not retrieve the host address from DNS server.\n");\r
goto Error;\r
} \r
} \r
//\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
HTTP_BOOT_ENTITY_DATA *EntityData;\r
UINTN CopyedSize;\r
\r
- if (Uri == NULL || BufferSize == 0 || Buffer == NULL || ImageType == NULL) {\r
+ if (Uri == NULL || BufferSize == NULL || Buffer == NULL || ImageType == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
if ((Cache->RequestData != NULL) &&\r
(Cache->RequestData->Url != NULL) &&\r
- (StrCmp (Uri, Cache->RequestData->Url) == 0)) \r
- {\r
+ (StrCmp (Uri, Cache->RequestData->Url) == 0)) {\r
//\r
// Hit in cache, record image type.\r
//\r
return EFI_OUT_OF_RESOURCES;\r
}\r
AsciiStrToUnicodeStrS (Private->BootFileUri, Url, UrlSize);\r
- if (!HeaderOnly) {\r
+ if (!HeaderOnly && Buffer != NULL) {\r
Status = HttpBootGetFileFromCache (Private, Url, BufferSize, Buffer, ImageType);\r
if (Status != EFI_NOT_FOUND) {\r
FreePool (Url);\r
Context.Cache = Cache;\r
Context.Private = Private;\r
Status = HttpInitMsgParser (\r
- HeaderOnly? HttpMethodHead : HttpMethodGet,\r
+ HeaderOnly ? HttpMethodHead : HttpMethodGet,\r
ResponseData->Response.StatusCode,\r
ResponseData->HeaderCount,\r
ResponseData->Headers,\r