/** @file
  Helper functions for configuring or getting the parameters relating to Ip4.

Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip4Impl.h"

CHAR16  mIp4Config2StorageName[] = L"IP4_CONFIG2_IFR_NVDATA";

/**
  Calculate the prefix length of the IPv4 subnet mask.

  @param[in]  SubnetMask The IPv4 subnet mask.

  @return The prefix length of the subnet mask.
  @retval 0 Other errors as indicated.

**/
UINT8
GetSubnetMaskPrefixLength (
  IN EFI_IPv4_ADDRESS  *SubnetMask
  )
{
  UINT8   Len;
  UINT32  ReverseMask;

  //
  // The SubnetMask is in network byte order.
  //
  ReverseMask = SwapBytes32 (*(UINT32 *)&SubnetMask[0]);

  //
  // Reverse it.
  //
  ReverseMask = ~ReverseMask;

  if ((ReverseMask & (ReverseMask + 1)) != 0) {
    return 0;
  }

  Len = 0;

  while (ReverseMask != 0) {
    ReverseMask = ReverseMask >> 1;
    Len++;
  }

  return (UINT8)(32 - Len);
}

/**
  Convert the decimal dotted IPv4 address into the binary IPv4 address.

  @param[in]   Str             The UNICODE string.
  @param[out]  Ip              The storage to return the IPv4 address.

  @retval EFI_SUCCESS           The binary IP address is returned in Ip.
  @retval EFI_INVALID_PARAMETER The IP string is malformatted.

**/
EFI_STATUS
Ip4Config2StrToIp (
  IN  CHAR16            *Str,
  OUT EFI_IPv4_ADDRESS  *Ip
  )
{
  UINTN  Index;
  UINTN  Number;

  Index = 0;

  while (*Str != L'\0') {
    if (Index > 3) {
      return EFI_INVALID_PARAMETER;
    }

    Number = 0;
    while ((*Str >= L'0') && (*Str <= L'9')) {
      Number = Number * 10 + (*Str - L'0');
      Str++;
    }

    if (Number > 0xFF) {
      return EFI_INVALID_PARAMETER;
    }

    Ip->Addr[Index] = (UINT8)Number;

    if ((*Str != L'\0') && (*Str != L'.')) {
      //
      // The current character should be either the NULL terminator or
      // the dot delimiter.
      //
      return EFI_INVALID_PARAMETER;
    }

    if (*Str == L'.') {
      //
      // Skip the delimiter.
      //
      Str++;
    }

    Index++;
  }

  if (Index != 4) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Convert the decimal dotted IPv4 addresses separated by space into the binary IPv4 address list.

  @param[in]   Str             The UNICODE string contains IPv4 addresses.
  @param[out]  PtrIpList       The storage to return the IPv4 address list.
  @param[out]  IpCount         The size of the IPv4 address list.

  @retval EFI_SUCCESS           The binary IP address list is returned in PtrIpList.
  @retval EFI_OUT_OF_RESOURCES  Error occurs in allocating memory.
  @retval EFI_INVALID_PARAMETER The IP string is malformatted.

**/
EFI_STATUS
Ip4Config2StrToIpList (
  IN  CHAR16            *Str,
  OUT EFI_IPv4_ADDRESS  **PtrIpList,
  OUT UINTN             *IpCount
  )
{
  UINTN    BeginIndex;
  UINTN    EndIndex;
  UINTN    Index;
  UINTN    IpIndex;
  CHAR16   *StrTemp;
  BOOLEAN  SpaceTag;

  BeginIndex = 0;
  EndIndex   = BeginIndex;
  Index      = 0;
  IpIndex    = 0;
  StrTemp    = NULL;
  SpaceTag   = TRUE;

  *PtrIpList = NULL;
  *IpCount   = 0;

  if (Str == NULL) {
    return EFI_SUCCESS;
  }

  //
  // Get the number of Ip.
  //
  while (*(Str + Index) != L'\0') {
    if (*(Str + Index) == L' ') {
      SpaceTag = TRUE;
    } else {
      if (SpaceTag) {
        (*IpCount)++;
        SpaceTag = FALSE;
      }
    }

    Index++;
  }

  if (*IpCount == 0) {
    return EFI_SUCCESS;
  }

  //
  // Allocate buffer for IpList.
  //
  *PtrIpList = AllocateZeroPool (*IpCount * sizeof (EFI_IPv4_ADDRESS));
  if (*PtrIpList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get IpList from Str.
  //
  Index = 0;
  while (*(Str + Index) != L'\0') {
    if (*(Str + Index) == L' ') {
      if (!SpaceTag) {
        StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));
        if (StrTemp == NULL) {
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_OUT_OF_RESOURCES;
        }

        CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));
        *(StrTemp + (EndIndex - BeginIndex)) = L'\0';

        if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {
          FreePool (StrTemp);
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_INVALID_PARAMETER;
        }

        BeginIndex = EndIndex;
        IpIndex++;

        FreePool (StrTemp);
      }

      BeginIndex++;
      EndIndex++;
      SpaceTag = TRUE;
    } else {
      EndIndex++;
      SpaceTag = FALSE;
    }

    Index++;

    if (*(Str + Index) == L'\0') {
      if (!SpaceTag) {
        StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));
        if (StrTemp == NULL) {
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_OUT_OF_RESOURCES;
        }

        CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));
        *(StrTemp + (EndIndex - BeginIndex)) = L'\0';

        if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {
          FreePool (StrTemp);
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_INVALID_PARAMETER;
        }

        FreePool (StrTemp);
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  Convert the IPv4 address into a dotted string.

  @param[in]   Ip   The IPv4 address.
  @param[out]  Str  The dotted IP string.

