/** @file
  Helper functions for configuring or obtaining the parameters relating to IP6.

  Copyright (c) 2010 - 2014, 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;
}
