public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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 --]

             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