**/
VOID
Ip4Config2IpToStr (
  IN  EFI_IPv4_ADDRESS  *Ip,
  OUT CHAR16            *Str
  )
{
  UnicodeSPrint (
    Str,
    2 * IP4_STR_MAX_SIZE,
    L"%d.%d.%d.%d",
    Ip->Addr[0],
    Ip->Addr[1],
    Ip->Addr[2],
    Ip->Addr[3]
    );
}

/**
  Convert the IPv4 address list into string consists of several decimal
  dotted IPv4 addresses separated by space.

  @param[in]   Ip        The IPv4 address list.
  @param[in]   IpCount   The size of IPv4 address list.
  @param[out]  Str       The string contains several decimal dotted
                         IPv4 addresses separated by space.

  @retval EFI_SUCCESS           Operation is success.
  @retval EFI_OUT_OF_RESOURCES  Error occurs in allocating memory.

**/
EFI_STATUS
Ip4Config2IpListToStr (
  IN  EFI_IPv4_ADDRESS  *Ip,
  IN  UINTN             IpCount,
  OUT CHAR16            *Str
  )
{
  UINTN             Index;
  UINTN             TemIndex;
  UINTN             StrIndex;
  CHAR16            *TempStr;
  EFI_IPv4_ADDRESS  *TempIp;

  Index    = 0;
  TemIndex = 0;
  StrIndex = 0;
  TempStr  = NULL;
  TempIp   = NULL;

  for (Index = 0; Index < IpCount; Index++) {
    TempIp = Ip + Index;
    if (TempStr == NULL) {
      TempStr = AllocateZeroPool (2 * IP4_STR_MAX_SIZE);
      if (TempStr == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
    }

    UnicodeSPrint (
      TempStr,
      2 * IP4_STR_MAX_SIZE,
      L"%d.%d.%d.%d",
      TempIp->Addr[0],
      TempIp->Addr[1],
      TempIp->Addr[2],
      TempIp->Addr[3]
      );

    for (TemIndex = 0; TemIndex < IP4_STR_MAX_SIZE; TemIndex++) {
      if (*(TempStr + TemIndex) == L'\0') {
        if (Index == IpCount - 1) {
          Str[StrIndex++] = L'\0';
        } else {
          Str[StrIndex++] = L' ';
        }

        break;
      } else {
        Str[StrIndex++] = *(TempStr + TemIndex);
      }
    }
  }

  if (TempStr != NULL) {
    FreePool (TempStr);
  }

  return EFI_SUCCESS;
}

/**
  The notify function of create event when performing a manual configuration.

  @param[in]    Event        The pointer of Event.
  @param[in]    Context      The pointer of Context.

**/
VOID
EFIAPI
Ip4Config2ManualAddressNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  *((BOOLEAN *)Context) = TRUE;
}

/**
  Convert the network configuration data into the IFR data.

  @param[in]       Instance          The IP4 config2 instance.
  @param[in, out]  IfrNvData         The IFR nv data.

  @retval EFI_SUCCESS            The configure parameter to IFR data was
                                 set successfully.
  @retval EFI_INVALID_PARAMETER  Source instance or target IFR data is not available.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
Ip4Config2ConvertConfigNvDataToIfrNvData (
  IN     IP4_CONFIG2_INSTANCE    *Instance,
  IN OUT IP4_CONFIG2_IFR_NVDATA  *IfrNvData
  )
{
  IP4_SERVICE                     *IpSb;
  EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2;
  EFI_IP4_CONFIG2_INTERFACE_INFO  *Ip4Info;
  EFI_IP4_CONFIG2_POLICY          Policy;
  UINTN                           DataSize;
  UINTN                           GatewaySize;
  EFI_IPv4_ADDRESS                GatewayAddress;
  EFI_STATUS                      Status;
  UINTN                           DnsSize;
  UINTN                           DnsCount;
  EFI_IPv4_ADDRESS                *DnsAddress;

  Status      = EFI_SUCCESS;
  Ip4Config2  = &Instance->Ip4Config2;
  Ip4Info     = NULL;
  DnsAddress  = NULL;
  GatewaySize = sizeof (EFI_IPv4_ADDRESS);

  if ((IfrNvData == NULL) || (Instance == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  NET_CHECK_SIGNATURE (Instance, IP4_CONFIG2_INSTANCE_SIGNATURE);

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  if (IpSb->DefaultInterface->Configured) {
    IfrNvData->Configure = 1;
  } else {
    IfrNvData->Configure = 0;
    goto Exit;
  }

  //
  // Get the Policy info.
  //
  DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);
  Status   = Ip4Config2->GetData (
                           Ip4Config2,
                           Ip4Config2DataTypePolicy,
                           &DataSize,
                           &Policy
                           );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  if (Policy == Ip4Config2PolicyStatic) {
    IfrNvData->DhcpEnable = FALSE;
  } else if (Policy == Ip4Config2PolicyDhcp) {
    IfrNvData->DhcpEnable = TRUE;
    goto Exit;
  }

  //
  // Get the interface info.
  //
  DataSize = 0;
  Status   = Ip4Config2->GetData (
                           Ip4Config2,
                           Ip4Config2DataTypeInterfaceInfo,
                           &DataSize,
                           NULL
                           );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return Status;
  }

  Ip4Info = AllocateZeroPool (DataSize);
  if (Ip4Info == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    return Status;
  }

  Status = Ip4Config2->GetData (
                         Ip4Config2,
                         Ip4Config2DataTypeInterfaceInfo,
                         &DataSize,
                         Ip4Info
                         );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Get the Gateway info.
  //
  Status = Ip4Config2->GetData (
                         Ip4Config2,
                         Ip4Config2DataTypeGateway,
                         &GatewaySize,
                         &GatewayAddress
                         );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Get the Dns info.
  //
  DnsSize = 0;
  Status  = Ip4Config2->GetData (
                          Ip4Config2,
                          Ip4Config2DataTypeDnsServer,
                          &DnsSize,
                          NULL
                          );
  if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {
    goto Exit;
  }

  DnsCount = (UINT32)(DnsSize / sizeof (EFI_IPv4_ADDRESS));

  if (DnsSize > 0) {
    DnsAddress = AllocateZeroPool (DnsSize);
    if (DnsAddress == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    Status = Ip4Config2->GetData (
                           Ip4Config2,
                           Ip4Config2DataTypeDnsServer,
                           &DnsSize,
                           DnsAddress
                           );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  Ip4Config2IpToStr (&Ip4Info->StationAddress, IfrNvData->StationAddress);
  Ip4Config2IpToStr (&Ip4Info->SubnetMask, IfrNvData->SubnetMask);
  Ip4Config2IpToStr (&GatewayAddress, IfrNvData->GatewayAddress);
  Status = Ip4Config2IpListToStr (DnsAddress, DnsCount, IfrNvData->DnsAddress);

Exit:

  if (DnsAddress != NULL) {
    FreePool (DnsAddress);
  }

  if (Ip4Info != NULL) {
    FreePool (Ip4Info);
  }

  return Status;
}

/**
  Convert the IFR data into the network configuration data and set the IP
  configure parameters for the NIC.

  @param[in]       IfrFormNvData     The IFR NV data.
  @param[in, out]  Instance          The IP4 config2 instance.

  @retval EFI_SUCCESS            The configure parameter for this NIC was
                                 set successfully.
  @retval EFI_INVALID_PARAMETER  The address information for setting is invalid.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
Ip4Config2ConvertIfrNvDataToConfigNvData (
  IN     IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData,
  IN OUT IP4_CONFIG2_INSTANCE    *Instance
  )
{
  EFI_STATUS                Status;
  EFI_IP4_CONFIG2_PROTOCOL  *Ip4Cfg2;
  IP4_CONFIG2_NVDATA        *Ip4NvData;

  EFI_IP_ADDRESS    StationAddress;
  EFI_IP_ADDRESS    SubnetMask;
  EFI_IP_ADDRESS    Gateway;
  IP4_ADDR          Ip;
  EFI_IPv4_ADDRESS  *DnsAddress;
  UINTN             DnsCount;
  UINTN             Index;

  EFI_EVENT      TimeoutEvent;
  EFI_EVENT      SetAddressEvent;
  BOOLEAN        IsAddressOk;
  UINTN          DataSize;
  EFI_INPUT_KEY  Key;

  Status    = EFI_SUCCESS;
  Ip4Cfg2   = &Instance->Ip4Config2;
  Ip4NvData = &Instance->Ip4NvData;

  DnsCount   = 0;
  DnsAddress = NULL;

  TimeoutEvent    = NULL;
  SetAddressEvent = NULL;

  if ((Instance == NULL) || (IfrFormNvData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IfrFormNvData->Configure != TRUE) {
    return EFI_SUCCESS;
  }

  if (IfrFormNvData->DhcpEnable == TRUE) {
    Ip4NvData->Policy = Ip4Config2PolicyDhcp;

    Status = Ip4Cfg2->SetData (
                        Ip4Cfg2,
                        Ip4Config2DataTypePolicy,
                        sizeof (EFI_IP4_CONFIG2_POLICY),
                        &Ip4NvData->Policy
                        );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    //
    // Get Ip4NvData from IfrFormNvData if it is valid.
    //
    Ip4NvData->Policy = Ip4Config2PolicyStatic;

    Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);
    if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);
      return EFI_INVALID_PARAMETER;
    }

    Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);
    if (EFI_ERROR (Status) ||
        ((SubnetMask.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0]))) ||
        !Ip4StationAddressValid (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0])))
    {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);
      return EFI_INVALID_PARAMETER;
    }

    Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);
    if (EFI_ERROR (Status) ||
        ((Gateway.Addr[0] != 0) && (SubnetMask.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (SubnetMask.Addr[0]))))
    {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);
      return EFI_INVALID_PARAMETER;
    }

    Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount);
    if (!EFI_ERROR (Status) && (DnsCount > 0)) {
      for (Index = 0; Index < DnsCount; Index++) {
        CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));
        if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
          FreePool (DnsAddress);
          return EFI_INVALID_PARAMETER;
        }
      }
    } else {
      if (EFI_ERROR (Status)) {
        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
      }
    }

    if (Ip4NvData->ManualAddress != NULL) {
      FreePool (Ip4NvData->ManualAddress);
    }

    Ip4NvData->ManualAddressCount = 1;
    Ip4NvData->ManualAddress      = AllocateZeroPool (sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS));
    if (Ip4NvData->ManualAddress == NULL) {
      if (DnsAddress != NULL) {
        FreePool (DnsAddress);
      }

      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (&Ip4NvData->ManualAddress->Address, &StationAddress.v4, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Ip4NvData->ManualAddress->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));

    if (Ip4NvData->GatewayAddress != NULL) {
      FreePool (Ip4NvData->GatewayAddress);
    }

    Ip4NvData->GatewayAddressCount = 1;
    Ip4NvData->GatewayAddress      = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));
    if (Ip4NvData->GatewayAddress == NULL) {
      if (DnsAddress != NULL) {
        FreePool (DnsAddress);
      }

      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (Ip4NvData->GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));

    if (Ip4NvData->DnsAddress != NULL) {
      FreePool (Ip4NvData->DnsAddress);
    }

    Ip4NvData->DnsAddressCount = (UINT32)DnsCount;
    Ip4NvData->DnsAddress      = DnsAddress;

    //
    // Setting Ip4NvData.
    //
    Status = Ip4Cfg2->SetData (
                        Ip4Cfg2,
                        Ip4Config2DataTypePolicy,
                        sizeof (EFI_IP4_CONFIG2_POLICY),
                        &Ip4NvData->Policy
                        );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Create events & timers for asynchronous settings.
    //
    Status = gBS->CreateEvent (
                    EVT_TIMER,
                    TPL_CALLBACK,
                    NULL,
                    NULL,
                    &TimeoutEvent
                    );
    if (EFI_ERROR (Status)) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    Ip4Config2ManualAddressNotify,
                    &IsAddressOk,
                    &SetAddressEvent
                    );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    IsAddressOk = FALSE;

    Status = Ip4Cfg2->RegisterDataNotify (
                        Ip4Cfg2,
                        Ip4Config2DataTypeManualAddress,
                        SetAddressEvent
                        );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    //
    // Set ManualAddress.
    //
    DataSize = Ip4NvData->ManualAddressCount * sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS);
    Status   = Ip4Cfg2->SetData (
                          Ip4Cfg2,
                          Ip4Config2DataTypeManualAddress,
                          DataSize,
                          (VOID *)Ip4NvData->ManualAddress
                          );

    if (Status == EFI_NOT_READY) {
      gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);
      while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
        if (IsAddressOk) {
          Status = EFI_SUCCESS;
          break;
        }
      }
    }

    Ip4Cfg2->UnregisterDataNotify (
               Ip4Cfg2,
               Ip4Config2DataTypeManualAddress,
               SetAddressEvent
               );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    //
    // Set gateway.
    //
    DataSize = Ip4NvData->GatewayAddressCount * sizeof (EFI_IPv4_ADDRESS);
    Status   = Ip4Cfg2->SetData (
                          Ip4Cfg2,
                          Ip4Config2DataTypeGateway,
                          DataSize,
                          Ip4NvData->GatewayAddress
                          );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    //
    // Set DNS addresses.
    //
    if ((Ip4NvData->DnsAddressCount > 0) && (Ip4NvData->DnsAddress != NULL)) {
      DataSize = Ip4NvData->DnsAddressCount * sizeof (EFI_IPv4_ADDRESS);
      Status   = Ip4Cfg2->SetData (
                            Ip4Cfg2,
                            Ip4Config2DataTypeDnsServer,
                            DataSize,
                            Ip4NvData->DnsAddress
                            );

      if (EFI_ERROR (Status)) {
        goto Exit;
      }
    }
  }

Exit:
  if (SetAddressEvent != NULL) {
    gBS->CloseEvent (SetAddressEvent);
  }

  if (TimeoutEvent != NULL) {
    gBS->CloseEvent (TimeoutEvent);
  }

  return Status;
}

/**
  This function allows the caller to request the current
  configuration for one or more named elements. The resulting
  string is in <ConfigAltResp> format. Any and all alternative
  configuration strings shall also be appended to the end of the
  current configuration string. If they are, they must appear
  after the current configuration. They must contain the same
  routing (GUID, NAME, PATH) as the current configuration string.
  They must have an additional description indicating the type of
  alternative configuration the string represents,
  "ALTCFG=<StringToken>". That <StringToken> (when
  converted from Hex UNICODE to binary) is a reference to a
  string in the associated string pack.

  @param[in] This       Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in] Request    A null-terminated Unicode string in
                        <ConfigRequest> format. Note that this
                        includes the routing information as well as
                        the configurable name / value pairs. It is
                        invalid for this string to be in
                        <MultiConfigRequest> format.
  @param[out] Progress  On return, points to a character in the
                        Request string. Points to the string's null
                        terminator if request was successful. Points
                        to the most recent "&" before the first
                        failing name / value pair (or the beginning
                        of the string if the failure is in the first
                        name / value pair) if the request was not
                        successful.
  @param[out] Results   A null-terminated Unicode string in
                        <ConfigAltResp> format which has all values
                        filled in for the names in the Request string.
                        String to be allocated by the called function.

  @retval EFI_SUCCESS             The Results string is filled with the
                                  values corresponding to all requested
                                  names.
  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
                                  parts of the results that must be
                                  stored awaiting possible future
                                  protocols.
  @retval EFI_NOT_FOUND           Routing data doesn't match any
                                  known driver. Progress set to the
                                  first character in the routing header.
                                  Note: There is no requirement that the
                                  driver validate the routing data. It
                                  must skip the <ConfigHdr> in order to
                                  process the names.
  @retval EFI_INVALID_PARAMETER   Illegal syntax. Progress set
                                  to most recent & before the
                                  error or the beginning of the
                                  string.
  @retval EFI_INVALID_PARAMETER   Unknown name. Progress points
                                  to the & before the name in
                                  question.Currently not implemented.
**/
EFI_STATUS
EFIAPI
Ip4FormExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Request,
  OUT EFI_STRING                            *Progress,
  OUT EFI_STRING                            *Results
  )
{
  EFI_STATUS              Status;
  IP4_CONFIG2_INSTANCE    *Ip4Config2Instance;
  IP4_FORM_CALLBACK_INFO  *Private;
  IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData;
  EFI_STRING              ConfigRequestHdr;
  EFI_STRING              ConfigRequest;
  BOOLEAN                 AllocatedRequest;
  EFI_STRING              FormResult;
  UINTN                   Size;
  UINTN                   BufferSize;

  if ((Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status             = EFI_SUCCESS;
  IfrFormNvData      = NULL;
  ConfigRequest      = NULL;
  FormResult         = NULL;
  Size               = 0;
  AllocatedRequest   = FALSE;
  ConfigRequest      = Request;
  Private            = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
  Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);
  BufferSize         = sizeof (IP4_CONFIG2_IFR_NVDATA);
  *Progress          = Request;

  //
  // Check Request data in <ConfigHdr>.
  //
  if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {
    IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));
    if (IfrFormNvData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance, IfrFormNvData);

    if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
      //
      // Request has no request element, construct full request string.
      // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
      // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
      //
      ConfigRequestHdr = HiiConstructConfigHdr (&gIp4Config2NvDataGuid, mIp4Config2StorageName, Private->ChildHandle);
      Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
      ConfigRequest    = AllocateZeroPool (Size);
      if (ConfigRequest == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Failure;
      }

      AllocatedRequest = TRUE;

      UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
      FreePool (ConfigRequestHdr);
    }

    //
    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
    //
    Status = gHiiConfigRouting->BlockToConfig (
                                  gHiiConfigRouting,
                                  ConfigRequest,
                                  (UINT8 *)IfrFormNvData,
                                  BufferSize,
                                  &FormResult,
                                  Progress
                                  );

    FreePool (IfrFormNvData);

    //
    // Free the allocated config request string.
    //
    if (AllocatedRequest) {
      FreePool (ConfigRequest);
      ConfigRequest = NULL;
    }

    if (EFI_ERROR (Status)) {
      goto Failure;
    }
  }

  if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {
    *Results = FormResult;
  } else {
    return EFI_NOT_FOUND;
  }

Failure:
  //
  // Set Progress string to the original request string.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return Status;
}

/**
  This function applies changes in a driver's configuration.
  Input is a Configuration, which has the routing data for this
  driver followed by name / value configuration pairs. The driver
  must apply those pairs to its configurable storage. If the
  driver's configuration is stored in a linear block of data
  and the driver's name / value pairs are in <BlockConfig>
  format, it may use the ConfigToBlock helper function (above) to
  simplify the job. Currently not implemented.

  @param[in]  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Configuration  A null-terminated Unicode string in
                             <ConfigString> format.
  @param[out] Progress       A pointer to a string filled in with the
                             offset of the most recent '&' before the
                             first failing name / value pair (or the
                             beginning of the string if the failure
                             is in the first name / value pair) or
                             the terminating NULL if all was
                             successful.

  @retval EFI_SUCCESS             The results have been distributed or are
                                  awaiting distribution.
  @retval EFI_OUT_OF_MEMORY       Not enough memory to store the
                                  parts of the results that must be
                                  stored awaiting possible future
                                  protocols.
  @retval EFI_INVALID_PARAMETERS  Passing in a NULL for the
                                  Results parameter would result
                                  in this type of error.
  @retval EFI_NOT_FOUND           Target for the specified routing data
                                  was not found.
**/
EFI_STATUS
EFIAPI
Ip4FormRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                            *Progress
  )
{
  EFI_STATUS              Status;
  UINTN                   BufferSize;
  IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData;
  IP4_CONFIG2_INSTANCE    *Ip4Config2Instance;
  IP4_FORM_CALLBACK_INFO  *Private;

  Status        = EFI_SUCCESS;
  IfrFormNvData = NULL;

  if ((Configuration == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Configuration;

  Private            = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
  Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);

  //
  // Check Routing data in <ConfigHdr>.
  //
  if (HiiIsConfigHdrMatch (Configuration, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {
    //
    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
    //
    IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));
    if (IfrFormNvData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    BufferSize = 0;

    Status = gHiiConfigRouting->ConfigToBlock (
                                  gHiiConfigRouting,
                                  Configuration,
                                  (UINT8 *)IfrFormNvData,
                                  &BufferSize,
                                  Progress
                                  );
    if (Status != EFI_BUFFER_TOO_SMALL) {
      return Status;
    }

    Status = gHiiConfigRouting->ConfigToBlock (
                                  gHiiConfigRouting,
                                  Configuration,
                                  (UINT8 *)IfrFormNvData,
                                  &BufferSize,
                                  Progress
                                  );
    if (!EFI_ERROR (Status)) {
      Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Ip4Config2Instance);
    }

    FreePool (IfrFormNvData);
  } else {
    return EFI_NOT_FOUND;
  }

  return Status;
}

/**
  This function is called to provide results data to the driver.
  This data consists of a unique key that is used to identify
  which data is either being passed back or being asked for.

  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Action             Specifies the type of action taken by the browser.
  @param[in]  QuestionId         A unique value which is sent to the original
                                 exporting driver so that it can identify the type
                                 of data to expect. The format of the data tends to
                                 vary based on the opcode that enerated the callback.
  @param[in]  Type               The type of value for the question.
  @param[in]  Value              A pointer to the data being sent to the original
                                 exporting driver.
  @param[out] ActionRequest      On return, points to the action requested by the
                                 callback function.

  @retval EFI_SUCCESS            The callback successfully handled the action.
  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
                                 variable and its data.
  @retval EFI_DEVICE_ERROR       The variable could not be saved.
  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
                                 callback. Currently not implemented.
  @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
Ip4FormCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  EFI_BROWSER_ACTION                    Action,
  IN  EFI_QUESTION_ID                       QuestionId,
  IN  UINT8                                 Type,
  IN  EFI_IFR_TYPE_VALUE                    *Value,
  OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  EFI_STATUS              Status;
  IP4_CONFIG2_INSTANCE    *Instance;
  IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData;
  IP4_FORM_CALLBACK_INFO  *Private;

  EFI_IP_ADDRESS    StationAddress;
  EFI_IP_ADDRESS    SubnetMask;
  EFI_IP_ADDRESS    Gateway;
  IP4_ADDR          Ip;
  EFI_IPv4_ADDRESS  *DnsAddress;
  UINTN             DnsCount;
  UINTN             Index;
  EFI_INPUT_KEY     Key;

  IfrFormNvData = NULL;
  DnsCount      = 0;
  DnsAddress    = NULL;

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    Private  = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
    Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);

    IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));
    if (IfrFormNvData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Retrieve uncommitted data from Browser
    //
    if (!HiiGetBrowserData (&gIp4Config2NvDataGuid, mIp4Config2StorageName, sizeof (IP4_CONFIG2_IFR_NVDATA), (UINT8 *)IfrFormNvData)) {
      FreePool (IfrFormNvData);
      return EFI_NOT_FOUND;
    }

    Status = EFI_SUCCESS;

    switch (QuestionId) {
      case KEY_LOCAL_IP:
        Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);
        if (EFI_ERROR (Status) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress.Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress.Addr[0]))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);
          Status = EFI_INVALID_PARAMETER;
        }

        break;

      case KEY_SUBNET_MASK:
        Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);
        if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);
          Status = EFI_INVALID_PARAMETER;
        }

        break;

      case KEY_GATE_WAY:
        Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);
        if (EFI_ERROR (Status) || IP4_IS_LOCAL_BROADCAST (NTOHL (Gateway.Addr[0]))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);
          Status = EFI_INVALID_PARAMETER;
        }

        break;

      case KEY_DNS:
        Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount);
        if (!EFI_ERROR (Status) && (DnsCount > 0)) {
          for (Index = 0; Index < DnsCount; Index++) {
            CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));
            if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
              CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
              Status = EFI_INVALID_PARAMETER;
              break;
            }
          }
        } else {
          if (EFI_ERROR (Status)) {
            CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
          }
        }

        if (DnsAddress != NULL) {
          FreePool (DnsAddress);
        }

        break;

      case KEY_SAVE_CHANGES:
        Status         = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Instance);
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
        break;

      default:
        break;
    }

    FreePool (IfrFormNvData);

    return Status;
  }

  //
  // All other action return unsupported.
  //
  return EFI_UNSUPPORTED;
}

/**
  Install HII Config Access protocol for network device and allocate resource.

  @param[in, out]  Instance        The IP4 config2 Instance.

  @retval EFI_SUCCESS              The HII Config Access protocol is installed.
  @retval EFI_OUT_OF_RESOURCES     Failed to allocate memory.
  @retval Others                   Other errors as indicated.

**/
EFI_STATUS
Ip4Config2FormInit (
  IN OUT IP4_CONFIG2_INSTANCE  *Instance
  )
{
  EFI_STATUS                      Status;
  IP4_SERVICE                     *IpSb;
  IP4_FORM_CALLBACK_INFO          *CallbackInfo;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  VENDOR_DEVICE_PATH              VendorDeviceNode;
  EFI_SERVICE_BINDING_PROTOCOL    *MnpSb;
  CHAR16                          *MacString;
  CHAR16                          MenuString[128];
  CHAR16                          PortString[128];
  CHAR16                          *OldMenuString;
  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  ASSERT (IpSb != NULL);

  CallbackInfo = &Instance->CallbackInfo;

  CallbackInfo->Signature = IP4_FORM_CALLBACK_INFO_SIGNATURE;

  Status = gBS->HandleProtocol (
                  IpSb->Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Construct device path node for EFI HII Config Access protocol,
  // which consists of controller physical device path and one hardware
  // vendor guid node.
  //
  ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
  VendorDeviceNode.Header.Type    = HARDWARE_DEVICE_PATH;
  VendorDeviceNode.Header.SubType = HW_VENDOR_DP;

  CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);

  SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
  CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
                                        ParentDevicePath,
                                        (EFI_DEVICE_PATH_PROTOCOL *)&VendorDeviceNode
                                        );
  if (CallbackInfo->HiiVendorDevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  ConfigAccess                = &CallbackInfo->HiiConfigAccessProtocol;
  ConfigAccess->ExtractConfig = Ip4FormExtractConfig;
  ConfigAccess->RouteConfig   = Ip4FormRouteConfig;
  ConfigAccess->Callback      = Ip4FormCallback;

  //
  // Install Device Path Protocol and Config Access protocol on new handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &CallbackInfo->ChildHandle,
                  &gEfiDevicePathProtocolGuid,
                  CallbackInfo->HiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  ConfigAccess,
                  NULL
                  );

  if (!EFI_ERROR (Status)) {
    //
    // Open the Parent Handle for the child
    //
    Status = gBS->OpenProtocol (
                    IpSb->Controller,
                    &gEfiManagedNetworkServiceBindingProtocolGuid,
                    (VOID **)&MnpSb,
                    IpSb->Image,
                    CallbackInfo->ChildHandle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );
  }

  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // Publish our HII data
  //
  CallbackInfo->RegisteredHandle = HiiAddPackages (
                                     &gIp4Config2NvDataGuid,
                                     CallbackInfo->ChildHandle,
                                     Ip4DxeStrings,
                                     Ip4Config2Bin,
                                     NULL
                                     );
  if (CallbackInfo->RegisteredHandle == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  //
  // Append MAC string in the menu help string and tile help string
  //
  Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);
  if (!EFI_ERROR (Status)) {
    OldMenuString = HiiGetString (
                      CallbackInfo->RegisteredHandle,
                      STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),
                      NULL
                      );
    UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
    HiiSetString (
      CallbackInfo->RegisteredHandle,
      STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),
      MenuString,
      NULL
      );

    UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);
    HiiSetString (
      CallbackInfo->RegisteredHandle,
      STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP),
      PortString,
      NULL
      );

    FreePool (MacString);
    FreePool (OldMenuString);

    return EFI_SUCCESS;
  }

Error:
  Ip4Config2FormUnload (Instance);
  return Status;
}

/**
  Uninstall the HII Config Access protocol for network devices and free up the resources.

  @param[in, out]  Instance      The IP4 config2 instance to unload a form.

**/
VOID
Ip4Config2FormUnload (
  IN OUT IP4_CONFIG2_INSTANCE  *Instance
  )
{
  IP4_SERVICE             *IpSb;
  IP4_FORM_CALLBACK_INFO  *CallbackInfo;
  IP4_CONFIG2_NVDATA      *Ip4NvData;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  ASSERT (IpSb != NULL);

  CallbackInfo = &Instance->CallbackInfo;

  if (CallbackInfo->ChildHandle != NULL) {
    //
    // Close the child handle
    //
    gBS->CloseProtocol (
           IpSb->Controller,
           &gEfiManagedNetworkServiceBindingProtocolGuid,
           IpSb->Image,
           CallbackInfo->ChildHandle
           );

    //
    // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
    //
    gBS->UninstallMultipleProtocolInterfaces (
           CallbackInfo->ChildHandle,
           &gEfiDevicePathProtocolGuid,
           CallbackInfo->HiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &CallbackInfo->HiiConfigAccessProtocol,
           NULL
           );
  }

  if (CallbackInfo->HiiVendorDevicePath != NULL) {
    FreePool (CallbackInfo->HiiVendorDevicePath);
  }

  if (CallbackInfo->RegisteredHandle != NULL) {
    //
    // Remove HII package list
    //
    HiiRemovePackages (CallbackInfo->RegisteredHandle);
  }

  Ip4NvData = &Instance->Ip4NvData;

  if (Ip4NvData->ManualAddress != NULL) {
    FreePool (Ip4NvData->ManualAddress);
  }

  if (Ip4NvData->GatewayAddress != NULL) {
    FreePool (Ip4NvData->GatewayAddress);
  }

  if (Ip4NvData->DnsAddress != NULL) {
    FreePool (Ip4NvData->DnsAddress);
  }

  Ip4NvData->ManualAddressCount  = 0;
  Ip4NvData->GatewayAddressCount = 0;
  Ip4NvData->DnsAddressCount     = 0;
}
