/** @file
  Helper functions for configuring or obtaining the parameters relating to IP6.

  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip6Impl.h"

CHAR16    mIp6ConfigStorageName[]     = L"IP6_CONFIG_IFR_NVDATA";

/**
  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
Ip6ConfigManualAddressNotify (
  IN EFI_EVENT    Event,
  IN VOID         *Context
  )
{
  *((BOOLEAN *) Context) = TRUE;
}

/**
  Get the configuration data for the EFI IPv6 network stack running on the
  communication. It is a help function to the call EfiIp6ConfigGetData().

  @param[in]      Ip6Config      The pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
  @param[in]      DataType       The type of data to get.
  @param[out]     DataSize       The size of buffer required in bytes.
  @param[out]     Data           The data buffer in which the configuration data is returned. The
                                 type of the data buffer associated with the DataType.
                                 It is the caller's responsibility to free the resource.

  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
                                - Ip6Config is NULL or invalid.
                                - DataSize is NULL.
                                - Data is NULL.
  @retval EFI_OUT_OF_RESOURCES  Fail to perform the operation due to lack of resources.
  @retval EFI_NOT_READY         The specified configuration data is not ready due to an
                                asynchronous configuration process already in progress.
  @retval EFI_NOT_FOUND         The specified configuration data was not found.

**/
EFI_STATUS
Ip6ConfigNvGetData (
  IN  EFI_IP6_CONFIG_PROTOCOL                *Ip6Config,
  IN  EFI_IP6_CONFIG_DATA_TYPE               DataType,
  OUT UINTN                                  *DataSize,
  OUT VOID                                   **Data
  )
{
  UINTN                   BufferSize;
  VOID                    *Buffer;
  EFI_STATUS              Status;

  if ((Ip6Config == NULL) || (Data == NULL) || (DataSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  BufferSize = 0;
  Status = Ip6Config->GetData (
                        Ip6Config,
                        DataType,
                        &BufferSize,
                        NULL
                        );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return Status;
  }

  Buffer = AllocateZeroPool (BufferSize);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = Ip6Config->GetData (
                        Ip6Config,
                        DataType,
                        &BufferSize,
                        Buffer
                        );
  if (EFI_ERROR (Status)) {
    FreePool (Buffer);
    return Status;
  }

  *DataSize = BufferSize;
  *Data     = Buffer;

  return EFI_SUCCESS;
}

/**
  Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified
  with ListHead.

  @param[in]      ListHead  The head of the list array in IP6_ADDRESS_INFO_ENTRY.

**/
VOID
Ip6FreeAddressInfoList (
  IN LIST_ENTRY                  *ListHead
  )
{
  IP6_ADDRESS_INFO_ENTRY         *Node;
  LIST_ENTRY                     *Entry;
  LIST_ENTRY                     *NextEntry;

  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ListHead) {
    Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);
    RemoveEntryList (&Node->Link);
    FreePool (Node);
  }
}

/**
  Convert the IPv6 address into a formatted string.

  @param[in]  Ip6       The IPv6 address.
  @param[out] Str       The formatted IP string.

**/
VOID
Ip6ToStr (
  IN  EFI_IPv6_ADDRESS  *Ip6,
  OUT CHAR16            *Str
  )
{
  UINTN                 Index;
  BOOLEAN               Short;
  UINTN                 Number;
  CHAR16                FormatString[8];

  Short = FALSE;

  for (Index = 0; Index < 15; Index = Index + 2) {
    if (!Short &&
        Index % 2 == 0 &&
        Ip6->Addr[Index] == 0 &&
        Ip6->Addr[Index + 1] == 0
        ) {
      //
      // Deal with the case of ::.
      //
      if (Index == 0) {
        *Str       = L':';
        *(Str + 1) = L':';
        Str        = Str + 2;
      } else {
        *Str       = L':';
        Str        = Str + 1;
      }

      while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) {
        Index = Index + 2;
      }

      Short = TRUE;

      if (Index == 16) {
        //
        // :: is at the end of the address.
        //
        *Str = L'\0';
        break;
      }
    }

    ASSERT (Index < 15);

    if (Ip6->Addr[Index] == 0) {
      Number = UnicodeSPrint (Str, 2 * IP6_STR_MAX_SIZE, L"%x:", (UINTN) Ip6->Addr[Index + 1]);
    } else {
      if (Ip6->Addr[Index + 1] < 0x10) {
        CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:"));
      } else {
        CopyMem (FormatString, L"%x%x:", StrSize (L"%x%x:"));
      }

      Number = UnicodeSPrint (
                 Str,
                 2 * IP6_STR_MAX_SIZE,
                 (CONST CHAR16 *) FormatString,
                 (UINTN) Ip6->Addr[Index],
                 (UINTN) Ip6->Addr[Index + 1]
                 );
    }

    Str = Str + Number;

    if (Index + 2 == 16) {
      *Str = L'\0';
      if (*(Str - 1) == L':') {
        *(Str - 1) = L'\0';
      }
    }
  }
}

/**
  Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.

  @param[out]      String  The buffer to store the converted string.
  @param[in]       IfId    The pointer of EFI_IP6_CONFIG_INTERFACE_ID.

  @retval EFI_SUCCESS              The string converted successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.

**/
EFI_STATUS
Ip6ConvertInterfaceIdToString (
  OUT CHAR16                         *String,
  IN  EFI_IP6_CONFIG_INTERFACE_ID    *IfId
  )
{
  UINT8                          Index;
  UINTN                          Number;

  if ((String == NULL) || (IfId == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  for (Index = 0; Index < 8; Index++) {
    Number = UnicodeSPrint (
               String,
               2 * INTERFACE_ID_STR_STORAGE,
               L"%x:",
               (UINTN) IfId->Id[Index]
               );
    String = String + Number;
  }

  *(String - 1) = '\0';

  return EFI_SUCCESS;
}

/**
  Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.

  @param[in]        String  The buffer of the string to be parsed.
  @param[out]       IfId    The pointer of EFI_IP6_CONFIG_INTERFACE_ID.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.

**/
EFI_STATUS
Ip6ParseInterfaceIdFromString (
  IN CONST CHAR16                    *String,
  OUT EFI_IP6_CONFIG_INTERFACE_ID    *IfId
  )
{
  UINT8                          Index;
  CHAR16                         *IfIdStr;
  CHAR16                         *TempStr;
  UINTN                          NodeVal;

  if ((String == NULL) || (IfId == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  IfIdStr = (CHAR16 *) String;

  ZeroMem (IfId, sizeof (EFI_IP6_CONFIG_INTERFACE_ID));

  for (Index = 0; Index < 8; Index++) {
    TempStr = IfIdStr;

    while ((*IfIdStr != L'\0') && (*IfIdStr != L':')) {
      IfIdStr++;
    }

    //
    // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.
    // If the number of X is less than 8, zero is appended to the InterfaceId.
    //
    if ((*IfIdStr == ':') && (Index == 7)) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Convert the string to interface id. AsciiStrHexToUintn stops at the
    // first character that is not a valid hex character, ':' or '\0' here.
    //
    NodeVal = StrHexToUintn (TempStr);
    if (NodeVal > 0xFF) {
      return EFI_INVALID_PARAMETER;
    }

    IfId->Id[Index] = (UINT8) NodeVal;

    IfIdStr++;
  }

  return EFI_SUCCESS;
}

/**
  Create Hii Extend Label OpCode as the start opcode and end opcode. It is
  a help function.

  @param[in]  StartLabelNumber   The number of start label.
  @param[out] StartOpCodeHandle  Points to the start opcode handle.
  @param[out] StartLabel         Points to the created start opcode.
  @param[out] EndOpCodeHandle    Points to the end opcode handle.
  @param[out] EndLabel           Points to the created end opcode.

  @retval EFI_OUT_OF_RESOURCES   Does not have sufficient resources to finish this
                                 operation.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.
  @retval EFI_SUCCESS            The operation completed successfully.

**/
EFI_STATUS
Ip6CreateOpCode (
  IN  UINT16                        StartLabelNumber,
  OUT VOID                          **StartOpCodeHandle,
  OUT EFI_IFR_GUID_LABEL            **StartLabel,
  OUT VOID                          **EndOpCodeHandle,
  OUT EFI_IFR_GUID_LABEL            **EndLabel
  )
{
  EFI_STATUS                        Status;
  EFI_IFR_GUID_LABEL                *InternalStartLabel;
  EFI_IFR_GUID_LABEL                *InternalEndLabel;

  if (StartOpCodeHandle == NULL || StartLabel == NULL || EndOpCodeHandle == NULL || EndLabel == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *StartOpCodeHandle = NULL;
  *EndOpCodeHandle   = NULL;
  Status             = EFI_OUT_OF_RESOURCES;

  //
  // Initialize the container for dynamic opcodes.
  //
  *StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (*StartOpCodeHandle == NULL) {
    return Status;
  }

  *EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (*EndOpCodeHandle == NULL) {
    goto Exit;
  }

  //
  // Create Hii Extend Label OpCode as the start opcode.
  //
  InternalStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                                *StartOpCodeHandle,
                                                &gEfiIfrTianoGuid,
                                                NULL,
                                                sizeof (EFI_IFR_GUID_LABEL)
                                                );
  if (InternalStartLabel == NULL) {
    goto Exit;
  }

  InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  InternalStartLabel->Number       = StartLabelNumber;

  //
  // Create Hii Extend Label OpCode as the end opcode.
  //
  InternalEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                              *EndOpCodeHandle,
                                              &gEfiIfrTianoGuid,
                                              NULL,
                                              sizeof (EFI_IFR_GUID_LABEL)
                                              );
  if (InternalEndLabel == NULL) {
    goto Exit;
  }

  InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  InternalEndLabel->Number       = LABEL_END;

  *StartLabel = InternalStartLabel;
  *EndLabel   = InternalEndLabel;

  return EFI_SUCCESS;

Exit:

  if (*StartOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (*StartOpCodeHandle);
  }

  if (*EndOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (*EndOpCodeHandle);
  }

  return Status;
}

/**
  This function converts the different format of address list to string format and
  then generates the corresponding text opcode to illustrate the address info in
  IP6 configuration page. Currently, the following formats are supported:
  EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;
  EFI_IPv6_ADDRESS     AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;
  EFI_IP6_ROUTE_TABLE  AddressType: Ip6ConfigNvRouteTable.

  @param[in, out] String           The pointer to the buffer to store the converted
                                   string.
  @param[in]      HiiHandle        A handle that was previously registered in the
                                   HII Database.
  @param[in]      AddressType      The address type.
  @param[in]      AddressInfo      Pointer to the address list.
  @param[in]      AddressCount     The address count of the address list.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.
  @retval EFI_UNSUPPORTED          The AddressType is not supported.


**/
EFI_STATUS
Ip6ConvertAddressListToString (
  IN OUT CHAR16                         *String,
  IN     EFI_HII_HANDLE                 HiiHandle,
  IN     IP6_CONFIG_NV_ADDRESS_TYPE     AddressType,
  IN     VOID                           *AddressInfo,
  IN     UINTN                          AddressCount
  )
{
  UINTN                          Index;
  UINTN                          Number;
  CHAR16                         *TempStr;
  EFI_STATUS                     Status;
  VOID                           *StartOpCodeHandle;
  EFI_IFR_GUID_LABEL             *StartLabel;
  VOID                           *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL             *EndLabel;
  UINT16                         StartLabelNumber;
  EFI_STRING_ID                  TextTwo;
  UINT8                          *AddressHead;
  UINT8                          PrefixLength;
  EFI_IPv6_ADDRESS               *Address;

  if ((String == NULL) || (HiiHandle == NULL) || (AddressInfo == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (AddressType == Ip6ConfigNvHostAddress) {
    StartLabelNumber = HOST_ADDRESS_LABEL;
  } else if (AddressType == Ip6ConfigNvGatewayAddress) {
    StartLabelNumber = GATEWAY_ADDRESS_LABEL;
  } else if (AddressType == Ip6ConfigNvDnsAddress) {
    StartLabelNumber = DNS_ADDRESS_LABEL;
  } else if (AddressType == Ip6ConfigNvRouteTable) {
    StartLabelNumber = ROUTE_TABLE_LABEL;
  } else {
    ASSERT (FALSE);
    return EFI_UNSUPPORTED;
  }

  Status = Ip6CreateOpCode (
             StartLabelNumber,
             &StartOpCodeHandle,
             &StartLabel,
             &EndOpCodeHandle,
             &EndLabel
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  AddressHead = (UINT8 *) AddressInfo;

  for (Index = 0; Index < AddressCount; Index++) {
    if (AddressType == Ip6ConfigNvHostAddress) {
      AddressInfo = AddressHead + sizeof (EFI_IP6_ADDRESS_INFO) * Index;
      Address     = &((EFI_IP6_ADDRESS_INFO *) AddressInfo)->Address;
    } else if (AddressType == Ip6ConfigNvRouteTable) {
      AddressInfo = AddressHead + sizeof (EFI_IP6_ROUTE_TABLE) * Index;
      Address     = &((EFI_IP6_ROUTE_TABLE *) AddressInfo)->Destination;
    } else {
      AddressInfo = AddressHead + sizeof (EFI_IPv6_ADDRESS) * Index;
      Address     = AddressInfo;
    }

    //
    // Convert the IP address info to string.
    //
    Ip6ToStr (Address, String);
    TempStr = String + StrLen (String);

    if ((AddressType == Ip6ConfigNvHostAddress) || (AddressType == Ip6ConfigNvRouteTable)) {
      if (AddressType == Ip6ConfigNvHostAddress) {
        PrefixLength = ((EFI_IP6_ADDRESS_INFO *) AddressInfo)->PrefixLength;
      } else {
        PrefixLength = ((EFI_IP6_ROUTE_TABLE *) AddressInfo)->PrefixLength;
      }

      //
      // Append the prefix length to the string.
      //
      *TempStr = L'/';
      TempStr++;
      Number  = UnicodeSPrint (TempStr, 6, L"%d", PrefixLength);
      TempStr = TempStr + Number;
    }

    if (AddressType == Ip6ConfigNvRouteTable) {
      //
      // Append " >> " to the string.
      //
      Number   = UnicodeSPrint (TempStr, 8, L" >>  ");
      TempStr  = TempStr + Number;

      //
      // Append the gateway address to the string.
      //
      Ip6ToStr (&((EFI_IP6_ROUTE_TABLE *) AddressInfo)->Gateway, TempStr);
      TempStr = TempStr + StrLen (TempStr);
    }

    //
    // Generate a text opcode and update the UI.
    //
    TextTwo = HiiSetString (HiiHandle, 0, String, NULL);
    if (TextTwo == 0) {
      Status = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    HiiCreateTextOpCode (StartOpCodeHandle, STR_NULL, STR_NULL, TextTwo);

    String = TempStr;
    *String = IP6_ADDRESS_DELIMITER;
    String++;
  }

  *(String - 1) = '\0';

  Status = HiiUpdateForm (
             HiiHandle,                       // HII handle
             &gIp6ConfigNvDataGuid,           // Formset GUID
             FORMID_MAIN_FORM,                // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

Exit:
  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  return Status;
}

/**
  Parse address list in string format and convert it to a list array of node in
  IP6_ADDRESS_INFO_ENTRY.

  @param[in]        String         The buffer to string to be parsed.
  @param[out]       ListHead       The list head of array.
  @param[out]       AddressCount   The number of list nodes in the array.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES     Failed to perform the operation due to lack of resource.

**/
EFI_STATUS
Ip6ParseAddressListFromString (
  IN CONST CHAR16                    *String,
  OUT LIST_ENTRY                     *ListHead,
  OUT UINT32                         *AddressCount
  )
{
  EFI_STATUS                     Status;
  CHAR16                         *LocalString;
  CHAR16                         *Temp;
  CHAR16                         *TempStr;
  EFI_IP6_ADDRESS_INFO           AddressInfo;
  IP6_ADDRESS_INFO_ENTRY         *Node;
  BOOLEAN                        Last;
  UINT32                         Count;

  if ((String == NULL) || (ListHead == NULL) || (AddressCount == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ZeroMem (&AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));
  LocalString = (CHAR16 *) AllocateCopyPool (StrSize (String), String);
  if (LocalString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Clean the original address list.
  //
  Ip6FreeAddressInfoList (ListHead);

  Temp  = LocalString;
  Last  = FALSE;
  Count = 0;

  while (*LocalString != L'\0') {
    TempStr = LocalString;
    while ((*LocalString != L'\0') && (*LocalString != IP6_ADDRESS_DELIMITER)) {
      LocalString++;
    }

    if (*LocalString == L'\0') {
      Last = TRUE;
    }

    *LocalString = L'\0';

    Status = NetLibStrToIp6andPrefix (TempStr, &AddressInfo.Address, &AddressInfo.PrefixLength);
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    if (AddressInfo.PrefixLength == 0xFF) {
      AddressInfo.PrefixLength = 0;
    }

    if (!NetIp6IsValidUnicast (&AddressInfo.Address)) {
      Status = EFI_INVALID_PARAMETER;
      goto Error;
    }

    Node = AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY));
    if (Node == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }

    CopyMem (&Node->AddrInfo, &AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));
    InsertTailList (ListHead, &Node->Link);
    Count++;

    if (Last) {
      break;
    }

    LocalString++;
  }

  FreePool (Temp);
  *AddressCount = Count;
  return EFI_SUCCESS;

Error:
  Ip6FreeAddressInfoList (ListHead);
  FreePool (Temp);
  return Status;
}

/**
  This function converts the interface info to string and draws it to the IP6 UI.
  The interface information includes interface name, interface type, hardware
  address and route table information.

  @param[in]       IfInfo          The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
  @param[in]       HiiHandle       The handle that was previously registered in the
                                   HII Database.
  @param[in, out]  IfrNvData       Points to IP6_CONFIG_IFR_NVDATA.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES     The operation failed due to lack of resources.

**/
EFI_STATUS
Ip6ConvertInterfaceInfoToString (
  IN     EFI_IP6_CONFIG_INTERFACE_INFO  *IfInfo,
  IN     EFI_HII_HANDLE                 HiiHandle,
  IN OUT IP6_CONFIG_IFR_NVDATA          *IfrNvData
  )
{
  UINT32                         Index;
  UINTN                          Number;
  CHAR16                         *String;
  CHAR16                         PortString[ADDRESS_STR_MAX_SIZE];
  CHAR16                         FormatString[8];
  EFI_STRING_ID                  StringId;

  if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Print the interface name.
  //
  StringId = HiiSetString (
               HiiHandle,
               STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT),
               IfInfo->Name,
               NULL
               );
  if (StringId == 0) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Print the interface type.
  //
  if (IfInfo->IfType == Ip6InterfaceTypeEthernet) {
    CopyMem (PortString, IP6_ETHERNET, sizeof (IP6_ETHERNET));
  } else if (IfInfo->IfType == Ip6InterfaceTypeExperimentalEthernet) {
    CopyMem (PortString, IP6_EXPERIMENTAL_ETHERNET, sizeof (IP6_EXPERIMENTAL_ETHERNET));
  } else {
    //
    // Refer to RFC1700, chapter Number Hardware Type.
    //
    UnicodeSPrint (PortString, 6, L"%d", IfInfo->IfType);
  }

  StringId = HiiSetString (
               HiiHandle,
               STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT),
               PortString,
               NULL
               );
  if (StringId == 0) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Convert the hardware address.
  //
  String = PortString;
  ASSERT (IfInfo->HwAddressSize <= 32);

  for (Index = 0; Index < IfInfo->HwAddressSize; Index++) {

    if (IfInfo->HwAddress.Addr[Index] < 0x10) {
      CopyMem (FormatString, L"0%x-", sizeof (L"0%x-"));
    } else {
      CopyMem (FormatString, L"%x-", sizeof (L"%x-"));
    }

    Number = UnicodeSPrint (
               String,
               8,
               (CONST CHAR16 *) FormatString,
               (UINTN) IfInfo->HwAddress.Addr[Index]
               );
    String = String + Number;
  }

  if (Index != 0) {
    ASSERT (String > PortString);
    String--;
    *String = '\0';
  }

  //
  // Print the hardware address.
  //
  StringId = HiiSetString (
               HiiHandle,
               STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT),
               PortString,
               NULL
               );
  if (StringId == 0) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.

  @param[in]      Instance         Points to IP6 config instance data.
  @param[in]      AddressType      The address type.
  @param[out]     AddressInfo      The pointer to the buffer to store the address list.
  @param[out]     AddressSize      The address size of the address list.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.
  @retval EFI_UNSUPPORTED          The AddressType is not supported.

**/
EFI_STATUS
Ip6BuildNvAddressInfo (
  IN  IP6_CONFIG_INSTANCE            *Instance,
  IN  IP6_CONFIG_NV_ADDRESS_TYPE     AddressType,
  OUT VOID                           **AddressInfo,
  OUT UINTN                          *AddressSize
  )
{
  IP6_CONFIG_NVDATA                  *Ip6NvData;
  LIST_ENTRY                         *Entry;
  LIST_ENTRY                         *ListHead;
  IP6_ADDRESS_INFO_ENTRY             *Node;
  VOID                               *AddressList;
  VOID                               *TmpStr;
  UINTN                              DataSize;
  EFI_IPv6_ADDRESS                   *Ip6Address;
  EFI_IP6_CONFIG_MANUAL_ADDRESS      *ManualAddress;

  if ((Instance == NULL) || (AddressInfo == NULL) || (AddressSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);

  Ip6NvData = &Instance->Ip6NvData;

  if (AddressType == Ip6ConfigNvHostAddress) {
    ListHead = &Ip6NvData->ManualAddress;
    DataSize = sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS) * Ip6NvData->ManualAddressCount;
  } else if (AddressType == Ip6ConfigNvGatewayAddress) {
    ListHead = &Ip6NvData->GatewayAddress;
    DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->GatewayAddressCount;
  } else if (AddressType == Ip6ConfigNvDnsAddress) {
    ListHead = &Ip6NvData->DnsAddress;
    DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->DnsAddressCount;
  } else {
    return EFI_UNSUPPORTED;
  }

  AddressList = AllocateZeroPool (DataSize);
  if (AddressList  == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TmpStr = AddressList;

  NET_LIST_FOR_EACH (Entry, ListHead) {
    Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);
    if (AddressType == Ip6ConfigNvHostAddress) {
      ManualAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) AddressList;
      IP6_COPY_ADDRESS (&ManualAddress->Address, &Node->AddrInfo.Address);
      ManualAddress->PrefixLength = Node->AddrInfo.PrefixLength;
      AddressList = (UINT8 *) AddressList + sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
    } else {
      Ip6Address = (EFI_IPv6_ADDRESS *) AddressList;
      IP6_COPY_ADDRESS (Ip6Address, &Node->AddrInfo.Address);
      AddressList = (UINT8 *) AddressList + sizeof (EFI_IPv6_ADDRESS);
    }
  }

  *AddressInfo = TmpStr;
  *AddressSize = DataSize;
  return EFI_SUCCESS;
}

/**
  Convert the IP6 configuration data into the IFR data.

  @param[in, out]  IfrNvData       The IFR NV data.
  @param[in]       Instance        The IP6 config instance data.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.
  @retval EFI_UNSUPPORTED          The policy is not supported in the current implementation.
  @retval Others                   Other errors as indicated.

**/
EFI_STATUS
Ip6ConvertConfigNvDataToIfrNvData (
  IN OUT IP6_CONFIG_IFR_NVDATA       *IfrNvData,
  IN     IP6_CONFIG_INSTANCE         *Instance
  )
{
  IP6_CONFIG_NVDATA                          *Ip6NvData;
  EFI_IP6_CONFIG_PROTOCOL                    *Ip6Config;
  UINTN                                      DataSize;
  VOID                                       *Data;
  EFI_STATUS                                 Status;
  EFI_IP6_CONFIG_POLICY                      Policy;
  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS   DadXmits;
  EFI_HII_HANDLE                             HiiHandle;

  if ((IfrNvData == NULL) || (Instance == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);

  Ip6Config = &Instance->Ip6Config;
  Ip6NvData = &Instance->Ip6NvData;
  Data      = NULL;
  DataSize  = 0;
  HiiHandle = Instance->CallbackInfo.RegisteredHandle;

  //
  // Get the current interface info.
  //
  Status = Ip6ConfigNvGetData (
             Ip6Config,
             Ip6ConfigDataTypeInterfaceInfo,
             &DataSize,
             (VOID **) &Data
             );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Convert the interface info to string and print.
  //
  Status = Ip6ConvertInterfaceInfoToString (
             (EFI_IP6_CONFIG_INTERFACE_INFO *) Data,
             HiiHandle,
             IfrNvData
             );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Get the interface id.
  //
  DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
  ZeroMem (&Ip6NvData->InterfaceId, DataSize);
  Status = Ip6Config->GetData (
                        Ip6Config,
                        Ip6ConfigDataTypeAltInterfaceId,
                        &DataSize,
                        &Ip6NvData->InterfaceId
                        );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);

  //
  // Get current policy.
  //
  DataSize = sizeof (EFI_IP6_CONFIG_POLICY);
  Status   = Ip6Config->GetData (
                          Ip6Config,
                          Ip6ConfigDataTypePolicy,
                          &DataSize,
                          &Policy
                          );

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  if (Policy == Ip6ConfigPolicyManual) {
    IfrNvData->Policy = IP6_POLICY_MANUAL;
  } else if (Policy == Ip6ConfigPolicyAutomatic) {
    IfrNvData->Policy = IP6_POLICY_AUTO;
  } else {
    ASSERT (FALSE);
    Status = EFI_UNSUPPORTED;
    goto Exit;
  }

  //
  // Get Duplicate Address Detection Transmits count.
  //
  DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
  Status   = Ip6Config->GetData (
                          Ip6Config,
                          Ip6ConfigDataTypeDupAddrDetectTransmits,
                          &DataSize,
                          &DadXmits
                          );

  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits;

Exit:
  if (Data != NULL) {
     FreePool (Data);
  }

  return Status;
}

/**
  Convert IFR data into IP6 configuration data. The policy, alternative interface
  ID, and DAD transmit counts, and will be saved.

  @param[in]       IfrNvData       The IFR NV data.
  @param[in, out]  Instance        The IP6 config instance data.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.
  @retval Others                   Other errors as indicated.

**/
EFI_STATUS
Ip6ConvertIfrNvDataToConfigNvDataGeneral (
  IN     IP6_CONFIG_IFR_NVDATA       *IfrNvData,
  IN OUT IP6_CONFIG_INSTANCE         *Instance
  )
{
  IP6_CONFIG_NVDATA                  *Ip6NvData;
  EFI_IP6_CONFIG_PROTOCOL            *Ip6Config;
  EFI_STATUS                         Status;

  if ((IfrNvData == NULL) || (Instance == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
  Ip6NvData = &Instance->Ip6NvData;
  Ip6Config = &Instance->Ip6Config;

  //
  // Update those fields which don't have INTERACTIVE attribute.
  //
  if (IfrNvData->Policy == IP6_POLICY_AUTO) {
    Ip6NvData->Policy = Ip6ConfigPolicyAutomatic;
  } else if (IfrNvData->Policy == IP6_POLICY_MANUAL) {
    Ip6NvData->Policy = Ip6ConfigPolicyManual;
  }

  Ip6NvData->DadTransmitCount.DupAddrDetectTransmits = IfrNvData->DadTransmitCount;

  //
  // Set the configured policy.
  //
  Status = Ip6Config->SetData (
                        Ip6Config,
                        Ip6ConfigDataTypePolicy,
                        sizeof (EFI_IP6_CONFIG_POLICY),
                        &Ip6NvData->Policy
                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Set the duplicate address detection transmits count.
  //
  Status = Ip6Config->SetData (
                        Ip6Config,
                        Ip6ConfigDataTypeDupAddrDetectTransmits,
                        sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),
                        &Ip6NvData->DadTransmitCount
                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Set the alternative interface ID
  //
  Status = Ip6Config->SetData (
                        Ip6Config,
                        Ip6ConfigDataTypeAltInterfaceId,
                        sizeof (EFI_IP6_CONFIG_INTERFACE_ID),
                        &Ip6NvData->InterfaceId
                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Convert IFR data into IP6 configuration data. The policy, configured
  manual address, gateway address, and DNS server address will be saved.

  @param[in]       IfrNvData       The IFR NV data.
  @param[in, out]  Instance        The IP6 config instance data.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.
  @retval Others                   Other errors as indicated.

**/
EFI_STATUS
Ip6ConvertIfrNvDataToConfigNvDataAdvanced (
  IN     IP6_CONFIG_IFR_NVDATA       *IfrNvData,
  IN OUT IP6_CONFIG_INSTANCE         *Instance
  )
{
  IP6_CONFIG_NVDATA                  *Ip6NvData;
  EFI_IP6_CONFIG_PROTOCOL            *Ip6Config;
  EFI_STATUS                         Status;
  EFI_IP6_CONFIG_MANUAL_ADDRESS      *ManualAddress;
  EFI_IPv6_ADDRESS                   *Address;
  BOOLEAN                            IsAddressOk;
  EFI_EVENT                          SetAddressEvent;
  EFI_EVENT                          TimeoutEvent;
  UINTN                              DataSize;

  if ((IfrNvData == NULL) || (Instance == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IfrNvData->Policy == IP6_POLICY_AUTO) {
    return EFI_SUCCESS;
  }

  NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
  Ip6NvData = &Instance->Ip6NvData;
  Ip6Config = &Instance->Ip6Config;

  //
  // Update those fields which don't have INTERACTIVE attribute.
  //
  Ip6NvData->Policy = Ip6ConfigPolicyManual;

  //
  // Set the configured policy.
  //
  Status = Ip6Config->SetData (
                        Ip6Config,
                        Ip6ConfigDataTypePolicy,
                        sizeof (EFI_IP6_CONFIG_POLICY),
                        &Ip6NvData->Policy
                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Create events & timers for asynchronous settings.
  //
  SetAddressEvent = NULL;
  TimeoutEvent    = NULL;
  ManualAddress   = NULL;
  Address         = NULL;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  Ip6ConfigManualAddressNotify,
                  &IsAddressOk,
                  &SetAddressEvent
                  );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &TimeoutEvent
                  );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Set the manual address list. This is an asynchronous process.
  //
  if (!IsListEmpty (&Ip6NvData->ManualAddress) && (Ip6NvData->ManualAddressCount != 0)) {
    Status = Ip6BuildNvAddressInfo (
               Instance,
               Ip6ConfigNvHostAddress,
               (VOID **) &ManualAddress,
               &DataSize
               );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    IsAddressOk = FALSE;

    Status = Ip6Config->RegisterDataNotify (
                          Ip6Config,
                          Ip6ConfigDataTypeManualAddress,
                          SetAddressEvent
                          );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    Status = Ip6Config->SetData (
                          Ip6Config,
                          Ip6ConfigDataTypeManualAddress,
                          DataSize,
                          (VOID *) ManualAddress
                          );
    if (Status == EFI_NOT_READY) {
      gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);
      while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
        if (IsAddressOk) {
          Status = EFI_SUCCESS;
        }
        break;
      }
    }

    Status = Ip6Config->UnregisterDataNotify (
                          Ip6Config,
                          Ip6ConfigDataTypeManualAddress,
                          SetAddressEvent
                          );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  //
  // Set gateway address list.
  //
  if (!IsListEmpty (&Ip6NvData->GatewayAddress) && (Ip6NvData->GatewayAddressCount != 0)) {
    Status = Ip6BuildNvAddressInfo (
               Instance,
               Ip6ConfigNvGatewayAddress,
               (VOID **) &Address,
               &DataSize
               );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    Status = Ip6Config->SetData (
                          Ip6Config,
                          Ip6ConfigDataTypeGateway,
                          DataSize,
                          (VOID *) Address
                          );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    FreePool (Address);
    Address = NULL;
  }

  //
  // Set DNS server address list.
  //
  if (!IsListEmpty (&Ip6NvData->DnsAddress) && (Ip6NvData->DnsAddressCount != 0)) {
    Status = Ip6BuildNvAddressInfo (
               Instance,
               Ip6ConfigNvDnsAddress,
               (VOID **) &Address,
               &DataSize
               );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    Status = Ip6Config->SetData (
                          Ip6Config,
                          Ip6ConfigDataTypeDnsServer,
                          DataSize,
                          (VOID *) Address
                          );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  Status = EFI_SUCCESS;

Exit:
  if (SetAddressEvent != NULL) {
    gBS->CloseEvent (SetAddressEvent);
  }

  if (TimeoutEvent != NULL) {
    gBS->CloseEvent (TimeoutEvent);
  }

  if (ManualAddress != NULL) {
    FreePool (ManualAddress);
  }

  if (Address != NULL) {
    FreePool (Address);
  }

  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_INVALID_PARAMETER   For example, passing in a NULL
                                  for the Request parameter
                                  would result in this type of
                                  error. In this case, the
                                  Progress parameter would be
                                  set to NULL.
  @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
Ip6FormExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  CONST EFI_STRING                       Request,
  OUT EFI_STRING                             *Progress,
  OUT EFI_STRING                             *Results
  )
{

  EFI_STATUS                                 Status;
  IP6_FORM_CALLBACK_INFO                     *Private;
  IP6_CONFIG_INSTANCE                        *Ip6ConfigInstance;
  IP6_CONFIG_IFR_NVDATA                      *IfrNvData;
  EFI_STRING                                 ConfigRequestHdr;
  EFI_STRING                                 ConfigRequest;
  BOOLEAN                                    AllocatedRequest;
  UINTN                                      Size;
  UINTN                                      BufferSize;

  if (This == NULL || Progress == NULL || Results == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) &&
      !HiiIsConfigHdrMatch (Request, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
  Ip6ConfigInstance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);
  BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);

  IfrNvData = (IP6_CONFIG_IFR_NVDATA *) AllocateZeroPool (BufferSize);
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = Ip6ConvertConfigNvDataToIfrNvData (IfrNvData, Ip6ConfigInstance);
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  ConfigRequest = Request;
  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 (
                         &gIp6ConfigNvDataGuid,
                         mIp6ConfigStorageName,
                         Private->ChildHandle
                         );
    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest = AllocateZeroPool (Size);
    ASSERT (ConfigRequest != NULL);
    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 *) IfrNvData,
                                BufferSize,
                                Results,
                                Progress
                                );

Exit:
  FreePool (IfrNvData);
  //
  // Free the allocated config request string.
  //
  if (AllocatedRequest) {
    FreePool (ConfigRequest);
    ConfigRequest = NULL;
  }
  //
  // 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
Ip6FormRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  CONST EFI_STRING                       Configuration,
  OUT EFI_STRING                             *Progress
  )
{
  if (This == NULL || Configuration == NULL || Progress == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check routing data in <ConfigHdr>.
  // Note: if only one Storage is used, then this checking could be skipped.
  //
  if (!HiiIsConfigHdrMatch (Configuration, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {
    *Progress = Configuration;
    return EFI_NOT_FOUND;
  }

  *Progress = Configuration + StrLen (Configuration);

  return EFI_SUCCESS;
}

/**
  Display host addresses, route table, DNS addresses and gateway addresses in
  "IPv6 Current Setting" page.

  @param[in]       Instance        The IP6 config instance data.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval Others                   Other errors as indicated.

**/
EFI_STATUS
Ip6GetCurrentSetting (
  IN IP6_CONFIG_INSTANCE        *Instance
  )
{
  EFI_IP6_CONFIG_PROTOCOL       *Ip6Config;
  EFI_HII_HANDLE                HiiHandle;
  EFI_IP6_CONFIG_INTERFACE_INFO *Data;
  UINTN                         DataSize;
  EFI_STATUS                    Status;
  CHAR16                        PortString[ADDRESS_STR_MAX_SIZE];
  EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;


  Ip6Config = &Instance->Ip6Config;
  HiiHandle = Instance->CallbackInfo.RegisteredHandle;
  Data      = NULL;

  //
  // Get current interface info.
  //
  Status = Ip6ConfigNvGetData (
             Ip6Config,
             Ip6ConfigDataTypeInterfaceInfo,
             &DataSize,
             (VOID **) &Data
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Generate dynamic text opcode for host address and draw it.
  //
  IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data;
  Status = Ip6ConvertAddressListToString (
             PortString,
             HiiHandle,
             Ip6ConfigNvHostAddress,
             IfInfo->AddressInfo,
             IfInfo->AddressInfoCount
             );
  if (EFI_ERROR (Status)) {
    FreePool (Data);
    return Status;
  }

  //
  // Generate the dynamic text opcode for route table and draw it.
  //
  Status = Ip6ConvertAddressListToString (
             PortString,
             HiiHandle,
             Ip6ConfigNvRouteTable,
             IfInfo->RouteTable,
             IfInfo->RouteCount
             );
  if (EFI_ERROR (Status)) {
    FreePool (Data);
    return Status;
  }

  //
  // Get DNS server list.
  //
  FreePool (Data);
  DataSize = 0;
  Data = NULL;
  Status = Ip6ConfigNvGetData (
             Ip6Config,
             Ip6ConfigDataTypeDnsServer,
             &DataSize,
             (VOID **) &Data
             );
  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
    if (Data != NULL) {
      FreePool (Data);
    }
    return Status;
  }

  if (DataSize > 0) {
    //
    // Generate the dynamic text opcode for DNS server and draw it.
    //
    Status = Ip6ConvertAddressListToString (
               PortString,
               HiiHandle,
               Ip6ConfigNvDnsAddress,
               Data,
               DataSize / sizeof (EFI_IPv6_ADDRESS)
               );
    if (EFI_ERROR (Status)) {
      FreePool (Data);
      return Status;
    }
  }

  //
  // Get gateway address list.
  //
  if (Data != NULL) {
    FreePool (Data);
  }

  DataSize = 0;
  Data = NULL;
  Status = Ip6ConfigNvGetData (
             Ip6Config,
             Ip6ConfigDataTypeGateway,
             &DataSize,
             (VOID **) &Data
             );
  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
    if (Data != NULL) {
      FreePool (Data);
    }
    return Status;
  }

  if (DataSize > 0) {
    //
    // Generate the dynamic text opcode for gateway and draw it.
    //
    Status = Ip6ConvertAddressListToString (
               PortString,
               HiiHandle,
               Ip6ConfigNvGatewayAddress,
               Data,
               DataSize / sizeof (EFI_IPv6_ADDRESS)
               );
    if (EFI_ERROR (Status)) {
      FreePool (Data);
      return Status;
    }
  }

  if (Data != NULL) {
    FreePool (Data);
  }

  return EFI_SUCCESS;
}

/**
  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 generated 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_PARAMETER  Passed in the wrong parameter.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
Ip6FormCallback (
  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
  )
{
  IP6_FORM_CALLBACK_INFO        *Private;
  UINTN                         BufferSize;
  IP6_CONFIG_IFR_NVDATA         *IfrNvData;
  EFI_STATUS                    Status;
  EFI_INPUT_KEY                 Key;
  IP6_CONFIG_INSTANCE           *Instance;
  IP6_CONFIG_NVDATA             *Ip6NvData;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private   = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
  Instance  = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);
  Ip6NvData = &Instance->Ip6NvData;

  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)){
    return EFI_SUCCESS;
  }

  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
    return EFI_UNSUPPORTED;
  }

  if ((Value == NULL) || (ActionRequest == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Retrieve uncommitted data from Browser
  //

  BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
  IfrNvData = AllocateZeroPool (BufferSize);
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = EFI_SUCCESS;

  HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);

  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    switch (QuestionId) {
    case KEY_GET_CURRENT_SETTING:
      Status = Ip6GetCurrentSetting (Instance);
      break;

    default:
      break;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    switch (QuestionId) {
    case KEY_SAVE_CONFIG_CHANGES:
      Status = Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData, Instance);
      if (EFI_ERROR (Status)) {
        break;
      }

      Status = Ip6GetCurrentSetting (Instance);

      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
      break;

    case KEY_IGNORE_CONFIG_CHANGES:
      Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);
      Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);
      Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);

      Ip6NvData->ManualAddressCount  = 0;
      Ip6NvData->GatewayAddressCount = 0;
      Ip6NvData->DnsAddressCount     = 0;

      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
      break;

    case KEY_SAVE_CHANGES:
      Status = Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData, Instance);
      if (EFI_ERROR (Status)) {
        break;
      }
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
      break;

    case KEY_INTERFACE_ID:
      Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Interface ID!",
          NULL
          );
      }

      break;

    case KEY_MANUAL_ADDRESS:
      Status = Ip6ParseAddressListFromString (
                 IfrNvData->ManualAddress,
                 &Ip6NvData->ManualAddress,
                 &Ip6NvData->ManualAddressCount
                 );
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Host Addresses!",
          NULL
          );
      }

      break;

    case KEY_GATEWAY_ADDRESS:
      Status = Ip6ParseAddressListFromString (
                 IfrNvData->GatewayAddress,
                 &Ip6NvData->GatewayAddress,
                 &Ip6NvData->GatewayAddressCount
                 );
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Gateway Addresses!",
          NULL
          );
      }

      break;

    case KEY_DNS_ADDRESS:
      Status = Ip6ParseAddressListFromString (
                 IfrNvData->DnsAddress,
                 &Ip6NvData->DnsAddress,
                 &Ip6NvData->DnsAddressCount
                 );
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid DNS Addresses!",
          NULL
          );
      }

      break;

    default:
      break;
    }
  }

  if (!EFI_ERROR (Status)) {
    //
    // Pass changed uncommitted data back to Form Browser.
    //
    BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
    HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL);
  }

  FreePool (IfrNvData);
  return Status;
}

/**
  Install HII Config Access protocol for network device and allocate resources.

  @param[in, out]  Instance      The IP6_CONFIG_INSTANCE to create a form.

  @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
Ip6ConfigFormInit (
  IN OUT IP6_CONFIG_INSTANCE     *Instance
  )
{
  EFI_STATUS                     Status;
  IP6_SERVICE                    *IpSb;
  IP6_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 = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
  ASSERT (IpSb != NULL);

  Status = gBS->HandleProtocol (
                  IpSb->Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  CallbackInfo = &Instance->CallbackInfo;
  CallbackInfo->Signature = IP6_FORM_CALLBACK_INFO_SIGNATURE;

  //
  // 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->HiiConfigAccess;
  ConfigAccess->ExtractConfig = Ip6FormExtractConfig;
  ConfigAccess->RouteConfig   = Ip6FormRouteConfig;
  ConfigAccess->Callback      = Ip6FormCallback;

  //
  // 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 (
                                     &gIp6ConfigNvDataGuid,
                                     CallbackInfo->ChildHandle,
                                     Ip6DxeStrings,
                                     Ip6ConfigBin,
                                     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_IP6_CONFIG_FORM_HELP),
                      NULL)
                      ;
    UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
    HiiSetString (
      CallbackInfo->RegisteredHandle,
      STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),
      MenuString,
      NULL
      );
    UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);
    HiiSetString (
      CallbackInfo->RegisteredHandle,
      STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP),
      PortString,
      NULL
      );

    FreePool (MacString);
    FreePool (OldMenuString);

    InitializeListHead (&Instance->Ip6NvData.ManualAddress);
    InitializeListHead (&Instance->Ip6NvData.GatewayAddress);
    InitializeListHead (&Instance->Ip6NvData.DnsAddress);

    return EFI_SUCCESS;
  }

Error:
  Ip6ConfigFormUnload (Instance);
  return Status;
}

/**
  Uninstall the HII Config Access protocol for network devices and free up the resources.

  @param[in, out]  Instance      The IP6_CONFIG_INSTANCE to unload a form.

**/
VOID
Ip6ConfigFormUnload (
  IN OUT IP6_CONFIG_INSTANCE     *Instance
  )
{
  IP6_SERVICE                    *IpSb;
  IP6_FORM_CALLBACK_INFO         *CallbackInfo;
  IP6_CONFIG_NVDATA              *Ip6NvData;

  IpSb = IP6_SERVICE_FROM_IP6_CONFIG_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->HiiConfigAccess,
           NULL
           );
  }

  if (CallbackInfo->HiiVendorDevicePath != NULL) {
    FreePool (CallbackInfo->HiiVendorDevicePath);
  }

  if (CallbackInfo->RegisteredHandle != NULL) {
    //
    // Remove HII package list
    //
    HiiRemovePackages (CallbackInfo->RegisteredHandle);
  }

  Ip6NvData = &Instance->Ip6NvData;

  Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);
  Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);
  Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);

  Ip6NvData->ManualAddressCount  = 0;
  Ip6NvData->GatewayAddressCount = 0;
  Ip6NvData->DnsAddressCount     = 0;
}
