From: "Sivaraman Nainar" <sivaramann@amiindia.co.in>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "liming.gao@intel.com" <liming.gao@intel.com>,
"jiaxin.wu@intel.com" <jiaxin.wu@intel.com>
Subject: Re: [edk2-devel] [Patch ] Static IP based HTTP Support
Date: Thu, 13 Aug 2020 15:59:17 +0000 [thread overview]
Message-ID: <B4DE137BDB63634BAC03BD9DE765F19702B4B34FEC@VENUS1.in.megatrends.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 60671 bytes --]
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2888
*** NetworkPkg\HttpBootDxe\HttpBootClient.c 2020-05-07 22:54:46.000000000 +05-30
--- NetworkPkg\HttpBootDxe\HttpBootClient.c 2020-08-09 21:03:01.000000000 +05-30
***************
*** 1,6 ****
--- 1,13 ----
+ //***********************************************************************
+ //* *
+ //* Copyright (c) 1985-2020, American Megatrends International LLC. *
+ //* *
+ //* All rights reserved. Subject to AMI licensing agreement. *
+ //* *
+ //***********************************************************************
/** @file
Implementation of the boot file download function.
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
***************
*** 45,57 ****
Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
Node->Ipv4.Header.SubType = MSG_IPv4_DP;
SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
CopyMem (&Node->Ipv4.LocalIpAddress, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));
Node->Ipv4.RemotePort = Private->Port;
Node->Ipv4.Protocol = EFI_IP_PROTO_TCP;
! Node->Ipv4.StaticIpAddress = FALSE;
CopyMem (&Node->Ipv4.GatewayIpAddress, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));
CopyMem (&Node->Ipv4.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
} else {
Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
if (Node == NULL) {
return EFI_OUT_OF_RESOURCES;
--- 52,67 ----
Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
Node->Ipv4.Header.SubType = MSG_IPv4_DP;
SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
CopyMem (&Node->Ipv4.LocalIpAddress, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));
Node->Ipv4.RemotePort = Private->Port;
Node->Ipv4.Protocol = EFI_IP_PROTO_TCP;
! if (Private->UsingStatic)
! Node->Ipv4.StaticIpAddress =TRUE;
! else
! Node->Ipv4.StaticIpAddress = FALSE;
CopyMem (&Node->Ipv4.GatewayIpAddress, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));
CopyMem (&Node->Ipv4.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
} else {
Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
if (Node == NULL) {
return EFI_OUT_OF_RESOURCES;
***************
*** 325,374 ****
EFI_DHCP6_PACKET_OPTION *Option;
EFI_IPv6_ADDRESS IpAddr;
CHAR8 *HostName;
UINTN HostNameSize;
CHAR16 *HostNameStr;
EFI_STATUS Status;
!
ASSERT (Private != NULL);
! ASSERT (Private->SelectIndex != 0);
! SelectIndex = Private->SelectIndex - 1;
! ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);
!
DnsServerIndex = 0;
Status = EFI_SUCCESS;
HostName = NULL;
//
// SelectOffer contains the IP address configuration and name server configuration.
// HttpOffer contains the boot file URL.
//
! SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp6;
! if (Private->FilePathUri == NULL) {
! //
! // In Corporate environment, we need a HttpOffer.
! //
! if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) ||
! (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns) ||
! (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns)) {
! HttpOffer = SelectOffer;
! } else {
! ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
! ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
! HttpOffer = &Private->OfferBuffer[ProxyIndex].Dhcp6;
! }
! Private->BootFileUriParser = HttpOffer->UriParser;
! Private->BootFileUri = (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data;
! } else {
! //
! // In Home environment the BootFileUri comes from the FilePath.
! //
! Private->BootFileUriParser = Private->FilePathUriParser;
! Private->BootFileUri = Private->FilePathUri;
! }
!
//
// Check the URI scheme.
//
Status = HttpBootCheckUriScheme (Private->BootFileUri);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "HttpBootDhcp6ExtractUriInfo: %r.\n", Status));
--- 335,397 ----
EFI_DHCP6_PACKET_OPTION *Option;
EFI_IPv6_ADDRESS IpAddr;
CHAR8 *HostName;
UINTN HostNameSize;
CHAR16 *HostNameStr;
EFI_STATUS Status;
! EFI_IPv6_ADDRESS *Dns;
! UINTN DataSize;
!
ASSERT (Private != NULL);
! if (!Private->UsingStatic){
! ASSERT (Private->SelectIndex != 0);
! SelectIndex = Private->SelectIndex - 1;
! ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);
! }
DnsServerIndex = 0;
+ DataSize = 0;
Status = EFI_SUCCESS;
HostName = NULL;
+ Dns = NULL;
+ if (Private->UsingStatic){
+ //Static HttpBoot supports Home Environment Only.
+ // In Home environment the BootFileUri comes from the FilePath.
+ //
+ Private->BootFileUriParser = Private->FilePathUriParser;
+ Private->BootFileUri = Private->FilePathUri;
+ }else{
+ Dns = NULL;
//
// SelectOffer contains the IP address configuration and name server configuration.
// HttpOffer contains the boot file URL.
//
! SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp6;
! if (Private->FilePathUri == NULL ) {
! //
! // In Corporate environment, we need a HttpOffer.
! //
! if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) ||
! (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns) ||
! (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns)) {
! HttpOffer = SelectOffer;
! } else {
! ASSERT (Private->SelectProxyType != HttpOfferTypeMax);
! ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
! HttpOffer = &Private->OfferBuffer[ProxyIndex].Dhcp6;
! }
! Private->BootFileUriParser = HttpOffer->UriParser;
! Private->BootFileUri = (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data;
! } else {
! //
! // In Home environment the BootFileUri comes from the FilePath.
! //
! Private->BootFileUriParser = Private->FilePathUriParser;
! Private->BootFileUri = Private->FilePathUri;
! }
! }
//
// Check the URI scheme.
//
Status = HttpBootCheckUriScheme (Private->BootFileUri);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "HttpBootDhcp6ExtractUriInfo: %r.\n", Status));
***************
*** 391,403 ****
//
// Register the IPv6 gateway address to the network device.
//
Status = HttpBootSetIp6Gateway (Private);
if (EFI_ERROR (Status)) {
return Status;
! }
if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) ||
(SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||
(SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns)) {
Option = SelectOffer->OptList[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];
ASSERT (Option != NULL);
--- 414,450 ----
//
// Register the IPv6 gateway address to the network device.
//
Status = HttpBootSetIp6Gateway (Private);
if (EFI_ERROR (Status)) {
return Status;
! }
! if (Private->UsingStatic){
! if( Private->DnsServerIp != NULL ){
! //
! // Configure the default DNS server if server assigned.
! //
!
! DataSize = Private->DnsServerCount * sizeof (EFI_IPv6_ADDRESS);
! Dns = AllocateZeroPool(DataSize);
! for (DnsServerIndex = 0;DnsServerIndex < Private->DnsServerCount;DnsServerIndex++)
! CopyMem(&Dns[DnsServerIndex],&Private->DnsServerIp[DnsServerIndex].v6,sizeof(EFI_IPv6_ADDRESS));
! Status = HttpBootSetIp6Dns (
! Private,
! DataSize,
! Dns
! );
! FreePool(Dns);
! if (EFI_ERROR (Status)) {
! goto Error;
! }
! }
!
! goto StaticBoot;
! }
!
if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) ||
(SelectOffer->OfferType == HttpOfferTypeDhcpDns) ||
(SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns)) {
Option = SelectOffer->OptList[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];
ASSERT (Option != NULL);
***************
*** 430,441 ****
--- 477,489 ----
}
//
// Extract the HTTP server Ip from URL. This is used to Check route table
// whether can send message to HTTP Server Ip through the GateWay.
//
+ StaticBoot:
Status = HttpUrlGetIp6 (
Private->BootFileUri,
Private->BootFileUriParser,
&IpAddr
);
***************
*** 523,546 ****
EFI_STATUS
HttpBootDiscoverBootInfo (
IN OUT HTTP_BOOT_PRIVATE_DATA *Private
)
{
EFI_STATUS Status;
//
// Start D.O.R.A/S.A.R.R exchange to acquire station ip address and
// other Http boot information.
//
Status = HttpBootDhcp (Private);
if (EFI_ERROR (Status)) {
return Status;
}
if (!Private->UsingIpv6) {
! Status = HttpBootDhcp4ExtractUriInfo (Private);
} else {
Status = HttpBootDhcp6ExtractUriInfo (Private);
}
return Status;
}
--- 571,639 ----
EFI_STATUS
HttpBootDiscoverBootInfo (
IN OUT HTTP_BOOT_PRIVATE_DATA *Private
)
{
EFI_STATUS Status;
+ EFI_IPv4_ADDRESS *Dns;
+ UINTN DataSize = 0;
+ UINT8 DnsServerIndex = 0;
+ Dns = NULL;
//
// Start D.O.R.A/S.A.R.R exchange to acquire station ip address and
// other Http boot information.
//
Status = HttpBootDhcp (Private);
if (EFI_ERROR (Status)) {
return Status;
}
if (!Private->UsingIpv6) {
! if (!Private->UsingStatic){
! Status = HttpBootDhcp4ExtractUriInfo (Private);
! }
! else{
! Private->BootFileUriParser = Private->FilePathUriParser;
! Private->BootFileUri = Private->FilePathUri;
!
! if (Private->DnsServerIp != NULL){
! DataSize = Private->DnsServerCount * sizeof(EFI_IPv4_ADDRESS);
! Dns = AllocateZeroPool(DataSize);
! for (DnsServerIndex = 0;DnsServerIndex < Private->DnsServerCount;DnsServerIndex++)
! CopyMem(&Dns[DnsServerIndex],&(Private->DnsServerIp[DnsServerIndex].v4),sizeof(EFI_IPv4_ADDRESS));
!
! Status = HttpBootRegisterIp4Dns (
! Private,
! DataSize,
! Dns
! );
!
! FreePool (Dns);
! if (EFI_ERROR (Status)) {
! FreePool (Private->DnsServerIp);
! Private->DnsServerIp = NULL;
! return Status;
! }
! }
! //
! // Extract the port from URL, and use default HTTP port 80 if not provided.
! //
! Status = HttpUrlGetPort (
! Private->BootFileUri,
! Private->BootFileUriParser,
! &Private->Port
! );
! if (EFI_ERROR (Status) || Private->Port == 0) {
! Private ->Port = 80;
! }
! //
! // Update the device path to include the IP and boot URI information.
! //
! Status = HttpBootUpdateDevicePath (Private);
! }
} else {
Status = HttpBootDhcp6ExtractUriInfo (Private);
}
return Status;
}
*** NetworkPkg\HttpBootDxe\HttpBootConfig.c 2020-05-07 22:54:46.000000000 +05-30
--- NetworkPkg\HttpBootDxe\HttpBootConfig.c 2020-08-04 15:28:06.000000000 +05-30
***************
*** 1,6 ****
--- 1,13 ----
+ //***********************************************************************
+ //* *
+ //* Copyright (c) 1985-2020, American Megatrends International LLC. *
+ //* *
+ //* All rights reserved. Subject to AMI licensing agreement. *
+ //* *
+ //***********************************************************************
/** @file
Helper functions for configuring or getting the parameters relating to HTTP Boot.
Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
***************
*** 36,72 ****
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
UINTN Length;
CHAR8 AsciiUri[URI_STR_MAX_SIZE];
EFI_STATUS Status;
UINTN Index;
EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
!
NewDevicePath = NULL;
Node = NULL;
TmpDevicePath = NULL;
if (StrLen (Description) == 0) {
return EFI_INVALID_PARAMETER;
}
//
// Convert the scheme to all lower case.
//
for (Index = 0; Index < StrLen (Uri); Index++) {
! if (Uri[Index] == L':') {
! break;
! }
if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
Uri[Index] -= (CHAR16)(L'A' - L'a');
}
}
//
! // Only accept empty URI, or http and https URI.
//
! if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 8) != 0)) {
return EFI_INVALID_PARAMETER;
}
//
// Create a new device path by appending the IP node and URI node to
// the driver's parent device path
--- 43,93 ----
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
UINTN Length;
CHAR8 AsciiUri[URI_STR_MAX_SIZE];
EFI_STATUS Status;
UINTN Index;
EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
! EFI_IP_ADDRESS LocalIp;
! EFI_IP_ADDRESS SubnetMask;
! EFI_IP_ADDRESS GatewayIp;
! CHAR16 DebugString[URI_STR_MAX_SIZE];
! CHAR8 *AsciiUri2;
!
! AsciiUri2 = NULL;
NewDevicePath = NULL;
Node = NULL;
TmpDevicePath = NULL;
if (StrLen (Description) == 0) {
return EFI_INVALID_PARAMETER;
}
//
// Convert the scheme to all lower case.
//
for (Index = 0; Index < StrLen (Uri); Index++) {
! if (Uri[Index] == L'/' && Uri[Index + 1] == L'/') {
! break;
! }
!
if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
Uri[Index] -= (CHAR16)(L'A' - L'a');
}
}
//
! // Only accept empty URI, or http , https URI and Static URI.
//
!
! if ((StrLen (Uri) != 0) && StrStr(Uri,L"static")){
! Private->UsingStatic = TRUE;
! }
! else{
! Private->UsingStatic = FALSE;
! }
! if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 8) != 0)&& EFI_ERROR(HttpBootCheckStaticUri(Uri)) {
return EFI_INVALID_PARAMETER;
}
//
// Create a new device path by appending the IP node and URI node to
// the driver's parent device path
***************
*** 77,107 ****
--- 98,159 ----
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
Node->Ipv4.Header.SubType = MSG_IPv4_DP;
SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
+ if (Private->UsingStatic){
+ Status = VerifyIpv4Address(Uri,&LocalIp,&SubnetMask,&GatewayIp,DebugString);
+ if (EFI_ERROR(Status))
+ return Status;
+ CopyMem (&Node->Ipv4.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
+ Node->Ipv4.RemotePort = Private->Port;
+ Node->Ipv4.Protocol = EFI_IP_PROTO_TCP;
+ Node->Ipv4.StaticIpAddress = TRUE;
+ CopyMem (&Node->Ipv4.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Node->Ipv4.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
+ }
} else {
Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
if (Node == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_EXIT;
}
Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
Node->Ipv6.Header.SubType = MSG_IPv6_DP;
SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
+ if (Private->UsingStatic){
+ Status = VerifyIpv6Address (Uri,&LocalIp,&GatewayIp,DebugString);
+ if (EFI_ERROR(Status))
+ return Status;
+ Node->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;
+ Node->Ipv6.RemotePort = Private->Port;
+ Node->Ipv6.Protocol = EFI_IP_PROTO_TCP;
+ Node->Ipv6.IpAddressOrigin = 0x03;
+ CopyMem (&Node->Ipv6.LocalIpAddress, &LocalIp.v6 , sizeof (EFI_IPv6_ADDRESS));
+ CopyMem (&Node->Ipv6.GatewayIpAddress, &GatewayIp.v6, sizeof (EFI_IPv6_ADDRESS));
+ }
}
TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
FreePool (Node);
if (TmpDevicePath == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Update the URI node with the input boot file URI.
//
UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri));
+ //Extract Bootfile uri from Static Uri.
+ if ((Private->UsingStatic && (AsciiStrStr(AsciiUri,"dns") == NULL))||( AsciiStrStr(AsciiUri,"dhcp"))){
+ AsciiUri2 = AsciiStrStr (AsciiUri ,"http");
+ if (AsciiUri2 != NULL){
+ for (Index =0;AsciiUri2[Index] != ')' && AsciiUri2[Index] != '\0' ;Index++);
+ AsciiUri2[Index] = '\0';
+ AsciiStrCpy(AsciiUri,AsciiUri2);
+ }
+ }
Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);
Node = AllocatePool (Length);
if (Node == NULL) {
Status = EFI_OUT_OF_RESOURCES;
FreePool (TmpDevicePath);
goto ON_EXIT;
***************
*** 483,494 ****
--- 535,551 ----
return EFI_OUT_OF_RESOURCES;
}
UnicodeStrToAsciiStrS (Uri, AsciiUri, UriLen);
Status = HttpBootCheckUriScheme (AsciiUri);
+ if (Status == EFI_INVALID_PARAMETER){
+ Status = HttpBootCheckStaticUri(Uri);
+ if (Status == EFI_UNSUPPORTED)
+ return EFI_INVALID_PARAMETER;
+ }
if (Status == EFI_INVALID_PARAMETER) {
DEBUG ((EFI_D_ERROR, "HttpBootFormCallback: %r.\n", Status));
CreatePopUp (
*** NetworkPkg\HttpBootDxe\HttpBootDxe.h 2020-05-07 22:54:46.000000000 +05-30
--- NetworkPkg\HttpBootDxe\HttpBootDxe.h 2020-08-09 21:00:21.000000000 +05-30
***************
*** 1,6 ****
--- 1,13 ----
+ //***********************************************************************
+ //* *
+ //* Copyright (c) 1985-2020, American Megatrends International LLC. *
+ //* *
+ //* All rights reserved. Subject to AMI licensing agreement. *
+ //* *
+ //***********************************************************************
/** @file
UEFI HTTP boot driver's private data structure and interfaces declaration.
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
***************
*** 254,265 ****
--- 261,273 ----
UINT32 SelectIndex;
UINT32 SelectProxyType;
HTTP_BOOT_DHCP_PACKET_CACHE OfferBuffer[HTTP_BOOT_OFFER_MAX_NUM];
UINT32 OfferNum;
UINT32 OfferCount[HttpOfferTypeMax];
UINT32 OfferIndex[HttpOfferTypeMax][HTTP_BOOT_OFFER_MAX_NUM];
+ BOOLEAN UsingStatic;
};
#define HTTP_BOOT_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('H', 'B', 'P', 'D')
#define HTTP_BOOT_VIRTUAL_NIC_SIGNATURE SIGNATURE_32 ('H', 'B', 'V', 'N')
#define HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE(a) CR (a, HTTP_BOOT_PRIVATE_DATA, LoadFile, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
#define HTTP_BOOT_PRIVATE_DATA_FROM_ID(a) CR (a, HTTP_BOOT_PRIVATE_DATA, Id, HTTP_BOOT_PRIVATE_DATA_SIGNATURE)
***************
*** 518,524 ****
--- 526,665 ----
HttpBootIp6DxeDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
);
+ /**
+ Configure Static Ip Address using Ipconfig2 Protocol
+
+ @param[in] Private Pointer to HTTP boot driver private data.
+ **/
+ EFI_STATUS
+ StaticHttpBoot(HTTP_BOOT_PRIVATE_DATA *Private);
+ /**
+ Get the IPv4 Address and Ipv6 Address from the Input Devicepath.
+
+
+ @param[in] FilePath Pointer to the device path which contains IPV4 and IPV6 path node.
+
+ @retval EFI_SUCCESS The IPV4 Address and IPV6 Address successfully assigned to Private variable
+ EFI_INVALID_PARAMETER If FilePath is Null
+ EFI_NOT_FOUND If IPV4Address can't be found
+ **/
+ EFI_STATUS
+ HttpBootParseIpAddress (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ );
+ /******
+ Get the IPv6Address,GatewayIp6Address using Http Uri given by user,
+ IPV6(LocalIp6Address,Tcp,static or dhcp,gatewayip6Address)/Dns(IP1,IP2,...,IPn)/Uri(_http://DomainName/xxx.efi)
+
+ @param[in] Buffer URI string of the boot file.
+ @param[out] LocalIp Ipv6 LocalIp Address is updated statically based on Uri
+ @param[out] GatewayIp Ipv6 GatewayIp is updated statically based on Uri
+ @Param[out] String The Error Message.
+
+ @retval EFI_SUCCESS IP Address is translated from String.
+ @retval EFI_INVALID_PARAMETER Url is not supported http and https
+ EFI_UNSUPPORTED If IP Address is Invalid and Static Uri is invalid
+ *******/
+ EFI_STATUS
+ VerifyIpv6Address (
+ IN CHAR16 *Buffer,
+ OUT EFI_IP_ADDRESS *LocalIp,
+ OUT EFI_IP_ADDRESS *GatewayIp,
+ OUT CHAR16 *String
+ );
+ /*********
+ Get the IPv4Address,subnetMask,GatewayIp using Http Uri given by user,
+ IPV4(ClientAddress,protocol,static or Dhcp,gatewayip,subnetMask)/Dns(DnsIP1,DnsIP2...,IPn)/Uri(_http://DomainName/xxx.efi)
+
+ @param[in] Uri The URI string of the boot file.
+ @param[out] LocalIP Ipv4 LocalP is updated statically based on Uri
+ @param[out] SubnetMask Ipv4 SubnetMask is updated statically based on Uri
+ @param[out] GatewayIp Ipv4 GatewayIp is updated statically based on Uri
+ @Param[out] String The Error Message.
+
+ @retval EFI_SUCCESS IP Address is translated from String.
+ @retval EFI_INVALID_PARAMETER Url is not supported http and https
+ EFI_UNSUPPORTED If IP Addrress and static Uri is invalid
+ ********/
+ EFI_STATUS
+ VerifyIpv4Address (
+ IN CHAR16 *Buffer,
+ OUT EFI_IP_ADDRESS *LocalIp,
+ OUT EFI_IP_ADDRESS *SubnetMask,
+ OUT EFI_IP_ADDRESS *GatewayIp,
+ OUT CHAR16 *String
+ );
+ /******
+ This function checks static Uri given by user.
+
+ @param[in] Buffer The URI string of the boot file.
+
+ @retval EFI_SUCCESS Uri and static IP address are valid.
+ EFI_UNSUPPORTED Static Uri is invalid Format.
+ EFI_INVALID_PARAMETER Url is not supported http and https.
+ *******/
+ EFI_STATUS
+ HttpBootCheckStaticUri(IN CHAR16 *Uri);
+ /**
+ Configure Static IPv6 Address using Ip6config Protocol
+
+ @param[in] Private Pointer to HTTP boot driver private data.
+ **/
+ EFI_STATUS StaticHttpIPv6Boot (HTTP_BOOT_PRIVATE_DATA *Private);
+
+ /**
+ This function will register the IPv4 gateway address to the network device.
+
+ @param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS The new IP configuration has been configured successfully.
+ @retval Others Failed to configure the address.
+
+ **/
+ EFI_STATUS
+ HttpBootRegisterIp4Gateway (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ );
+ /**
+ This function will switch the IP4 configuration policy to Static.
+
+ @param[in] Private Pointer to HTTP boot driver private data.
+
+ @retval EFI_SUCCESS The policy is already configured to static.
+ @retval Others Other error as indicated..
+
+ **/
+ EFI_STATUS
+ HttpBootSetIp4Policy (
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ );
+ /**
+ Checks the HttpBoot Mode is static or Dhcp from the Input Devicepath.
+ And Update Private variable private->usingstatic
+
+
+ @param[in] FilePath Pointer to the device path which contains a IPV4 and IPv6 device path node.
+
+ @retval EFI_SUCCESS The IPV4 Address and IPv6 Address are successfully assigned to Private variable
+ EFI_INVALID_PARAMETER If FilePath is Null
+ **/
+ EFI_STATUS
+ HttpBootCheckBootType (IN EFI_DEVICE_PATH_PROTOCOL *FilePath,IN HTTP_BOOT_PRIVATE_DATA *Private);
+ /**
+ Get the IPv4 and IPv6 Dns Address from Input Uri
+
+
+ @param[in] Uri Input Uri from Filepath
+ @param[in] UsingIPv6 Specifies the type of IP addresses.
+ @param[in] Private The pointer to the driver's private data.
+
+ @retval EFI_SUCCESS The IPV4 Address and IPv6 Address are successfully assigned to HTTP boot driver private data.
+ EFI_INVALID_PARAMETER If Uri is not a valid Static Devicepath URI
+ **/
+ EFI_STATUS
+ HttpBootParseDnsIp(IN CHAR8 *Uri,BOOLEAN UsingIpv6,IN HTTP_BOOT_PRIVATE_DATA *Private);
#endif
*** NetworkPkg\HttpBootDxe\HttpBootDxe.inf 2020-05-07 22:54:46.000000000 +05-30
--- NetworkPkg\HttpBootDxe\HttpBootDxe.inf 2020-07-24 16:19:43.000000000 +05-30
***************
*** 1,6 ****
--- 1,15 ----
+
+ #***********************************************************************
+ #* *
+ #* Copyright (c) 1985-2020, American Megatrends International LLC. *
+ #* *
+ #* All rights reserved. Subject to AMI licensing agreement. *
+ #* *
+ #***********************************************************************
+
## @file
# This modules produce the Load File Protocol for UEFI HTTP boot.
#
# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
***************
*** 38,49 ****
--- 47,59 ----
HttpBootSupport.h
HttpBootSupport.c
HttpBootClient.h
HttpBootClient.c
HttpBootConfigVfr.vfr
HttpBootConfigStrings.uni
+ HttpBootStatic.c
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
MemoryAllocationLib
BaseLib
*** NetworkPkg\HttpBootDxe\HttpBootImpl.c 2020-05-07 22:54:46.000000000 +05-30
--- NetworkPkg\HttpBootDxe\HttpBootImpl.c 2020-08-09 20:08:53.000000000 +05-30
***************
*** 1,6 ****
--- 1,14 ----
+ //***********************************************************************
+ //* *
+ //* Copyright (c) 1985-2020, American Megatrends International LLC. *
+ //* *
+ //* All rights reserved. Subject to AMI licensing agreement. *
+ //* *
+ //***********************************************************************
+
/** @file
The implementation of EFI_LOAD_FILE_PROTOCOL for UEFI HTTP boot.
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
***************
*** 119,139 ****
Uri = NULL;
if (Private == NULL || FilePath == NULL) {
return EFI_INVALID_PARAMETER;
}
!
//
// Check the URI in the input FilePath, in order to see whether it is
// required to boot from a new specified boot file.
//
Status = HttpBootParseFilePath (FilePath, &Uri);
if (EFI_ERROR (Status)) {
return EFI_INVALID_PARAMETER;
! }
//
// Check whether we need to stop and restart the HTTP boot driver.
//
if (Private->Started) {
//
--- 127,158 ----
Uri = NULL;
if (Private == NULL || FilePath == NULL) {
return EFI_INVALID_PARAMETER;
}
! //
! // Check If HttpBoot get IP Address from user as statically or from dhcp in the input FilePath,
//
+ Status = HttpBootCheckBootType(FilePath,Private);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
// Check the URI in the input FilePath, in order to see whether it is
// required to boot from a new specified boot file.
//
Status = HttpBootParseFilePath (FilePath, &Uri);
if (EFI_ERROR (Status)) {
return EFI_INVALID_PARAMETER;
! }
!
! if (Private->UsingStatic){
! Status = HttpBootParseDnsIp(Uri,UsingIpv6,Private);
! if (EFI_ERROR(Status))
! return Status;
! }
//
// Check whether we need to stop and restart the HTTP boot driver.
//
if (Private->Started) {
//
***************
*** 161,173 ****
if (Uri != NULL) {
FreePool (Uri);
}
return EFI_ALREADY_STARTED;
}
}
!
//
// Detect whether using ipv6 or not, and set it to the private data.
//
if (UsingIpv6 && Private->Ip6Nic != NULL) {
Private->UsingIpv6 = TRUE;
} else if (!UsingIpv6 && Private->Ip4Nic != NULL) {
--- 180,201 ----
if (Uri != NULL) {
FreePool (Uri);
}
return EFI_ALREADY_STARTED;
}
}
!
! //Check the IP Address in the input FilePath and
! //update the Ip Address to Private Data
! //
! if (Private->UsingStatic){
! Status = HttpBootParseIpAddress (FilePath,Private);
! if (EFI_ERROR (Status)) {
! return Status;
! }
! }
//
// Detect whether using ipv6 or not, and set it to the private data.
//
if (UsingIpv6 && Private->Ip6Nic != NULL) {
Private->UsingIpv6 = TRUE;
} else if (!UsingIpv6 && Private->Ip4Nic != NULL) {
***************
*** 196,215 ****
--- 224,245 ----
}
}
//
// Init the content of cached DHCP offer list.
//
+ if(!Private->UsingStatic){
ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));
if (!Private->UsingIpv6) {
for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = HTTP_CACHED_DHCP4_PACKET_MAX_SIZE;
}
} else {
for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = HTTP_CACHED_DHCP6_PACKET_MAX_SIZE;
+ }
}
}
if (Private->UsingIpv6) {
//
// Set Ip6 policy to Automatic to start the Ip6 router discovery.
***************
*** 252,274 ****
return EFI_NOT_STARTED;
}
Status = EFI_DEVICE_ERROR;
if (!Private->UsingIpv6) {
! //
// Start D.O.R.A process to get a IPv4 address and other boot information.
//
! Status = HttpBootDhcp4Dora (Private);
} else {
! //
// Start S.A.R.R process to get a IPv6 address and other boot information.
//
! Status = HttpBootDhcp6Sarr (Private);
! }
!
return Status;
}
/**
Attempt to download the boot file through HTTP message exchange.
--- 282,332 ----
return EFI_NOT_STARTED;
}
Status = EFI_DEVICE_ERROR;
if (!Private->UsingIpv6) {
!
! if (!Private->UsingStatic) {
! //
// Start D.O.R.A process to get a IPv4 address and other boot information.
//
! Status = HttpBootDhcp4Dora (Private);
! }else{
! Status = HttpBootSetIp4Policy (Private);
! if (EFI_ERROR (Status)) {
! return Status;
! }
! Status = StaticHttpBoot(Private);
! if (EFI_ERROR (Status)) {
! return Status;
! }
! Status = HttpBootRegisterIp4Gateway (Private);
! if (EFI_ERROR (Status)) {
! return Status;
! }
!
! AsciiPrint ("\n Station IP address is ");
! HttpBootShowIp4Addr (&Private->StationIp.v4);
! AsciiPrint ("\n");
! }
!
} else {
!
! if (!Private->UsingStatic){
! //
// Start S.A.R.R process to get a IPv6 address and other boot information.
//
! Status = HttpBootDhcp6Sarr (Private);
! }else{
! Status = StaticHttpIPv6Boot (Private);
! AsciiPrint ("\n Station IPv6 address is ");
! HttpBootShowIp6Addr (&Private->StationIp.v6);
! AsciiPrint ("\n");
! }
! }
return Status;
}
/**
Attempt to download the boot file through HTTP message exchange.
***
--- NetworkPkg\HttpBootDxe\HttpBootStatic.c 2020-08-09 21:00:09.000000000 +05-30
***************
*** 0 ****
--- 1,650 ----
+ //***********************************************************************
+ //* *
+ //* Copyright (c) 1985-2020, American Megatrends International LLC. *
+ //* *
+ //* All rights reserved. Subject to AMI licensing agreement. *
+ //* *
+ //***********************************************************************
+
+ /** @file HttpBootStatic.c
+ Provides the Static Http Boot related functions .
+
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+
+ #include "HttpBootDxe.h"
+ #include <Library/UefiBootManagerLib.h>
+
+
+ /**
+ Get the IPv4 and IPv6 Address from the Input Devicepath.
+
+
+ @param[in] FilePath Pointer to the device path which contains a IPV4 and IPV6 device path node.
+
+ @retval EFI_SUCCESS The IPV4 Address and IPv6 Address are successfully assigned to Private variable
+ EFI_INVALID_PARAMETER If FilePath is Null
+ **/
+ EFI_STATUS
+ HttpBootParseIpAddress (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN HTTP_BOOT_PRIVATE_DATA *Private
+ )
+ {
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEV_PATH *Node;
+
+ if (FilePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS));
+ ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS));
+ ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS));
+ //
+ // Extract the IPV4 address from the FilePath
+ //
+
+ TempDevicePath = FilePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+
+ if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&
+ (DevicePathSubType (TempDevicePath) == MSG_IPv4_DP)) {
+ Node = ( EFI_DEV_PATH *)TempDevicePath;
+
+ CopyMem (&Private->StationIp.v4, &Node->Ipv4.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Private->SubnetMask.v4, &Node->Ipv4.SubnetMask , sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&Private->GatewayIp.v4, &Node->Ipv4.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
+ }
+ else if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&
+ (DevicePathSubType (TempDevicePath) == MSG_IPv6_DP)) {
+ Node = (EFI_DEV_PATH *)TempDevicePath ;
+
+ CopyMem (&Private ->StationIp.v6,&Node ->Ipv6.LocalIpAddress,sizeof (EFI_IPv6_ADDRESS));
+ CopyMem (&Private ->GatewayIp.v6,&Node ->Ipv6.GatewayIpAddress,sizeof (EFI_IPv6_ADDRESS));
+ }
+
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ /**
+ The notify function of create event when performing a manual config.
+
+ @param[in] Event The event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the event.
+
+ **/
+ VOID
+ EFIAPI
+ IfConfigManualAddressNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+ {
+ *((BOOLEAN *) Context) = TRUE;
+ }
+ /**
+ Configure Static Ip Address using Ip4config2 Protocol
+
+ @param[in] Private Pointer to HTTP boot driver private data.
+ **/
+ EFI_STATUS
+ StaticHttpBoot (HTTP_BOOT_PRIVATE_DATA *Private)
+ {
+ EFI_EVENT MappedEvt;
+ BOOLEAN IsAddressOk;
+ EFI_IP4_CONFIG2_POLICY Policy;
+ EFI_IP4_CONFIG2_MANUAL_ADDRESS ManualAddress;
+ EFI_STATUS Status;
+ UINTN DataSize ;
+ EFI_IP4_CONFIG2_PROTOCOL *IfCfg ;
+ EFI_EVENT TimeOutEvt ;
+ //
+ // Create events & timers for asynchronous settings.
+ //
+ CopyMem (&ManualAddress.Address , &Private->StationIp.v4, sizeof (EFI_IPv4_ADDRESS));
+ CopyMem (&ManualAddress.SubnetMask , &Private ->SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
+
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &TimeOutEvt
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IfConfigManualAddressNotify,
+ &IsAddressOk,
+ &MappedEvt
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ IfCfg = Private->Ip4Config2;
+ Status = IfCfg->RegisterDataNotify (
+ IfCfg,
+ Ip4Config2DataTypeManualAddress,
+ MappedEvt
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+ Policy = Ip4Config2PolicyStatic;
+ Status = IfCfg->SetData (
+ IfCfg,
+ Ip4Config2DataTypePolicy,
+ sizeof (EFI_IP4_CONFIG2_POLICY),
+ &Policy
+ );
+
+ if (EFI_ERROR(Status))
+ return Status;
+ DataSize = sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS);
+
+ Status = IfCfg->SetData (
+ IfCfg,
+ Ip4Config2DataTypeManualAddress,
+ DataSize,
+ &ManualAddress
+ );
+ if (Status == EFI_NOT_READY) {
+ gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000);
+ while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {
+ if (IsAddressOk) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ Status = IfCfg->UnregisterDataNotify (
+ IfCfg,
+ Ip4Config2DataTypeManualAddress,
+ MappedEvt
+ );
+
+ return Status;
+ }
+
+ /**
+ The notify function of create event when performing a manual config.
+
+ @param[in] Event The event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the event.
+
+ **/
+ VOID
+ EFIAPI
+ IfConfig6ManualAddressNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+ {
+ *((BOOLEAN *) Context) = TRUE;
+ }
+ /**
+ Configure Static Ipv6 Address using Ip6config Protocol
+
+ @param[in] Private Pointer to HTTP boot driver private data.
+ **/
+
+ EFI_STATUS
+ StaticHttpIPv6Boot (HTTP_BOOT_PRIVATE_DATA *Private)
+ {
+ EFI_STATUS Status;
+ EFI_IP6_CONFIG_PROTOCOL *IfCfg;
+ EFI_IP6_CONFIG_MANUAL_ADDRESS CfgManAddr;
+ UINT32 CurDadXmits;
+ UINTN CurDadXmitsLen;
+ EFI_IP6_CONFIG_POLICY Policy;
+ EFI_EVENT TimeOutEvt;
+ EFI_EVENT MappedEvt;
+ BOOLEAN IsAddressOk;
+
+ // Set static host ip6 address list.
+ // This is a asynchronous process.
+ //
+ CopyMem (&CfgManAddr.Address,&Private->StationIp.v6,sizeof(EFI_IPv6_ADDRESS));
+ CfgManAddr.PrefixLength = IP6_PREFIX_LENGTH;
+ CfgManAddr.IsAnycast = FALSE ;
+
+ IsAddressOk = FALSE;
+ IfCfg = Private->Ip6Config;
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &TimeOutEvt
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IfConfig6ManualAddressNotify,
+ &IsAddressOk,
+ &MappedEvt
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = IfCfg->RegisterDataNotify (
+ IfCfg,
+ Ip6ConfigDataTypeManualAddress,
+ MappedEvt
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Policy = Ip6ConfigPolicyManual;
+ Status = IfCfg->SetData (
+ IfCfg,
+ Ip6ConfigDataTypePolicy,
+ sizeof (EFI_IP6_CONFIG_POLICY),
+ &Policy
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = IfCfg->SetData (
+ IfCfg,
+ Ip6ConfigDataTypeManualAddress,
+ sizeof(EFI_IP6_CONFIG_MANUAL_ADDRESS),
+ &CfgManAddr
+ );
+
+
+ if (Status == EFI_NOT_READY) {
+ //
+ // Get current dad transmits count.
+ //
+ CurDadXmitsLen = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
+ Status = IfCfg->GetData (
+ IfCfg,
+ Ip6ConfigDataTypeDupAddrDetectTransmits,
+ &CurDadXmitsLen,
+ &CurDadXmits
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000 + 10000000 * CurDadXmits);
+
+ while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {
+ if (IsAddressOk) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ Status = IfCfg->SetData (
+ IfCfg,
+ Ip6ConfigDataTypeGateway,
+ sizeof(EFI_IPv6_ADDRESS),
+ &Private->GatewayIp.v6
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ ON_EXIT:
+
+ Status = IfCfg->UnregisterDataNotify (
+ IfCfg,
+ Ip6ConfigDataTypeManualAddress,
+ MappedEvt
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ return Status;
+
+ }
+ /*********
+ Get the IPv4Address,subnetMask,GatewayIp using Http Uri given by user,
+ IPV4(ClientAddress,protocol,static or Dhcp ,gatewayip,subnetMask)/Dns(DnsIP1,DnsIP2...,IPn)/Uri(_http://DomainName/xxx.efi)
+
+ @param[in] Uri The URI string of the boot file.
+ @param[out] LocalIP Ipv4 LocalP is updated statically based on Uri
+ @param[out] SubnetMask Ipv4 SubnetMask is updated statically based on Uri
+ @param[out] GatewayIp Ipv4 GatewayIp is updated statically based on Uri
+ @Param[out] String The Error Message.
+
+ @retval EFI_SUCCESS IP Address is translated from String.
+ @retval EFI_INVALID_PARAMETER Url is not supported http and https
+ EFI_UNSUPPORTED If IP Addrress and static Uri is invalid
+ ********/
+ EFI_STATUS
+ VerifyIpv4Address (
+ IN CHAR16 *Buffer,
+ OUT EFI_IP_ADDRESS *LocalIp,
+ OUT EFI_IP_ADDRESS *SubnetMask,
+ OUT EFI_IP_ADDRESS *GatewayIp,
+ OUT CHAR16 *String
+ )
+ {
+ CHAR16 *EndPointer;
+ RETURN_STATUS Status;
+ EFI_IPv4_ADDRESS Dns;
+ CHAR8 AsciiUri[URI_STR_MAX_SIZE];
+
+ if (StrnCmp (Buffer ,L"ipv4(",5)){
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid Uri Format!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer +=StrLen(L"ipv4(");
+ Status = StrToIpv4Address (Buffer, &EndPointer,&LocalIp->v4,NULL);
+ if (RETURN_ERROR (Status)){
+ StrCpyS (String ,URI_STR_MAX_SIZE,L"Invalid LocalIP address!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer = EndPointer;
+ if (StrnCmp(Buffer,L",tcp,static,",12 ) && StrnCmp(Buffer,L",tcp,dhcp,",10 )){
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid Uri Format!");
+ return EFI_UNSUPPORTED;
+ }
+ if (StrnCmp(Buffer,L",tcp,dhcp,",10))
+ Buffer +=StrLen(L",tcp,static,");
+ else
+ Buffer +=StrLen(L",tcp,dhcp,");
+
+ Status = StrToIpv4Address (Buffer,&EndPointer, &GatewayIp->v4,NULL);
+ if (RETURN_ERROR(Status)) {
+ StrCpyS (String ,URI_STR_MAX_SIZE,L"Invalid GatewayIP Address!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer = EndPointer + 1;
+ Status = StrToIpv4Address (Buffer,&EndPointer, &SubnetMask->v4,NULL);
+ if (RETURN_ERROR(Status)) {
+ StrCpyS (String ,URI_STR_MAX_SIZE,L"Invalid SubnetMask Address!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer = EndPointer;
+ if (StrnCmp(Buffer,L")/uri(",6) && StrnCmp(Buffer,L")/dns(",6)){
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid Uri Format!");
+ return EFI_UNSUPPORTED;
+ }
+ if (!StrnCmp(Buffer,L")/dns(",6))
+ {
+ Buffer += StrLen(L")/dns(");
+ do{
+ Status = StrToIpv4Address (Buffer,&EndPointer, &Dns,NULL);
+ if (RETURN_ERROR(Status)) {
+ StrCpyS (String ,URI_STR_MAX_SIZE,L"Invalid DnsServerIP Address!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer = EndPointer +1;
+ }while(*EndPointer == L',');
+ }
+ if (!StrnCmp (Buffer,L"}/uri(",6)){
+ Buffer +=StrLen(L")/uri(");
+ UnicodeStrToAsciiStrS (Buffer, AsciiUri, URI_STR_MAX_SIZE);
+ Status = HttpBootCheckUriScheme (AsciiUri);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ /******
+ Get the IPv6Address,GatewayIp6Address using Http Uri given by user,
+ IPV6(LocalIp6Address,Tcp,static or dhcp,gatewayip6Address)/Dns(IP1,IP2,...,IPn)/Uri(_http://DomainName/xxx.efi)
+
+ @param[in] Buffer URI string of the boot file.
+ @param[out] LocalIp Ipv6 LocalIp Address is updated statically based on Uri
+ @param[out] GatewayIp Ipv6 GatewayIp is updated statically based on Uri
+ @Param[out] String The Error Message.
+
+ @retval EFI_SUCCESS IP Address is translated from String.
+ @retval EFI_INVALID_PARAMETER Url is not supported http and https
+ EFI_UNSUPPORTED If IP Address is Invalid and Static Uri is invalid
+ *******/
+ EFI_STATUS
+ VerifyIpv6Address (
+ IN CHAR16 *Buffer,
+ OUT EFI_IP_ADDRESS *LocalIp,
+ OUT EFI_IP_ADDRESS *GatewayIp,
+ OUT CHAR16 *String
+ )
+ {
+
+ CHAR16 *EndPointer;
+ RETURN_STATUS Status;
+ EFI_IPv6_ADDRESS Dns;
+ CHAR8 AsciiUri[URI_STR_MAX_SIZE];
+
+ if (StrnCmp (Buffer ,L"ipv6(",5)){
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid Uri Format!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer += StrLen (L"ipv6(");
+ Status = StrToIpv6Address (Buffer, &EndPointer,&LocalIp->v6,NULL);
+ if (RETURN_ERROR (Status)){
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid LocalIP address!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer = EndPointer;
+ if (StrnCmp(Buffer,L",tcp,static,",12) && StrnCmp(Buffer,L",tcp,dhcp,",10)){
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid Uri Format!");
+ return EFI_UNSUPPORTED;
+ }
+ if (StrnCmp(Buffer,L",tcp,dhcp,",10))
+ Buffer +=StrLen(L",tcp,static,");
+ else
+ Buffer +=StrLen(L",tcp,dhcp,");
+
+ Status = StrToIpv6Address (Buffer,&EndPointer, &GatewayIp->v6,NULL);
+ if (RETURN_ERROR (Status) ) {
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid GatewayIP Address!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer = EndPointer;
+ if (StrnCmp(Buffer,L")/uri(",6) && StrnCmp(Buffer,L")/dns(",6)){
+ StrCpyS (String ,URI_STR_MAX_SIZE, L"Invalid Uri Format!");
+ return EFI_UNSUPPORTED;
+ }
+ if (!StrnCmp(Buffer,L")/dns(",6))
+ {
+ Buffer += StrLen(L")/dns(");
+ do{
+ Status = StrToIpv6Address (Buffer,&EndPointer, &Dns,NULL);
+ if (RETURN_ERROR(Status)) {
+ StrCpyS (String ,URI_STR_MAX_SIZE,L"Invalid DnsServerIP Address!");
+ return EFI_UNSUPPORTED;
+ }
+ Buffer = EndPointer +1;
+ }while(*EndPointer == L',');
+ }
+ if (!StrnCmp (Buffer,L"}/uri(",6)){
+ Buffer +=StrLen(L")/uri(");
+ UnicodeStrToAsciiStrS (Buffer, AsciiUri, URI_STR_MAX_SIZE);
+ Status = HttpBootCheckUriScheme (AsciiUri);
+ return Status;
+ }
+ return EFI_SUCCESS;
+ }
+ /******
+ This function checks static Uri given by user and returns BOOLEAN(TRUE:valid Uri,FALSE:Invalid Uri)
+
+ @param[in] Buffer The URI string of the boot file.
+
+ @retval SUCCESS Uri and static IP address are valid.
+ EFI_UNSUPPORTED Static Uri is invalid Format.
+ EFI_INVALID_PARAMETER Url is not supported http and https
+ *******/
+ EFI_STATUS
+ HttpBootCheckStaticUri(IN CHAR16 *Uri)
+ {
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+ EFI_IP_ADDRESS LocalIp;
+ EFI_IP_ADDRESS SubnetMask;
+ EFI_IP_ADDRESS GatewayIp;
+ CHAR16 ErrorMessage[URI_STR_MAX_SIZE];
+ UINTN Index = 0;
+
+ if (StrLen (Uri) == 0)
+ return EFI_INVALID_PARAMETER;
+
+ for (Index = 0; Index < StrLen (Uri); Index++) {
+ if (Uri[Index] == L'/' && Uri[Index + 1] == L'/') {
+ break;
+ }
+ if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
+ Uri[Index] -= (CHAR16)(L'A' - L'a');
+ }
+ }
+ if (StrnCmp (Uri,L"ipv4(",5) == 0){
+ Status = VerifyIpv4Address (Uri,&LocalIp,&SubnetMask,&GatewayIp,ErrorMessage);
+ if (EFI_ERROR(Status)){
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ ErrorMessage,
+ NULL
+ );
+ return Status;
+ }
+ }else if (StrnCmp (Uri,L"ipv6(",5) == 0){
+ Status = VerifyIpv6Address (Uri,&LocalIp,&GatewayIp,ErrorMessage);
+ if (EFI_ERROR(Status)){
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ ErrorMessage,
+ NULL
+ );
+ return Status;
+ }
+ }else if ((StrnCmp(Uri, L"http://", 7) != 0) && (StrnCmp(Uri, L"https://", 8) != 0)){
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"Invalid Uri",
+ NULL
+ );
+ return EFI_UNSUPPORTED;
+ }
+ return EFI_SUCCESS ;
+ }
+ /**
+ Checks the HttpBoot Mode is static or Dhcp from the Input Devicepath.
+ And Update Private Variable Private->UsingStatic
+
+
+ @param[in] FilePath Pointer to the device path which contains a IPV4 and IPv6 device path node.
+
+ @retval EFI_SUCCESS The IPV4 Address and IPv6 Address are successfully assigned to Private variable
+ EFI_INVALID_PARAMETER If FilePath is Null
+ **/
+ EFI_STATUS
+ HttpBootCheckBootType (IN EFI_DEVICE_PATH_PROTOCOL *FilePath,IN HTTP_BOOT_PRIVATE_DATA *Private)
+ {
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEV_PATH *Node;
+
+ if (FilePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TempDevicePath = FilePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH)){
+ if (DevicePathSubType (TempDevicePath) == MSG_IPv4_DP){
+ Node = (EFI_DEV_PATH *)TempDevicePath ;
+ Private->UsingStatic = Node->Ipv4.StaticIpAddress ;
+ }else if (DevicePathSubType (TempDevicePath) == MSG_IPv6_DP){
+ Node = (EFI_DEV_PATH *)TempDevicePath ;
+ Private->UsingStatic =(Node->Ipv6.IpAddressOrigin == 0x03) ? TRUE : FALSE;
+ }
+ }
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ return EFI_SUCCESS;
+ }
+ /**
+ Get the IPv4 and IPv6 Dns Address from Input Uri
+
+
+ @param[in] Uri Input Uri from Filepath
+ @param[in] UsingIPv6 Specifies the type of IP addresses.
+ @param[in] Private The pointer to the driver's private data.
+
+ @retval EFI_SUCCESS The IPV4 Address and IPv6 Address are successfully assigned to HTTP boot driver private data.
+ EFI_INVALID_PARAMETER If Uri is not a valid Static Devicepath URI
+ **/
+ EFI_STATUS
+ HttpBootParseDnsIp(IN CHAR8 *Uri,BOOLEAN UsingIpv6,IN HTTP_BOOT_PRIVATE_DATA *Private)
+ {
+ EFI_STATUS Status;
+ CHAR16 Uri2[URI_STR_MAX_SIZE];
+ UINT32 Index = 0;
+ UINTN UriStrLength = 0;
+ CHAR16 *EndPointer;
+ CHAR16 *Buffer;
+ UINTN DataSize = 0;
+
+ if (Uri == NULL)
+ return EFI_SUCCESS;
+ AsciiStrToUnicodeStrS(Uri,Uri2,URI_STR_MAX_SIZE);
+ UriStrLength = AsciiStrLen(Uri) + 1;
+ Status = HttpBootCheckStaticUri(Uri2);
+ if (EFI_ERROR(Status))
+ return Status;
+ if (Buffer = StrStr(Uri2,L"dns("))
+ {
+ Buffer += 4;
+ DataSize = sizeof(EFI_IP_ADDRESS) ;
+ Private->DnsServerIp = AllocateZeroPool(DataSize);
+ if (UsingIpv6)
+ Status = StrToIpv6Address (Buffer,&EndPointer,&Private->DnsServerIp[Index++].v6,NULL);
+ else
+ Status = StrToIpv4Address (Buffer,&EndPointer,&Private->DnsServerIp[Index++].v4,NULL);
+ if (EFI_ERROR(Status)){
+ FreePool(Private->DnsServerIp);
+ Private->DnsServerIp = NULL;
+ return Status;
+ }
+ while(*EndPointer == L','){
+ Private->DnsServerIp = ReallocatePool(DataSize,DataSize + sizeof(EFI_IP_ADDRESS),Private->DnsServerIp);
+ if (UsingIpv6)
+ Status = StrToIpv6Address (Buffer,&EndPointer,&Private->DnsServerIp[Index++].v6,NULL);
+ else
+ Status = StrToIpv4Address (Buffer,&EndPointer,&Private->DnsServerIp[Index++].v4,NULL);
+ if (EFI_ERROR(Status)){
+ FreePool(Private->DnsServerIp);
+ Private->DnsServerIp = NULL;
+ return Status;
+ }
+ Buffer = EndPointer + 1;
+ }while(*EndPointer == L',');
+ Private->DnsServerCount = Index;
+ if (Buffer = StrStr(Uri2,L"http")){
+ for (Index =0;Buffer[Index] != L')' && Buffer[Index] != L'\0' ;Index++);
+ Buffer[Index] = L'\0';
+ }
+ UnicodeStrToAsciiStrS(Buffer,Uri,UriStrLength);
+ }
+ return EFI_SUCCESS;
+ }
+
[-- Attachment #2: Type: text/html, Size: 250647 bytes --]
next reply other threads:[~2020-08-13 15:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-13 15:59 Sivaraman Nainar [this message]
2020-08-13 20:00 ` [edk2-devel] [Patch ] Static IP based HTTP Support Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=B4DE137BDB63634BAC03BD9DE765F19702B4B34FEC@VENUS1.in.megatrends.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox