/** @file
  Helper functions for configuring or obtaining the parameters relating to IP6.

  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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 illustarate 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
                             beginn ing 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 adderss 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;
}
