ShellPkg: Merge Ping6 and Ifconfig6 tools to Shell command.
authorZhang, Lubo <C:/Program Files (x86)/Git/o=Intel/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Zhang, Lubob8d>
Wed, 2 Mar 2016 02:13:54 +0000 (10:13 +0800)
committerJiaxin Wu <jiaxin.wu@intel.com>
Tue, 8 Mar 2016 07:01:29 +0000 (15:01 +0800)
According to the new Shell spec, we add Network2 profile and
merge Ping6 and Ifconfig6 tools to Shell command.

Cc: Carsey Jaben <jaben.carsey@intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Zhang Lubo <lubo.zhang@intel.com>
Reviewed-By: Jaben Carsey <Jaben.carsey@intel.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
ShellPkg/Include/Guid/ShellLibHiiGuid.h
ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c [new file with mode: 0644]
ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c [new file with mode: 0644]
ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c [new file with mode: 0644]
ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h [new file with mode: 0644]
ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf [new file with mode: 0644]
ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni [new file with mode: 0644]
ShellPkg/ShellPkg.dec
ShellPkg/ShellPkg.dsc

index 62c2e72..15cd85e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   GUIDs for HII package list installed by Shell libraries.\r
 \r
-  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
   { \\r
     0xf3d301bb, 0xf4a5, 0x45a8, { 0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae } \\r
   }\r
+\r
+#define SHELL_NETWORK2_HII_GUID \\r
+  { \\r
+    0x174b2b5, 0xf505, 0x4b12, { 0xaa, 0x60, 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37 } \\r
+  }\r
+\r
 #define SHELL_TFTP_HII_GUID \\r
   { \\r
     0x738a9314, 0x82c1, 0x4592, { 0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4 } \\r
@@ -73,6 +79,7 @@ extern EFI_GUID gShellLevel1HiiGuid;
 extern EFI_GUID gShellLevel2HiiGuid;\r
 extern EFI_GUID gShellLevel3HiiGuid;\r
 extern EFI_GUID gShellNetwork1HiiGuid;\r
+extern EFI_GUID gShellNetwork2HiiGuid;\r
 extern EFI_GUID gShellTftpHiiGuid;\r
 extern EFI_GUID gShellBcfgHiiGuid;\r
 \r
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
new file mode 100644 (file)
index 0000000..371b368
--- /dev/null
@@ -0,0 +1,1839 @@
+/** @file\r
+  The implementation for Shell command IfConfig6.\r
+\r
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include "UefiShellNetwork2CommandsLib.h"\r
+\r
+enum {\r
+  IfConfig6OpList     = 1,\r
+  IfConfig6OpSet      = 2,\r
+  IfConfig6OpClear    = 3\r
+};\r
+\r
+typedef enum {\r
+  VarCheckReserved      = -1,\r
+  VarCheckOk            = 0,\r
+  VarCheckDuplicate,\r
+  VarCheckConflict,\r
+  VarCheckUnknown,\r
+  VarCheckLackValue,\r
+  VarCheckOutOfMem\r
+} VAR_CHECK_CODE;\r
+\r
+typedef enum {\r
+  FlagTypeSingle         = 0,\r
+  FlagTypeNeedVar,\r
+  FlagTypeNeedSet,\r
+  FlagTypeSkipUnknown\r
+} VAR_CHECK_FLAG_TYPE;\r
+\r
+#define MACADDRMAXSIZE    32\r
+#define PREFIXMAXLEN      16\r
+\r
+typedef struct _IFCONFIG6_INTERFACE_CB {\r
+  EFI_HANDLE                                  NicHandle;\r
+  LIST_ENTRY                                  Link;\r
+  EFI_IP6_CONFIG_PROTOCOL                     *IfCfg;\r
+  EFI_IP6_CONFIG_INTERFACE_INFO               *IfInfo;\r
+  EFI_IP6_CONFIG_INTERFACE_ID                 *IfId;\r
+  EFI_IP6_CONFIG_POLICY                       Policy;\r
+  EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS    Xmits;\r
+  UINT32                                      DnsCnt;\r
+  EFI_IPv6_ADDRESS                            DnsAddr[1];\r
+} IFCONFIG6_INTERFACE_CB;\r
+\r
+typedef struct _ARG_LIST ARG_LIST;\r
+\r
+struct _ARG_LIST {\r
+  ARG_LIST    *Next;\r
+  CHAR16      *Arg;\r
+};\r
+\r
+typedef struct _IFCONFIG6_PRIVATE_DATA {\r
+  EFI_HANDLE  ImageHandle;\r
+  LIST_ENTRY  IfList;\r
+\r
+  UINT32      OpCode;\r
+  CHAR16      *IfName;\r
+  ARG_LIST    *VarArg;\r
+} IFCONFIG6_PRIVATE_DATA;\r
+\r
+typedef struct _VAR_CHECK_ITEM{\r
+  CHAR16                 *FlagStr;\r
+  UINT32                 FlagID;\r
+  UINT32                 ConflictMask;\r
+  VAR_CHECK_FLAG_TYPE    FlagType;\r
+} VAR_CHECK_ITEM;\r
+\r
+\r
+SHELL_PARAM_ITEM    mIfConfig6CheckList[] = {\r
+  {\r
+    L"-b",\r
+    TypeFlag\r
+  },\r
+  {\r
+    L"-s",\r
+    TypeMaxValue\r
+  },\r
+  {\r
+    L"-l",\r
+    TypeValue\r
+  },\r
+  {\r
+    L"-r",\r
+    TypeValue\r
+  },\r
+  {\r
+    L"-?",\r
+    TypeFlag\r
+  },\r
+  {\r
+    NULL,\r
+    TypeMax\r
+  },\r
+};\r
+\r
+VAR_CHECK_ITEM  mIfConfig6SetCheckList[] = {\r
+  {\r
+   L"auto",\r
+    0x00000001,\r
+    0x00000001,\r
+    FlagTypeSingle\r
+  },\r
+  {\r
+    L"man",\r
+    0x00000002,\r
+    0x00000001,\r
+    FlagTypeSingle\r
+  },\r
+  {\r
+    L"host",\r
+    0x00000004,\r
+    0x00000002,\r
+    FlagTypeSingle\r
+  },\r
+  {\r
+    L"dad",\r
+    0x00000008,\r
+    0x00000004,\r
+    FlagTypeSingle\r
+  },\r
+  {\r
+    L"gw",\r
+    0x00000010,\r
+    0x00000008,\r
+    FlagTypeSingle\r
+  },\r
+  {\r
+    L"dns",\r
+    0x00000020,\r
+    0x00000010,\r
+    FlagTypeSingle\r
+  },\r
+  {\r
+    L"id",\r
+    0x00000040,\r
+    0x00000020,\r
+    FlagTypeSingle\r
+  },\r
+  {\r
+    NULL,\r
+    0x0,\r
+    0x0,\r
+    FlagTypeSkipUnknown\r
+  },\r
+};\r
+\r
+/**\r
+  Split a string with specified separator and save the substring to a list.\r
+\r
+  @param[in]    String       The pointer of the input string.\r
+  @param[in]    Separator    The specified separator.\r
+\r
+  @return The pointer of headnode of ARG_LIST.\r
+\r
+**/\r
+ARG_LIST *\r
+IfConfig6SplitStrToList (\r
+  IN CONST CHAR16    *String,\r
+  IN CHAR16          Separator\r
+  )\r
+{\r
+  CHAR16      *Str;\r
+  CHAR16      *ArgStr;\r
+  ARG_LIST    *ArgList;\r
+  ARG_LIST    *ArgNode;\r
+\r
+  if (String == NULL || *String == L'\0') {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Copy the CONST string to a local copy.\r
+  //\r
+  Str     = AllocateCopyPool (StrSize (String), String);\r
+  ASSERT (Str != NULL);\r
+  ArgStr  = Str;\r
+\r
+  //\r
+  // init a node for the list head.\r
+  //\r
+  ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));\r
+  ASSERT (ArgNode != NULL);\r
+  ArgList = ArgNode;\r
+\r
+  //\r
+  // Split the local copy and save in the list node.\r
+  //\r
+  while (*Str != L'\0') {\r
+    if (*Str == Separator) {\r
+      *Str          = L'\0';\r
+      ArgNode->Arg  = ArgStr;\r
+      ArgStr        = Str + 1;\r
+      ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));\r
+      ASSERT (ArgNode->Next != NULL);\r
+      ArgNode = ArgNode->Next;\r
+    }\r
+\r
+    Str++;\r
+  }\r
+\r
+  ArgNode->Arg  = ArgStr;\r
+  ArgNode->Next = NULL;\r
+\r
+  return ArgList;\r
+}\r
+\r
+/**\r
+  Check the correctness of input Args with '-s' option.\r
+\r
+  @param[in]    CheckList    The pointer of VAR_CHECK_ITEM array.\r
+  @param[in]    Name         The pointer of input arg.\r
+  @param[in]    Init         The switch to execute the check.\r
+\r
+  @return The value of VAR_CHECK_CODE.\r
+\r
+**/\r
+VAR_CHECK_CODE\r
+IfConfig6RetriveCheckListByName(\r
+  IN VAR_CHECK_ITEM    *CheckList,\r
+  IN CHAR16            *Name,\r
+  IN BOOLEAN           Init\r
+)\r
+{\r
+  STATIC UINT32     CheckDuplicate;\r
+  STATIC UINT32     CheckConflict;\r
+  VAR_CHECK_CODE    RtCode;\r
+  UINT32            Index;\r
+  VAR_CHECK_ITEM    Arg;\r
+\r
+  if (Init) {\r
+    CheckDuplicate = 0;\r
+    CheckConflict  = 0;\r
+    return VarCheckOk;\r
+  }\r
+\r
+  RtCode  = VarCheckOk;\r
+  Index   = 0;\r
+  Arg     = CheckList[Index];\r
+\r
+  //\r
+  // Check the Duplicated/Conflicted/Unknown input Args.\r
+  //\r
+  while (Arg.FlagStr != NULL) {\r
+    if (StrCmp (Arg.FlagStr, Name) == 0) {\r
+\r
+      if (CheckDuplicate & Arg.FlagID) {\r
+        RtCode = VarCheckDuplicate;\r
+        break;\r
+      }\r
+\r
+      if (CheckConflict & Arg.ConflictMask) {\r
+        RtCode = VarCheckConflict;\r
+        break;\r
+      }\r
+\r
+      CheckDuplicate |= Arg.FlagID;\r
+      CheckConflict  |= Arg.ConflictMask;\r
+      break;\r
+    }\r
+\r
+    Arg = CheckList[++Index];\r
+  }\r
+\r
+  if (Arg.FlagStr == NULL) {\r
+    RtCode = VarCheckUnknown;\r
+  }\r
+\r
+  return RtCode;\r
+}\r
+\r
+/**\r
+  The notify function of create event when performing a manual config.\r
+\r
+  @param[in]    Event        The event this notify function registered to.\r
+  @param[in]    Context      Pointer to the context data registered to the event.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+IfConfig6ManualAddressNotify (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID         *Context\r
+  )\r
+{\r
+  *((BOOLEAN *) Context) = TRUE;\r
+}\r
+\r
+/**\r
+  Print MAC address.\r
+\r
+  @param[in]    Node    The pointer of MAC address buffer.\r
+  @param[in]    Size    The size of MAC address buffer.\r
+\r
+**/\r
+VOID\r
+IfConfig6PrintMacAddr (\r
+  IN UINT8     *Node,\r
+  IN UINT32    Size\r
+  )\r
+{\r
+  UINTN    Index;\r
+\r
+  ASSERT (Size <= MACADDRMAXSIZE);\r
+\r
+  for (Index = 0; Index < Size; Index++) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_BODY), gShellNetwork2HiiHandle, Node[Index]);\r
+    if (Index + 1 < Size) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);\r
+    }\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);\r
+}\r
+\r
+/**\r
+  Print IPv6 address.\r
+\r
+  @param[in]    Ip           The pointer of Ip bufffer in EFI_IPv6_ADDRESS format.\r
+  @param[in]    PrefixLen    The pointer of PrefixLen that describes the size Prefix.\r
+\r
+**/\r
+VOID\r
+IfConfig6PrintIpAddr (\r
+  IN EFI_IPv6_ADDRESS    *Ip,\r
+  IN UINT8               *PrefixLen\r
+  )\r
+{\r
+  UINTN      Index;\r
+  BOOLEAN    Short;\r
+\r
+  Short = FALSE;\r
+\r
+  for (Index = 0; Index < PREFIXMAXLEN; Index = Index + 2) {\r
+\r
+    if (!Short && (Index + 1 < PREFIXMAXLEN) && (Index % 2 == 0) && (Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0)) {\r
+      //\r
+      // Deal with the case of ::.\r
+      //\r
+      if (Index == 0) {\r
+        //\r
+        // :: is at the beginning of the address.\r
+        //\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);\r
+      }\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);\r
+\r
+      while ((Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0) && (Index < PREFIXMAXLEN)) {\r
+        Index = Index + 2;\r
+        if (Index > PREFIXMAXLEN - 2) {\r
+          break;\r
+        }\r
+      }\r
+\r
+      Short = TRUE;\r
+\r
+      if (Index == PREFIXMAXLEN) {\r
+        //\r
+        // :: is at the end of the address.\r
+        //\r
+        break;\r
+      }\r
+    }\r
+\r
+    if (Index < PREFIXMAXLEN - 1) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), gShellNetwork2HiiHandle, Ip->Addr[Index]);\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), gShellNetwork2HiiHandle, Ip->Addr[Index + 1]);\r
+    }\r
+\r
+    if (Index + 2 < PREFIXMAXLEN) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);\r
+    }\r
+  }\r
+\r
+  if (PrefixLen != NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), gShellNetwork2HiiHandle, *PrefixLen);\r
+  }\r
+}\r
+\r
+/**\r
+  Pick up host IPv6 address in string format from Args with "-s" option and convert it to EFI_IP6_CONFIG_MANUAL_ADDRESS format.\r
+\r
+  @param[in, out]    Arg        The pointer of the address of ARG_LIST which save Args with the "-s" option.\r
+  @param[out]        Buf        The pointer of the address of EFI_IP6_CONFIG_MANUAL_ADDRESS.\r
+  @param[out]        BufSize    The pointer of BufSize that describes the size of Buf in bytes.\r
+\r
+  @retval EFI_SUCCESS    The convertion is successful.\r
+  @retval Others         Does't find the host address, or it is an invalid IPv6 address in string format.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6ParseManualAddressList (\r
+  IN OUT ARG_LIST                         **Arg,\r
+     OUT EFI_IP6_CONFIG_MANUAL_ADDRESS    **Buf,\r
+     OUT UINTN                            *BufSize\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  EFI_IP6_CONFIG_MANUAL_ADDRESS    *AddrBuf;\r
+  ARG_LIST                         *VarArg;\r
+  EFI_IPv6_ADDRESS                 Address;\r
+  UINT8                            Prefix;\r
+  UINT8                            AddrCnt;\r
+\r
+  Prefix   = 0;\r
+  AddrCnt  = 0;\r
+  *BufSize = 0;\r
+  *Buf     = NULL;\r
+  VarArg   = *Arg;\r
+  Status   = EFI_SUCCESS;\r
+\r
+  //\r
+  // Go through the list to check the correctness of input host ip6 address.\r
+  //\r
+  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {\r
+\r
+    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // host ip ip ... gw\r
+      //\r
+      break;\r
+    }\r
+\r
+    VarArg = VarArg->Next;\r
+    AddrCnt++;\r
+  }\r
+\r
+  if (AddrCnt == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));\r
+  ASSERT (AddrBuf != NULL);\r
+\r
+  AddrCnt = 0;\r
+  VarArg  = *Arg;\r
+  Status  = EFI_SUCCESS;\r
+\r
+  //\r
+  // Go through the list to fill in the EFI_IP6_CONFIG_MANUAL_ADDRESS structure.\r
+  //\r
+  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {\r
+\r
+    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // If prefix length is not set, set it as Zero here. In the IfConfigSetInterfaceInfo()\r
+    // Zero prefix, length will be transfered to default prefix length.\r
+    //\r
+    if (Prefix == 0xFF) {\r
+      Prefix = 0;\r
+    }\r
+    AddrBuf[AddrCnt].IsAnycast    = FALSE;\r
+    AddrBuf[AddrCnt].PrefixLength = Prefix;\r
+    IP6_COPY_ADDRESS (&AddrBuf[AddrCnt].Address, &Address);\r
+    VarArg = VarArg->Next;\r
+    AddrCnt++;\r
+  }\r
+\r
+  *Arg = VarArg;\r
+\r
+  if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {\r
+    goto ON_ERROR;\r
+  }\r
+\r
+  *Buf     = AddrBuf;\r
+  *BufSize = AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);\r
+\r
+  return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+\r
+  FreePool (AddrBuf);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Pick up gw/dns IPv6 address in string format from Args with "-s" option and convert it to EFI_IPv6_ADDRESS format.\r
+\r
+  @param[in, out]    Arg        The pointer of the address of ARG_LIST that save Args with the "-s" option.\r
+  @param[out]        Buf        The pointer of the address of EFI_IPv6_ADDRESS.\r
+  @param[out]        BufSize    The pointer of BufSize that describes the size of Buf in bytes.\r
+\r
+  @retval EFI_SUCCESS    The conversion is successful.\r
+  @retval Others         Doesn't find the host address, or it is an invalid IPv6 address in string format.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6ParseGwDnsAddressList (\r
+  IN OUT ARG_LIST            **Arg,\r
+     OUT EFI_IPv6_ADDRESS    **Buf,\r
+     OUT UINTN               *BufSize\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_IPv6_ADDRESS    *AddrBuf;\r
+  ARG_LIST            *VarArg;\r
+  EFI_IPv6_ADDRESS    Address;\r
+  UINT8               Prefix;\r
+  UINT8               AddrCnt;\r
+\r
+  AddrCnt  = 0;\r
+  *BufSize = 0;\r
+  *Buf     = NULL;\r
+  VarArg   = *Arg;\r
+  Status   = EFI_SUCCESS;\r
+\r
+  //\r
+  // Go through the list to check the correctness of input gw/dns address.\r
+  //\r
+  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {\r
+\r
+    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // gw ip ip ... host\r
+      //\r
+      break;\r
+    }\r
+\r
+    VarArg = VarArg->Next;\r
+    AddrCnt++;\r
+  }\r
+\r
+  if (AddrCnt == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IPv6_ADDRESS));\r
+  ASSERT (AddrBuf != NULL);\r
+\r
+  AddrCnt = 0;\r
+  VarArg  = *Arg;\r
+  Status  = EFI_SUCCESS;\r
+\r
+  //\r
+  // Go through the list to fill in the EFI_IPv6_ADDRESS structure.\r
+  //\r
+  while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {\r
+\r
+    Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    IP6_COPY_ADDRESS (&AddrBuf[AddrCnt], &Address);\r
+\r
+    VarArg = VarArg->Next;\r
+    AddrCnt++;\r
+  }\r
+\r
+  *Arg = VarArg;\r
+\r
+  if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {\r
+   goto ON_ERROR;\r
+  }\r
+\r
+  *Buf     = AddrBuf;\r
+  *BufSize = AddrCnt * sizeof (EFI_IPv6_ADDRESS);\r
+\r
+  return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+\r
+  FreePool (AddrBuf);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Parse InterfaceId in string format from Args with the "-s" option and convert it to EFI_IP6_CONFIG_INTERFACE_ID format.\r
+\r
+  @param[in, out]   Arg     The pointer of the address of ARG_LIST that saves Args with the "-s" option.\r
+  @param[out]       IfId    The pointer of EFI_IP6_CONFIG_INTERFACE_ID.\r
+\r
+  @retval EFI_SUCCESS              The get status processed successfullly.\r
+  @retval EFI_INVALID_PARAMETER    The get status process failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6ParseInterfaceId (\r
+  IN OUT ARG_LIST                       **Arg,\r
+     OUT EFI_IP6_CONFIG_INTERFACE_ID    **IfId\r
+  )\r
+{\r
+  UINT8     Index;\r
+  UINT8     NodeVal;\r
+  CHAR16    *IdStr;\r
+\r
+  if (*Arg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Index = 0;\r
+  IdStr = (*Arg)->Arg;\r
+  ASSERT (IfId != NULL);\r
+  *IfId = AllocateZeroPool (sizeof (EFI_IP6_CONFIG_INTERFACE_ID));\r
+  ASSERT (*IfId != NULL);\r
+\r
+  while ((*IdStr != L'\0') && (Index < 8)) {\r
+\r
+    NodeVal = 0;\r
+    while ((*IdStr != L':') && (*IdStr != L'\0')) {\r
+\r
+      if ((*IdStr <= L'F') && (*IdStr >= L'A')) {\r
+        NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'A' + 10);\r
+      } else if ((*IdStr <= L'f') && (*IdStr >= L'a')) {\r
+        NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'a' + 10);\r
+      } else if ((*IdStr <= L'9') && (*IdStr >= L'0')) {\r
+        NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'0');\r
+      } else {\r
+        FreePool (*IfId);\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      IdStr++;\r
+    }\r
+\r
+    (*IfId)->Id[Index++] = NodeVal;\r
+\r
+    if (*IdStr == L':') {\r
+      IdStr++;\r
+    }\r
+  }\r
+\r
+  *Arg = (*Arg)->Next;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Parse dad in string format from Args with the "-s" option and convert it to UINT32 format.\r
+\r
+  @param[in, out]   Arg      The pointer of the address of ARG_LIST that saves Args with the "-s" option.\r
+  @param[out]       Xmits    The pointer of Xmits.\r
+\r
+  @retval EFI_SUCCESS    The get status processed successfully.\r
+  @retval others         The get status process failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6ParseDadXmits (\r
+  IN OUT ARG_LIST    **Arg,\r
+     OUT UINT32      *Xmits\r
+  )\r
+{\r
+  CHAR16    *ValStr;\r
+\r
+  if (*Arg == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValStr = (*Arg)->Arg;\r
+  *Xmits = 0;\r
+\r
+  while (*ValStr != L'\0') {\r
+\r
+    if ((*ValStr <= L'9') && (*ValStr >= L'0')) {\r
+\r
+      *Xmits = (*Xmits * 10) + (*ValStr - L'0');\r
+\r
+    } else {\r
+\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    ValStr++;\r
+  }\r
+\r
+  *Arg = (*Arg)->Next;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  The get current status of all handles.\r
+\r
+  @param[in]   ImageHandle    The handle of  ImageHandle.\r
+  @param[in]   IfName         The pointer of  IfName(interface name).\r
+  @param[in]   IfList         The pointer of  IfList(interface list).\r
+\r
+  @retval EFI_SUCCESS    The get status processed successfully.\r
+  @retval others         The get status process failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6GetInterfaceInfo (\r
+  IN EFI_HANDLE    ImageHandle,\r
+  IN CHAR16        *IfName,\r
+  IN LIST_ENTRY    *IfList\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  UINTN                            HandleIndex;\r
+  UINTN                            HandleNum;\r
+  EFI_HANDLE                       *HandleBuffer;\r
+  EFI_IP6_CONFIG_PROTOCOL          *Ip6Cfg;\r
+  EFI_IP6_CONFIG_INTERFACE_INFO    *IfInfo;\r
+  IFCONFIG6_INTERFACE_CB           *IfCb;\r
+  UINTN                            DataSize;\r
+\r
+  HandleBuffer = NULL;\r
+  HandleNum    = 0;\r
+\r
+  IfInfo       = NULL;\r
+  IfCb         = NULL;\r
+\r
+  //\r
+  // Locate all the handles with ip6 service binding protocol.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiIp6ServiceBindingProtocolGuid,\r
+                  NULL,\r
+                  &HandleNum,\r
+                  &HandleBuffer\r
+                 );\r
+  if (EFI_ERROR (Status) || (HandleNum == 0)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Enumerate all handles that installed with ip6 service binding protocol.\r
+  //\r
+  for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {\r
+    IfCb      = NULL;\r
+    IfInfo    = NULL;\r
+    DataSize  = 0;\r
+\r
+    //\r
+    // Ip6config protocol and ip6 service binding protocol are installed\r
+    // on the same handle.\r
+    //\r
+    ASSERT (HandleBuffer != NULL);\r
+    Status = gBS->HandleProtocol (\r
+                    HandleBuffer[HandleIndex],\r
+                    &gEfiIp6ConfigProtocolGuid,\r
+                    (VOID **) &Ip6Cfg\r
+                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+    //\r
+    // Get the interface information size.\r
+    //\r
+    Status = Ip6Cfg->GetData (\r
+                       Ip6Cfg,\r
+                       Ip6ConfigDataTypeInterfaceInfo,\r
+                       &DataSize,\r
+                       NULL\r
+                       );\r
+\r
+    if (Status != EFI_BUFFER_TOO_SMALL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    IfInfo = AllocateZeroPool (DataSize);\r
+\r
+    if (IfInfo == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ON_ERROR;\r
+    }\r
+    //\r
+    // Get the interface info.\r
+    //\r
+    Status = Ip6Cfg->GetData (\r
+                       Ip6Cfg,\r
+                       Ip6ConfigDataTypeInterfaceInfo,\r
+                       &DataSize,\r
+                       IfInfo\r
+                       );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+      goto ON_ERROR;\r
+    }\r
+    //\r
+    // Check the interface name if required.\r
+    //\r
+    if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) {\r
+      FreePool (IfInfo);\r
+      continue;\r
+    }\r
+\r
+    DataSize = 0;\r
+    //\r
+    // Get the size of dns server list.\r
+    //\r
+    Status = Ip6Cfg->GetData (\r
+                       Ip6Cfg,\r
+                       Ip6ConfigDataTypeDnsServer,\r
+                       &DataSize,\r
+                       NULL\r
+                       );\r
+\r
+    if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    IfCb = AllocateZeroPool (sizeof (IFCONFIG6_INTERFACE_CB) + DataSize);\r
+\r
+    if (IfCb == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    IfCb->NicHandle = HandleBuffer[HandleIndex];\r
+    IfCb->IfInfo    = IfInfo;\r
+    IfCb->IfCfg     = Ip6Cfg;\r
+    IfCb->DnsCnt    = (UINT32) (DataSize / sizeof (EFI_IPv6_ADDRESS));\r
+\r
+    //\r
+    // Get the dns server list if has.\r
+    //\r
+    if (DataSize > 0) {\r
+\r
+      Status = Ip6Cfg->GetData (\r
+                         Ip6Cfg,\r
+                         Ip6ConfigDataTypeDnsServer,\r
+                         &DataSize,\r
+                         IfCb->DnsAddr\r
+                         );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+        goto ON_ERROR;\r
+      }\r
+    }\r
+    //\r
+    // Get the interface id if has.\r
+    //\r
+    DataSize   = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);\r
+    IfCb->IfId = AllocateZeroPool (DataSize);\r
+\r
+    if (IfCb->IfId == NULL) {\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    Status = Ip6Cfg->GetData (\r
+                       Ip6Cfg,\r
+                       Ip6ConfigDataTypeAltInterfaceId,\r
+                       &DataSize,\r
+                       IfCb->IfId\r
+                       );\r
+\r
+    if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    if (Status == EFI_NOT_FOUND) {\r
+      FreePool (IfCb->IfId);\r
+      IfCb->IfId = NULL;\r
+    }\r
+    //\r
+    // Get the config policy.\r
+    //\r
+    DataSize = sizeof (EFI_IP6_CONFIG_POLICY);\r
+    Status   = Ip6Cfg->GetData (\r
+                         Ip6Cfg,\r
+                         Ip6ConfigDataTypePolicy,\r
+                         &DataSize,\r
+                         &IfCb->Policy\r
+                         );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+      goto ON_ERROR;\r
+    }\r
+    //\r
+    // Get the dad transmits.\r
+    //\r
+    DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);\r
+    Status   = Ip6Cfg->GetData (\r
+                         Ip6Cfg,\r
+                         Ip6ConfigDataTypeDupAddrDetectTransmits,\r
+                         &DataSize,\r
+                         &IfCb->Xmits\r
+                         );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    InsertTailList (IfList, &IfCb->Link);\r
+\r
+    if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) {\r
+      //\r
+      // Only need the appointed interface, keep the allocated buffer.\r
+      //\r
+      IfCb   = NULL;\r
+      IfInfo = NULL;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (HandleBuffer != NULL) {\r
+    FreePool (HandleBuffer);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+\r
+  if (IfInfo != NULL) {\r
+    FreePool (IfInfo);\r
+  }\r
+\r
+  if (IfCb != NULL) {\r
+    if (IfCb->IfId != NULL) {\r
+      FreePool (IfCb->IfId);\r
+    }\r
+\r
+    FreePool (IfCb);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  The list process of the IfConfig6 application.\r
+\r
+  @param[in]   IfList    The pointer of IfList(interface list).\r
+\r
+  @retval SHELL_SUCCESS  The IfConfig6 list processed successfully.\r
+  @retval others         The IfConfig6 list process failed.\r
+\r
+**/\r
+SHELL_STATUS\r
+IfConfig6ShowInterfaceInfo (\r
+  IN LIST_ENTRY    *IfList\r
+  )\r
+{\r
+  LIST_ENTRY                *Entry;\r
+  IFCONFIG6_INTERFACE_CB    *IfCb;\r
+  UINTN                     Index;\r
+\r
+  Entry  = IfList->ForwardLink;\r
+\r
+  if (IsListEmpty (IfList)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);\r
+  }\r
+\r
+  //\r
+  // Go through the interface list.\r
+  //\r
+  while (Entry != IfList) {\r
+\r
+    IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);\r
+\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), gShellNetwork2HiiHandle);\r
+\r
+    //\r
+    // Print interface name.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME), gShellNetwork2HiiHandle, IfCb->IfInfo->Name);\r
+\r
+    //\r
+    // Print interface config policy.\r
+    //\r
+    if (IfCb->Policy == Ip6ConfigPolicyAutomatic) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO), gShellNetwork2HiiHandle);\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN), gShellNetwork2HiiHandle);\r
+    }\r
+\r
+    //\r
+    // Print dad transmit.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS), gShellNetwork2HiiHandle, IfCb->Xmits);\r
+\r
+    //\r
+    // Print interface id if has.\r
+    //\r
+    if (IfCb->IfId != NULL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD), gShellNetwork2HiiHandle);\r
+\r
+      IfConfig6PrintMacAddr (\r
+        IfCb->IfId->Id,\r
+        8\r
+        );\r
+    }\r
+    //\r
+    // Print mac address of the interface.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD), gShellNetwork2HiiHandle);\r
+\r
+    IfConfig6PrintMacAddr (\r
+      IfCb->IfInfo->HwAddress.Addr,\r
+      IfCb->IfInfo->HwAddressSize\r
+      );\r
+\r
+    //\r
+    // Print ip addresses list of the interface.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_HEAD), gShellNetwork2HiiHandle);\r
+\r
+    for (Index = 0; Index < IfCb->IfInfo->AddressInfoCount; Index++) {\r
+      IfConfig6PrintIpAddr (\r
+        &IfCb->IfInfo->AddressInfo[Index].Address,\r
+        &IfCb->IfInfo->AddressInfo[Index].PrefixLength\r
+        );\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);\r
+    }\r
+\r
+    //\r
+    // Print dns server addresses list of the interface if has.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD), gShellNetwork2HiiHandle);\r
+\r
+    for (Index = 0; Index < IfCb->DnsCnt; Index++) {\r
+      IfConfig6PrintIpAddr (\r
+        &IfCb->DnsAddr[Index],\r
+        NULL\r
+        );\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);\r
+    }\r
+\r
+    //\r
+    // Print route table of the interface if has.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD), gShellNetwork2HiiHandle);\r
+\r
+    for (Index = 0; Index < IfCb->IfInfo->RouteCount; Index++) {\r
+      IfConfig6PrintIpAddr (\r
+        &IfCb->IfInfo->RouteTable[Index].Destination,\r
+        &IfCb->IfInfo->RouteTable[Index].PrefixLength\r
+        );\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_JOINT), gShellNetwork2HiiHandle);\r
+\r
+      IfConfig6PrintIpAddr (\r
+        &IfCb->IfInfo->RouteTable[Index].Gateway,\r
+        NULL\r
+        );\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);\r
+    }\r
+\r
+    Entry = Entry->ForwardLink;\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), gShellNetwork2HiiHandle);\r
+\r
+  return SHELL_SUCCESS;\r
+}\r
+\r
+/**\r
+  The clean process of the IfConfig6 application.\r
+\r
+  @param[in]   IfList    The pointer of IfList(interface list).\r
+\r
+  @retval SHELL_SUCCESS  The IfConfig6 clean processed successfully.\r
+  @retval others         The IfConfig6 clean process failed.\r
+\r
+**/\r
+SHELL_STATUS\r
+IfConfig6ClearInterfaceInfo (\r
+  IN LIST_ENTRY    *IfList\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  SHELL_STATUS              ShellStatus;\r
+  LIST_ENTRY                *Entry;\r
+  IFCONFIG6_INTERFACE_CB    *IfCb;\r
+  EFI_IP6_CONFIG_POLICY     Policy;\r
+\r
+  Policy = Ip6ConfigPolicyAutomatic;\r
+  Entry  = IfList->ForwardLink;\r
+  Status = EFI_SUCCESS;\r
+  ShellStatus = SHELL_SUCCESS;\r
+\r
+  if (IsListEmpty (IfList)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);\r
+  }\r
+\r
+  //\r
+  // Go through the interface list.\r
+  //\r
+  while (Entry != IfList) {\r
+\r
+    IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);\r
+\r
+    Status = IfCb->IfCfg->SetData (\r
+                            IfCb->IfCfg,\r
+                            Ip6ConfigDataTypePolicy,\r
+                            sizeof (EFI_IP6_CONFIG_POLICY),\r
+                            &Policy\r
+                            );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      ShellStatus = SHELL_ACCESS_DENIED;\r
+      break;\r
+    }\r
+\r
+    Entry  = Entry->ForwardLink;\r
+  }\r
+\r
+  return ShellStatus;\r
+}\r
+\r
+/**\r
+  The set process of the IfConfig6 application.\r
+\r
+  @param[in]   IfList    The pointer of IfList(interface list).\r
+  @param[in]   VarArg    The pointer of ARG_LIST(Args with "-s" option).\r
+\r
+  @retval SHELL_SUCCESS  The IfConfig6 set processed successfully.\r
+  @retval others         The IfConfig6 set process failed.\r
+\r
+**/\r
+SHELL_STATUS\r
+IfConfig6SetInterfaceInfo (\r
+  IN LIST_ENTRY    *IfList,\r
+  IN ARG_LIST      *VarArg\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  SHELL_STATUS                     ShellStatus;\r
+  IFCONFIG6_INTERFACE_CB           *IfCb;\r
+  EFI_IP6_CONFIG_MANUAL_ADDRESS    *CfgManAddr;\r
+  EFI_IPv6_ADDRESS                 *CfgAddr;\r
+  UINTN                            AddrSize;\r
+  EFI_IP6_CONFIG_INTERFACE_ID      *InterfaceId;\r
+  UINT32                           DadXmits;\r
+  UINT32                           CurDadXmits;\r
+  UINTN                            CurDadXmitsLen;\r
+  EFI_IP6_CONFIG_POLICY            Policy;\r
+\r
+  VAR_CHECK_CODE                   CheckCode;\r
+  EFI_EVENT                        TimeOutEvt;\r
+  EFI_EVENT                        MappedEvt;\r
+  BOOLEAN                          IsAddressOk;\r
+\r
+  UINTN                            DataSize;\r
+  UINT32                           Index;\r
+  UINT32                           Index2;\r
+  BOOLEAN                          IsAddressSet;\r
+  EFI_IP6_CONFIG_INTERFACE_INFO    *IfInfo;\r
+\r
+  CfgManAddr  = NULL;\r
+  CfgAddr     = NULL;\r
+  TimeOutEvt  = NULL;\r
+  MappedEvt   = NULL;\r
+  IfInfo      = NULL;\r
+  InterfaceId = NULL;\r
+  CurDadXmits = 0;\r
+\r
+  if (IsListEmpty (IfList)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);\r
+    return SHELL_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Make sure to set only one interface each time.\r
+  //\r
+  IfCb   = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link);\r
+  Status = EFI_SUCCESS;\r
+  ShellStatus = SHELL_SUCCESS;\r
+\r
+  //\r
+  // Initialize check list mechanism.\r
+  //\r
+  CheckCode = IfConfig6RetriveCheckListByName(\r
+                NULL,\r
+                NULL,\r
+                TRUE\r
+                );\r
+\r
+  //\r
+  // Create events & timers for asynchronous settings.\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_TIMER,\r
+                  TPL_CALLBACK,\r
+                  NULL,\r
+                  NULL,\r
+                  &TimeOutEvt\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  IfConfig6ManualAddressNotify,\r
+                  &IsAddressOk,\r
+                  &MappedEvt\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Parse the setting variables.\r
+  //\r
+  while (VarArg != NULL) {\r
+     //\r
+     // Check invalid parameters (duplication & unknown & conflict).\r
+     //\r
+    CheckCode = IfConfig6RetriveCheckListByName(\r
+                  mIfConfig6SetCheckList,\r
+                  VarArg->Arg,\r
+                  FALSE\r
+                  );\r
+\r
+    if (VarCheckOk != CheckCode) {\r
+      switch (CheckCode) {\r
+        case VarCheckDuplicate:\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);\r
+          break;\r
+\r
+        case VarCheckConflict:\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);\r
+          break;\r
+\r
+        case VarCheckUnknown:\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);\r
+          break;\r
+\r
+        default:\r
+          break;\r
+      }\r
+\r
+      VarArg = VarArg->Next;\r
+      continue;\r
+    }\r
+    //\r
+    // Process valid variables.\r
+    //\r
+    if (StrCmp(VarArg->Arg, L"auto") == 0) {\r
+      //\r
+      // Set automaic config policy\r
+      //\r
+      Policy = Ip6ConfigPolicyAutomatic;\r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypePolicy,\r
+                              sizeof (EFI_IP6_CONFIG_POLICY),\r
+                              &Policy\r
+                              );\r
+\r
+      if (EFI_ERROR(Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      VarArg= VarArg->Next;\r
+\r
+    } else if (StrCmp (VarArg->Arg, L"man") == 0) {\r
+      //\r
+      // Set manual config policy.\r
+      //\r
+      Policy = Ip6ConfigPolicyManual;\r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypePolicy,\r
+                              sizeof (EFI_IP6_CONFIG_POLICY),\r
+                              &Policy\r
+                              );\r
+\r
+      if (EFI_ERROR(Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      VarArg= VarArg->Next;\r
+\r
+    } else if (StrCmp (VarArg->Arg, L"host") == 0) {\r
+      //\r
+      // Parse till the next tag or the end of command line.\r
+      //\r
+      VarArg = VarArg->Next;\r
+      Status = IfConfig6ParseManualAddressList (\r
+                 &VarArg,\r
+                 &CfgManAddr,\r
+                 &AddrSize\r
+                 );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        if (Status == EFI_INVALID_PARAMETER) {\r
+          ShellStatus = SHELL_INVALID_PARAMETER;\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"host");\r
+          continue;\r
+        } else {\r
+          ShellStatus = SHELL_ACCESS_DENIED;\r
+          goto ON_EXIT;\r
+        }\r
+      }\r
+      //\r
+      // Set static host ip6 address list.\r
+      //   This is a asynchronous process.\r
+      //\r
+      IsAddressOk = FALSE;\r
+\r
+      Status = IfCb->IfCfg->RegisterDataNotify (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeManualAddress,\r
+                              MappedEvt\r
+                              );\r
+      if (EFI_ERROR (Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeManualAddress,\r
+                              AddrSize,\r
+                              CfgManAddr\r
+                              );\r
+\r
+      if (Status == EFI_NOT_READY) {\r
+        //\r
+        // Get current dad transmits count.\r
+        //\r
+        CurDadXmitsLen = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);\r
+        IfCb->IfCfg->GetData (\r
+                       IfCb->IfCfg,\r
+                       Ip6ConfigDataTypeDupAddrDetectTransmits,\r
+                       &CurDadXmitsLen,\r
+                       &CurDadXmits\r
+                       );\r
+\r
+        gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000 + 10000000 * CurDadXmits);\r
+\r
+        while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {\r
+          if (IsAddressOk) {\r
+            Status = EFI_SUCCESS;\r
+            break;\r
+          }\r
+        }\r
+      }\r
+\r
+      IfCb->IfCfg->UnregisterDataNotify (\r
+                     IfCb->IfCfg,\r
+                     Ip6ConfigDataTypeManualAddress,\r
+                     MappedEvt\r
+                     );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST), gShellNetwork2HiiHandle, Status);\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      //\r
+      // Check whether the address is set successfully.\r
+      //\r
+      DataSize = 0;\r
+\r
+      Status = IfCb->IfCfg->GetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeInterfaceInfo,\r
+                              &DataSize,\r
+                              NULL\r
+                              );\r
+\r
+      if (Status != EFI_BUFFER_TOO_SMALL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      IfInfo = AllocateZeroPool (DataSize);\r
+\r
+      if (IfInfo == NULL) {\r
+        ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      Status = IfCb->IfCfg->GetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeInterfaceInfo,\r
+                              &DataSize,\r
+                              IfInfo\r
+                              );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      for ( Index = 0; Index < (UINTN) (AddrSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); Index++) {\r
+        IsAddressSet = FALSE;\r
+        //\r
+        // By default, the prefix length 0 is regarded as 64.\r
+        //\r
+        if (CfgManAddr[Index].PrefixLength == 0) {\r
+          CfgManAddr[Index].PrefixLength = 64;\r
+        }\r
+\r
+        for (Index2 = 0; Index2 < IfInfo->AddressInfoCount; Index2++) {\r
+          if (EFI_IP6_EQUAL (&IfInfo->AddressInfo[Index2].Address, &CfgManAddr[Index].Address) &&\r
+              (IfInfo->AddressInfo[Index2].PrefixLength == CfgManAddr[Index].PrefixLength)) {\r
+            IsAddressSet = TRUE;\r
+            break;\r
+          }\r
+        }\r
+\r
+        if (!IsAddressSet) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED), gShellNetwork2HiiHandle);\r
+          IfConfig6PrintIpAddr (\r
+            &CfgManAddr[Index].Address,\r
+            &CfgManAddr[Index].PrefixLength\r
+            );\r
+        }\r
+      }\r
+\r
+    } else if (StrCmp (VarArg->Arg, L"gw") == 0) {\r
+      //\r
+      // Parse till the next tag or the end of command line.\r
+      //\r
+      VarArg = VarArg->Next;\r
+      Status = IfConfig6ParseGwDnsAddressList (\r
+                 &VarArg,\r
+                 &CfgAddr,\r
+                 &AddrSize\r
+                 );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        if (Status == EFI_INVALID_PARAMETER) {\r
+          ShellStatus = SHELL_INVALID_PARAMETER;\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"gw");\r
+          continue;\r
+        } else {\r
+          ShellStatus = SHELL_ACCESS_DENIED;\r
+          goto ON_EXIT;\r
+        }\r
+      }\r
+      //\r
+      // Set static gateway ip6 address list.\r
+      //\r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeGateway,\r
+                              AddrSize,\r
+                              CfgAddr\r
+                              );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+    } else if (StrCmp (VarArg->Arg, L"dns") == 0) {\r
+      //\r
+      // Parse till the next tag or the end of command line.\r
+      //\r
+      VarArg = VarArg->Next;\r
+      Status = IfConfig6ParseGwDnsAddressList (\r
+                 &VarArg,\r
+                 &CfgAddr,\r
+                 &AddrSize\r
+                 );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        if (Status == EFI_INVALID_PARAMETER) {\r
+          ShellStatus = SHELL_INVALID_PARAMETER;\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"dns");\r
+          continue;\r
+        } else {\r
+          ShellStatus = SHELL_ACCESS_DENIED;\r
+          goto ON_EXIT;\r
+        }\r
+      }\r
+      //\r
+      // Set static DNS server ip6 address list.\r
+      //\r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeDnsServer,\r
+                              AddrSize,\r
+                              CfgAddr\r
+                              );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+    } else if (StrCmp (VarArg->Arg, L"id") == 0) {\r
+      //\r
+      // Parse till the next tag or the end of command line.\r
+      //\r
+      VarArg = VarArg->Next;\r
+      Status = IfConfig6ParseInterfaceId (&VarArg, &InterfaceId);\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellStatus = SHELL_INVALID_PARAMETER;\r
+        goto ON_EXIT;\r
+      }\r
+      //\r
+      // Set alternative interface id.\r
+      //\r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeAltInterfaceId,\r
+                              sizeof (EFI_IP6_CONFIG_INTERFACE_ID),\r
+                              InterfaceId\r
+                              );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+\r
+    } else if (StrCmp (VarArg->Arg, L"dad") == 0) {\r
+      //\r
+      // Parse till the next tag or the end of command line.\r
+      //\r
+      VarArg = VarArg->Next;\r
+      Status = IfConfig6ParseDadXmits (&VarArg, &DadXmits);\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+      //\r
+      // Set dad transmits count.\r
+      //\r
+      Status = IfCb->IfCfg->SetData (\r
+                              IfCb->IfCfg,\r
+                              Ip6ConfigDataTypeDupAddrDetectTransmits,\r
+                              sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),\r
+                              &DadXmits\r
+                              );\r
+\r
+      if (EFI_ERROR(Status)) {\r
+        ShellStatus = SHELL_ACCESS_DENIED;\r
+        goto ON_EXIT;\r
+      }\r
+    }\r
+  }\r
+\r
+ON_EXIT:\r
+\r
+  if (CfgManAddr != NULL) {\r
+    FreePool (CfgManAddr);\r
+  }\r
+\r
+  if (CfgAddr != NULL) {\r
+    FreePool (CfgAddr);\r
+  }\r
+\r
+  if (MappedEvt != NULL) {\r
+    gBS->CloseEvent (MappedEvt);\r
+  }\r
+\r
+  if (TimeOutEvt != NULL) {\r
+    gBS->CloseEvent (TimeOutEvt);\r
+  }\r
+\r
+  if (IfInfo != NULL) {\r
+    FreePool (IfInfo);\r
+  }\r
+\r
+  return ShellStatus;\r
+\r
+}\r
+\r
+/**\r
+  The IfConfig6 main process.\r
+\r
+  @param[in]   Private    The pointer of IFCONFIG6_PRIVATE_DATA.\r
+\r
+  @retval SHELL_SUCCESS   IfConfig6 processed successfully.\r
+  @retval others          The IfConfig6 process failed.\r
+\r
+**/\r
+SHELL_STATUS\r
+IfConfig6 (\r
+  IN IFCONFIG6_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  SHELL_STATUS  ShellStatus;\r
+\r
+  ShellStatus = SHELL_SUCCESS;\r
+\r
+  //\r
+  // Get configure information of all interfaces.\r
+  //\r
+  Status = IfConfig6GetInterfaceInfo (\r
+             Private->ImageHandle,\r
+             Private->IfName,\r
+             &Private->IfList\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellStatus = SHELL_NOT_FOUND;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  switch (Private->OpCode) {\r
+  case IfConfig6OpList:\r
+    ShellStatus = IfConfig6ShowInterfaceInfo (&Private->IfList);\r
+    break;\r
+\r
+  case IfConfig6OpClear:\r
+    ShellStatus = IfConfig6ClearInterfaceInfo (&Private->IfList);\r
+    break;\r
+\r
+  case IfConfig6OpSet:\r
+    ShellStatus = IfConfig6SetInterfaceInfo (&Private->IfList, Private->VarArg);\r
+    break;\r
+\r
+  default:\r
+    ShellStatus = SHELL_UNSUPPORTED;\r
+  }\r
+\r
+ON_EXIT:\r
+\r
+  return ShellStatus;\r
+}\r
+\r
+/**\r
+  The IfConfig6 cleanup process, free the allocated memory.\r
+\r
+  @param[in]   Private    The pointer of  IFCONFIG6_PRIVATE_DATA.\r
+\r
+**/\r
+VOID\r
+IfConfig6Cleanup (\r
+  IN IFCONFIG6_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  LIST_ENTRY                *Entry;\r
+  LIST_ENTRY                *NextEntry;\r
+  IFCONFIG6_INTERFACE_CB    *IfCb;\r
+  ARG_LIST                  *ArgNode;\r
+  ARG_LIST                  *ArgHead;\r
+\r
+  ASSERT (Private != NULL);\r
+\r
+  //\r
+  // Clean the list which save the set config Args.\r
+  //\r
+  if (Private->VarArg != NULL) {\r
+    ArgHead = Private->VarArg;\r
+\r
+    while (ArgHead->Next != NULL) {\r
+      ArgNode = ArgHead->Next;\r
+      FreePool (ArgHead);\r
+      ArgHead = ArgNode;\r
+    }\r
+\r
+    FreePool (ArgHead);\r
+  }\r
+\r
+  if (Private->IfName != NULL)\r
+    FreePool (Private->IfName);\r
+\r
+\r
+  //\r
+  // Clean the IFCONFIG6_INTERFACE_CB list.\r
+  //\r
+  Entry     = Private->IfList.ForwardLink;\r
+  NextEntry = Entry->ForwardLink;\r
+\r
+  while (Entry != &Private->IfList) {\r
+\r
+    IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);\r
+\r
+    RemoveEntryList (&IfCb->Link);\r
+\r
+    if (IfCb->IfId != NULL) {\r
+\r
+      FreePool (IfCb->IfId);\r
+    }\r
+\r
+    if (IfCb->IfInfo != NULL) {\r
+\r
+      FreePool (IfCb->IfInfo);\r
+    }\r
+\r
+    FreePool (IfCb);\r
+\r
+    Entry     = NextEntry;\r
+    NextEntry = Entry->ForwardLink;\r
+  }\r
+\r
+  FreePool (Private);\r
+}\r
+\r
+/**\r
+  Function for 'ifconfig6' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+\r
+  @retval SHELL_SUCCESS   ifconfig6 command processed successfully.\r
+  @retval others          The ifconfig6 command process failed.\r
+\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunIfconfig6 (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  SHELL_STATUS              ShellStatus;\r
+  IFCONFIG6_PRIVATE_DATA    *Private;\r
+  LIST_ENTRY                *ParamPackage;\r
+  CONST CHAR16              *ValueStr;\r
+  ARG_LIST                  *ArgList;\r
+  CHAR16                    *ProblemParam;\r
+  CHAR16                    *Str;\r
+\r
+  Private = NULL;\r
+  Status = EFI_INVALID_PARAMETER;\r
+  ShellStatus = SHELL_SUCCESS;\r
+\r
+  Status = ShellCommandLineParseEx (mIfConfig6CheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND), gShellNetwork2HiiHandle, L"ifconfig6", ProblemParam);\r
+    ShellStatus = SHELL_INVALID_PARAMETER;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // To handle no option.\r
+  //\r
+  if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") &&\r
+      !ShellCommandLineGetFlag (ParamPackage, L"-?") && !ShellCommandLineGetFlag (ParamPackage, L"-l")) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_LACK_OPTION), gShellNetwork2HiiHandle);\r
+    ShellStatus = SHELL_INVALID_PARAMETER;\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // To handle conflict options.\r
+  //\r
+  if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) ||\r
+      ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||\r
+      ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||\r
+      ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||\r
+      ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||\r
+      ((ShellCommandLineGetFlag (ParamPackage, L"-l")) && (ShellCommandLineGetFlag (ParamPackage, L"-?")))) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_CONFLICT_OPTIONS), gShellNetwork2HiiHandle);\r
+    ShellStatus = SHELL_INVALID_PARAMETER;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));\r
+\r
+  if (Private == NULL) {\r
+    ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  InitializeListHead (&Private->IfList);\r
+\r
+  //\r
+  // To get interface name for the list option.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {\r
+    Private->OpCode = IfConfig6OpList;\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");\r
+    if (ValueStr != NULL) {\r
+      Str             = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
+      ASSERT (Str != NULL);\r
+      Private->IfName = Str;\r
+    }\r
+  }\r
+  //\r
+  // To get interface name for the clear option.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-r")) {\r
+    Private->OpCode = IfConfig6OpClear;\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r");\r
+    if (ValueStr != NULL) {\r
+      Str             = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
+      ASSERT (Str != NULL);\r
+      Private->IfName = Str;\r
+    }\r
+  }\r
+  //\r
+  // To get interface name and corresponding Args for the set option.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-s")) {\r
+\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");\r
+    if (ValueStr == NULL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_INTERFACE), gShellNetwork2HiiHandle);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto ON_EXIT;\r
+    }\r
+    //\r
+    // To split the configuration into multi-section.\r
+    //\r
+    ArgList         = IfConfig6SplitStrToList (ValueStr, L' ');\r
+    ASSERT (ArgList != NULL);\r
+\r
+    Private->OpCode = IfConfig6OpSet;\r
+    Private->IfName = ArgList->Arg;\r
+\r
+    Private->VarArg = ArgList->Next;\r
+\r
+    if (Private->IfName == NULL || Private->VarArg == NULL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_COMMAND), gShellNetwork2HiiHandle);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+  //\r
+  // Main process of ifconfig6.\r
+  //\r
+  ShellStatus = IfConfig6 (Private);\r
+\r
+ON_EXIT:\r
+\r
+  ShellCommandLineFreeVarList (ParamPackage);\r
+  if (Private != NULL) {\r
+    IfConfig6Cleanup (Private);\r
+  }\r
+  return ShellStatus;\r
+\r
+}\r
+\r
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
new file mode 100644 (file)
index 0000000..af7d08f
--- /dev/null
@@ -0,0 +1,1247 @@
+/** @file\r
+  The implementation for Ping6 application.\r
+\r
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UefiShellNetwork2CommandsLib.h"\r
+\r
+#define PING6_DEFAULT_TIMEOUT      5000\r
+#define PING6_MAX_SEND_NUMBER      10000\r
+#define PING6_MAX_BUFFER_SIZE      32768\r
+#define PING6_ONE_SECOND           10000000\r
+\r
+//\r
+// A similar amount of time that passes in femtoseconds\r
+// for each increment of TimerValue. It is for NT32 only.\r
+//\r
+#define NTTIMERPERIOD    358049\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct _ICMP6_ECHO_REQUEST_REPLY {\r
+  UINT8                       Type;\r
+  UINT8                       Code;\r
+  UINT16                      Checksum;\r
+  UINT16                      Identifier;\r
+  UINT16                      SequenceNum;\r
+  UINT64                      TimeStamp;\r
+  UINT8                       Data[1];\r
+} ICMP6_ECHO_REQUEST_REPLY;\r
+\r
+#pragma pack()\r
+\r
+typedef struct _PING6_ICMP6_TX_INFO {\r
+  LIST_ENTRY                  Link;\r
+  UINT16                      SequenceNum;\r
+  UINT64                      TimeStamp;\r
+  EFI_IP6_COMPLETION_TOKEN    *Token;\r
+} PING6_ICMP6_TX_INFO;\r
+\r
+typedef struct _PING6_PRIVATE_DATA {\r
+  EFI_HANDLE                  ImageHandle;\r
+  EFI_HANDLE                  NicHandle;\r
+  EFI_HANDLE                  Ip6ChildHandle;\r
+  EFI_IP6_PROTOCOL            *Ip6;\r
+  EFI_EVENT                   Timer;\r
+\r
+  EFI_STATUS                  Status;\r
+  LIST_ENTRY                  TxList;\r
+  EFI_IP6_COMPLETION_TOKEN    RxToken;\r
+  UINT16                      RxCount;\r
+  UINT16                      TxCount;\r
+  UINT64                      RttSum;\r
+  UINT64                      RttMin;\r
+  UINT64                      RttMax;\r
+  UINT32                      SequenceNum;\r
+\r
+  EFI_IPv6_ADDRESS            SrcAddress;\r
+  EFI_IPv6_ADDRESS            DstAddress;\r
+  UINT32                      SendNum;\r
+  UINT32                      BufferSize;\r
+} PING6_PRIVATE_DATA;\r
+\r
+\r
+SHELL_PARAM_ITEM    Ping6ParamList[] = {\r
+  {\r
+    L"-l",\r
+    TypeValue\r
+  },\r
+  {\r
+    L"-n",\r
+    TypeValue\r
+  },\r
+  {\r
+    L"-s",\r
+    TypeValue\r
+  },\r
+  {\r
+    L"-?",\r
+    TypeFlag\r
+  },\r
+  {\r
+    NULL,\r
+    TypeMax\r
+  },\r
+};\r
+\r
+//\r
+// Global Variables in Ping6 application.\r
+//\r
+CONST CHAR16            *mIp6DstString;\r
+CONST CHAR16            *mIp6SrcString;\r
+UINT64                  mFrequency = 0;\r
+UINT64                  mIp6CurrentTick = 0;\r
+EFI_CPU_ARCH_PROTOCOL   *Cpu = NULL;\r
+\r
+\r
+\r
+/**\r
+  Reads and returns the current value of the Time.\r
+\r
+  @return The current tick value.\r
+\r
+**/\r
+UINT64\r
+Ping6ReadTime ()\r
+{\r
+  UINT64                 TimerPeriod;\r
+  EFI_STATUS             Status;\r
+\r
+  ASSERT (Cpu != NULL);\r
+\r
+  Status = Cpu->GetTimerValue (Cpu, 0, &mIp6CurrentTick, &TimerPeriod);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // The WinntGetTimerValue will return EFI_UNSUPPORTED. Set the\r
+    // TimerPeriod by ourselves.\r
+    //\r
+    mIp6CurrentTick += 1000000;\r
+  }\r
+\r
+  return mIp6CurrentTick;\r
+}\r
+\r
+/**\r
+  Get and calculate the frequency in tick/ms.\r
+  The result is saved in the globle variable mFrequency\r
+\r
+  @retval EFI_SUCCESS    Calculated the frequency successfully.\r
+  @retval Others         Failed to calculate the frequency.\r
+\r
+**/\r
+EFI_STATUS\r
+Ping6GetFrequency (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS               Status;\r
+  UINT64                   CurrentTick;\r
+  UINT64                   TimerPeriod;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &Cpu);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTick, &TimerPeriod);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // For NT32 Simulator only. 358049 is a similar value to keep timer granularity.\r
+    // Set the timer period by ourselves.\r
+    //\r
+    TimerPeriod = (UINT64) NTTIMERPERIOD;\r
+  }\r
+  //\r
+  // The timer period is in femtosecond (1 femtosecond is 1e-15 second).\r
+  // So 1e+12 is divided by timer period to produce the freq in tick/ms.\r
+  //\r
+  mFrequency = DivU64x64Remainder (1000000000000ULL, TimerPeriod, NULL);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Get and calculate the duration in ms.\r
+\r
+  @param[in]  Begin    The start point of time.\r
+  @param[in]  End      The end point of time.\r
+\r
+  @return The duration in ms.\r
+\r
+**/\r
+UINT64\r
+Ping6CalculateTick (\r
+  IN UINT64    Begin,\r
+  IN UINT64    End\r
+  )\r
+{\r
+  ASSERT (End > Begin);\r
+  return DivU64x64Remainder (End - Begin, mFrequency, NULL);\r
+}\r
+\r
+/**\r
+  Destroy IPING6_ICMP6_TX_INFO, and recollect the memory.\r
+\r
+  @param[in]    TxInfo    The pointer to PING6_ICMP6_TX_INFO.\r
+\r
+**/\r
+VOID\r
+Ping6DestroyTxInfo (\r
+  IN PING6_ICMP6_TX_INFO    *TxInfo\r
+  )\r
+{\r
+  EFI_IP6_TRANSMIT_DATA    *TxData;\r
+  EFI_IP6_FRAGMENT_DATA    *FragData;\r
+  UINTN                    Index;\r
+\r
+  ASSERT (TxInfo != NULL);\r
+\r
+  if (TxInfo->Token != NULL) {\r
+\r
+    if (TxInfo->Token->Event != NULL) {\r
+      gBS->CloseEvent (TxInfo->Token->Event);\r
+    }\r
+\r
+    TxData = TxInfo->Token->Packet.TxData;\r
+    if (TxData != NULL) {\r
+\r
+      if (TxData->OverrideData != NULL) {\r
+        FreePool (TxData->OverrideData);\r
+      }\r
+\r
+      if (TxData->ExtHdrs != NULL) {\r
+        FreePool (TxData->ExtHdrs);\r
+      }\r
+\r
+      for (Index = 0; Index < TxData->FragmentCount; Index++) {\r
+        FragData = TxData->FragmentTable[Index].FragmentBuffer;\r
+        if (FragData != NULL) {\r
+          FreePool (FragData);\r
+        }\r
+      }\r
+    }\r
+\r
+    FreePool (TxInfo->Token);\r
+  }\r
+\r
+  FreePool (TxInfo);\r
+}\r
+\r
+/**\r
+  Match the request, and reply with SequenceNum/TimeStamp.\r
+\r
+  @param[in]    Private    The pointer to PING6_PRIVATE_DATA.\r
+  @param[in]    Packet     The pointer to ICMP6_ECHO_REQUEST_REPLY.\r
+\r
+  @retval EFI_SUCCESS      The match is successful.\r
+  @retval EFI_NOT_FOUND    The reply can't be matched with any request.\r
+\r
+**/\r
+EFI_STATUS\r
+Ping6OnMatchEchoReply (\r
+  IN PING6_PRIVATE_DATA          *Private,\r
+  IN ICMP6_ECHO_REQUEST_REPLY    *Packet\r
+  )\r
+{\r
+  PING6_ICMP6_TX_INFO    *TxInfo;\r
+  LIST_ENTRY             *Entry;\r
+  LIST_ENTRY             *NextEntry;\r
+\r
+  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {\r
+    TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);\r
+\r
+    if ((TxInfo->SequenceNum == Packet->SequenceNum) && (TxInfo->TimeStamp == Packet->TimeStamp)) {\r
+      Private->RxCount++;\r
+      RemoveEntryList (&TxInfo->Link);\r
+      Ping6DestroyTxInfo (TxInfo);\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  The original intention is to send a request.\r
+  Currently, the application retransmits an icmp6 echo request packet\r
+  per second in sendnumber times that is specified by the user.\r
+  Because nothing can be done here, all things move to the timer rountine.\r
+\r
+  @param[in]    Event      A EFI_EVENT type event.\r
+  @param[in]    Context    The pointer to Context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ping6OnEchoRequestSent6 (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID         *Context\r
+  )\r
+{\r
+}\r
+\r
+/**\r
+  receive reply, match and print reply infomation.\r
+\r
+  @param[in]    Event      A EFI_EVENT type event.\r
+  @param[in]    Context    The pointer to context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ping6OnEchoReplyReceived6 (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID         *Context\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  PING6_PRIVATE_DATA          *Private;\r
+  EFI_IP6_COMPLETION_TOKEN    *RxToken;\r
+  EFI_IP6_RECEIVE_DATA        *RxData;\r
+  ICMP6_ECHO_REQUEST_REPLY    *Reply;\r
+  UINT32                      PayLoad;\r
+  UINT64                      Rtt;\r
+  CHAR8                       Near;\r
+\r
+  Private = (PING6_PRIVATE_DATA *) Context;\r
+\r
+  if (Private->Status == EFI_ABORTED) {\r
+    return;\r
+  }\r
+\r
+  RxToken = &Private->RxToken;\r
+  RxData  = RxToken->Packet.RxData;\r
+  Reply   = RxData->FragmentTable[0].FragmentBuffer;\r
+  PayLoad = RxData->DataLength;\r
+\r
+  if (RxData->Header->NextHeader != IP6_ICMP) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (!IP6_IS_MULTICAST (&Private->DstAddress) &&\r
+      !EFI_IP6_EQUAL (&RxData->Header->SourceAddress, &Private->DstAddress)) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if ((Reply->Type != ICMP_V6_ECHO_REPLY) || (Reply->Code != 0)) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  if (PayLoad != Private->BufferSize) {\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Check whether the reply matches the sent request before.\r
+  //\r
+  Status = Ping6OnMatchEchoReply (Private, Reply);\r
+  if (EFI_ERROR(Status)) {\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Display statistics on this icmp6 echo reply packet.\r
+  //\r
+  Rtt  = Ping6CalculateTick (Reply->TimeStamp, Ping6ReadTime ());\r
+  if (Rtt != 0) {\r
+    Near = (CHAR8) '=';\r
+  } else {\r
+    Near = (CHAR8) '<';\r
+  }\r
+\r
+  Private->RttSum += Rtt;\r
+  Private->RttMin  = Private->RttMin > Rtt ? Rtt : Private->RttMin;\r
+  Private->RttMax  = Private->RttMax < Rtt ? Rtt : Private->RttMax;\r
+\r
+  ShellPrintHiiEx (\r
+    -1,\r
+    -1,\r
+    NULL,\r
+    STRING_TOKEN (STR_PING6_REPLY_INFO),\r
+    gShellNetwork2HiiHandle,\r
+    PayLoad,\r
+    mIp6DstString,\r
+    Reply->SequenceNum,\r
+    RxData->Header->HopLimit,\r
+    Near,\r
+    Rtt\r
+    );\r
+\r
+ON_EXIT:\r
+\r
+  if (Private->RxCount < Private->SendNum) {\r
+    //\r
+    // Continue to receive icmp6 echo reply packets.\r
+    //\r
+    RxToken->Status = EFI_ABORTED;\r
+\r
+    Status = Private->Ip6->Receive (Private->Ip6, RxToken);\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      Private->Status = EFI_ABORTED;\r
+    }\r
+  } else {\r
+    //\r
+    // All reply have already been received from the dest host.\r
+    //\r
+    Private->Status = EFI_SUCCESS;\r
+  }\r
+  //\r
+  // Singal to recycle the each rxdata here, not at the end of process.\r
+  //\r
+  gBS->SignalEvent (RxData->RecycleSignal);\r
+}\r
+\r
+/**\r
+  Initial EFI_IP6_COMPLETION_TOKEN.\r
+\r
+  @param[in]    Private        The pointer of PING6_PRIVATE_DATA.\r
+  @param[in]    TimeStamp      The TimeStamp of request.\r
+  @param[in]    SequenceNum    The SequenceNum of request.\r
+\r
+  @return The pointer of EFI_IP6_COMPLETION_TOKEN.\r
+\r
+**/\r
+EFI_IP6_COMPLETION_TOKEN *\r
+Ping6GenerateToken (\r
+  IN PING6_PRIVATE_DATA    *Private,\r
+  IN UINT64                TimeStamp,\r
+  IN UINT16                SequenceNum\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_IP6_COMPLETION_TOKEN    *Token;\r
+  EFI_IP6_TRANSMIT_DATA       *TxData;\r
+  ICMP6_ECHO_REQUEST_REPLY    *Request;\r
+\r
+  Request = AllocateZeroPool (Private->BufferSize);\r
+\r
+  if (Request == NULL) {\r
+    return NULL;\r
+  }\r
+  //\r
+  // Assembly icmp6 echo request packet.\r
+  //\r
+  Request->Type        = ICMP_V6_ECHO_REQUEST;\r
+  Request->Code        = 0;\r
+  Request->SequenceNum = SequenceNum;\r
+  Request->TimeStamp   = TimeStamp;\r
+  Request->Identifier  = 0;\r
+  //\r
+  // Leave check sum to ip6 layer, since it has no idea of source address\r
+  // selection.\r
+  //\r
+  Request->Checksum    = 0;\r
+\r
+  TxData = AllocateZeroPool (sizeof (EFI_IP6_TRANSMIT_DATA));\r
+\r
+  if (TxData == NULL) {\r
+    FreePool (Request);\r
+    return NULL;\r
+  }\r
+  //\r
+  // Assembly ipv6 token for transmit.\r
+  //\r
+  TxData->OverrideData       = 0;\r
+  TxData->ExtHdrsLength      = 0;\r
+  TxData->ExtHdrs            = NULL;\r
+  TxData->DataLength         = Private->BufferSize;\r
+  TxData->FragmentCount      = 1;\r
+  TxData->FragmentTable[0].FragmentBuffer = (VOID *) Request;\r
+  TxData->FragmentTable[0].FragmentLength = Private->BufferSize;\r
+\r
+  Token = AllocateZeroPool (sizeof (EFI_IP6_COMPLETION_TOKEN));\r
+\r
+  if (Token == NULL) {\r
+    FreePool (Request);\r
+    FreePool (TxData);\r
+    return NULL;\r
+  }\r
+\r
+  Token->Status         = EFI_ABORTED;\r
+  Token->Packet.TxData  = TxData;\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  Ping6OnEchoRequestSent6,\r
+                  Private,\r
+                  &Token->Event\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (Request);\r
+    FreePool (TxData);\r
+    FreePool (Token);\r
+    return NULL;\r
+  }\r
+\r
+  return Token;\r
+}\r
+\r
+/**\r
+  Transmit the EFI_IP6_COMPLETION_TOKEN.\r
+\r
+  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.\r
+\r
+  @retval EFI_SUCCESS             Transmitted successfully.\r
+  @retval EFI_OUT_OF_RESOURCES    No memory is available on the platform.\r
+  @retval others                  Transmitted unsuccessfully.\r
+\r
+**/\r
+EFI_STATUS\r
+Ping6SendEchoRequest (\r
+  IN PING6_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  EFI_STATUS             Status;\r
+  PING6_ICMP6_TX_INFO    *TxInfo;\r
+\r
+  TxInfo = AllocateZeroPool (sizeof (PING6_ICMP6_TX_INFO));\r
+\r
+  if (TxInfo == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  TxInfo->TimeStamp   = Ping6ReadTime ();\r
+  TxInfo->SequenceNum = (UINT16) (Private->TxCount + 1);\r
+\r
+  TxInfo->Token       = Ping6GenerateToken (\r
+                          Private,\r
+                          TxInfo->TimeStamp,\r
+                          TxInfo->SequenceNum\r
+                          );\r
+\r
+  if (TxInfo->Token == NULL) {\r
+    Ping6DestroyTxInfo (TxInfo);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Status = Private->Ip6->Transmit (Private->Ip6, TxInfo->Token);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    Ping6DestroyTxInfo (TxInfo);\r
+    return Status;\r
+  }\r
+\r
+  InsertTailList (&Private->TxList, &TxInfo->Link);\r
+  Private->TxCount++;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Place a completion token into the receive packet queue to receive the echo reply.\r
+\r
+  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.\r
+\r
+  @retval EFI_SUCCESS      Put the token into the receive packet queue successfully.\r
+  @retval others           Put the token into the receive packet queue unsuccessfully.\r
+\r
+**/\r
+EFI_STATUS\r
+Ping6OnReceiveEchoReply (\r
+  IN PING6_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  ZeroMem (&Private->RxToken, sizeof (EFI_IP6_COMPLETION_TOKEN));\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  Ping6OnEchoReplyReceived6,\r
+                  Private,\r
+                  &Private->RxToken.Event\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Private->RxToken.Status = EFI_NOT_READY;\r
+\r
+  return Private->Ip6->Receive (Private->Ip6, &Private->RxToken);\r
+}\r
+\r
+/**\r
+  Remove the timeout request from the list.\r
+\r
+  @param[in]    Event    A EFI_EVENT type event.\r
+  @param[in]    Context  The pointer to Context.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+Ping6OnTimerRoutine6 (\r
+  IN EFI_EVENT    Event,\r
+  IN VOID         *Context\r
+  )\r
+{\r
+  EFI_STATUS             Status;\r
+  PING6_PRIVATE_DATA     *Private;\r
+  PING6_ICMP6_TX_INFO    *TxInfo;\r
+  LIST_ENTRY             *Entry;\r
+  LIST_ENTRY             *NextEntry;\r
+  UINT64                 Time;\r
+\r
+  Private = (PING6_PRIVATE_DATA *) Context;\r
+\r
+  //\r
+  // Retransmit icmp6 echo request packets per second in sendnumber times.\r
+  //\r
+  if (Private->TxCount < Private->SendNum) {\r
+\r
+    Status = Ping6SendEchoRequest (Private);\r
+    if (Private->TxCount != 0){\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_SEND_REQUEST), gShellNetwork2HiiHandle, Private->TxCount + 1);\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Check whether any icmp6 echo request in the list timeout.\r
+  //\r
+  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {\r
+    TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);\r
+    Time   = Ping6CalculateTick (TxInfo->TimeStamp, Ping6ReadTime ());\r
+\r
+    //\r
+    // Remove the timeout echo request from txlist.\r
+    //\r
+    if (Time > PING6_DEFAULT_TIMEOUT) {\r
+\r
+      if (EFI_ERROR (TxInfo->Token->Status)) {\r
+        Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);\r
+      }\r
+      //\r
+      // Remove the timeout icmp6 echo request from list.\r
+      //\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_TIMEOUT), gShellNetwork2HiiHandle, TxInfo->SequenceNum);\r
+\r
+      RemoveEntryList (&TxInfo->Link);\r
+      Ping6DestroyTxInfo (TxInfo);\r
+\r
+      if (IsListEmpty (&Private->TxList) && (Private->TxCount == Private->SendNum)) {\r
+        //\r
+        // All the left icmp6 echo request in the list timeout.\r
+        //\r
+        Private->Status = EFI_TIMEOUT;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Create a valid IP6 instance.\r
+\r
+  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.\r
+\r
+  @retval EFI_SUCCESS              Create a valid IP6 instance successfully.\r
+  @retval EFI_ABORTED              Locate handle with ip6 service binding protocol unsuccessfully.\r
+  @retval EFI_INVALID_PARAMETER    The source address is unspecified when the destination address is a link -ocal address.\r
+  @retval EFI_OUT_OF_RESOURCES     No memory is available on the platform.\r
+  @retval EFI_NOT_FOUND            The source address is not found.\r
+**/\r
+EFI_STATUS\r
+Ping6CreateIpInstance (\r
+  IN  PING6_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  UINTN                            HandleIndex;\r
+  UINTN                            HandleNum;\r
+  EFI_HANDLE                       *HandleBuffer;\r
+  EFI_SERVICE_BINDING_PROTOCOL     *Ip6Sb;\r
+  EFI_IP6_CONFIG_PROTOCOL          *Ip6Cfg;\r
+  EFI_IP6_CONFIG_DATA              Ip6Config;\r
+  EFI_IP6_CONFIG_INTERFACE_INFO    *IfInfo;\r
+  UINTN                            IfInfoSize;\r
+  EFI_IPv6_ADDRESS                 *Addr;\r
+  UINTN                            AddrIndex;\r
+\r
+  HandleBuffer = NULL;\r
+  Ip6Sb        = NULL;\r
+  IfInfo       = NULL;\r
+  IfInfoSize   = 0;\r
+\r
+  //\r
+  // Locate all the handles with ip6 service binding protocol.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiIp6ServiceBindingProtocolGuid,\r
+                  NULL,\r
+                  &HandleNum,\r
+                  &HandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status) || (HandleNum == 0)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  //\r
+  // Source address is required when pinging a link-local address on multi-\r
+  // interfaces host.\r
+  //\r
+  if (NetIp6IsLinkLocalAddr (&Private->DstAddress) &&\r
+      NetIp6IsUnspecifiedAddr (&Private->SrcAddress) &&\r
+      (HandleNum > 1)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SOURCE), gShellNetwork2HiiHandle);\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto ON_ERROR;\r
+  }\r
+  //\r
+  // For each ip6 protocol, check interface addresses list.\r
+  //\r
+  for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {\r
+\r
+    Ip6Sb      = NULL;\r
+    IfInfo     = NULL;\r
+    IfInfoSize = 0;\r
+\r
+    Status = gBS->HandleProtocol (\r
+                    HandleBuffer[HandleIndex],\r
+                    &gEfiIp6ServiceBindingProtocolGuid,\r
+                    (VOID **) &Ip6Sb\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    if (NetIp6IsUnspecifiedAddr (&Private->SrcAddress)) {\r
+      //\r
+      // No need to match interface address.\r
+      //\r
+      break;\r
+    } else {\r
+      //\r
+      // Ip6config protocol and ip6 service binding protocol are installed\r
+      // on the same handle.\r
+      //\r
+      Status = gBS->HandleProtocol (\r
+                      HandleBuffer[HandleIndex],\r
+                      &gEfiIp6ConfigProtocolGuid,\r
+                      (VOID **) &Ip6Cfg\r
+                      );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        goto ON_ERROR;\r
+      }\r
+      //\r
+      // Get the interface information size.\r
+      //\r
+      Status = Ip6Cfg->GetData (\r
+                         Ip6Cfg,\r
+                         Ip6ConfigDataTypeInterfaceInfo,\r
+                         &IfInfoSize,\r
+                         NULL\r
+                         );\r
+\r
+      if (Status != EFI_BUFFER_TOO_SMALL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+        goto ON_ERROR;\r
+      }\r
+\r
+      IfInfo = AllocateZeroPool (IfInfoSize);\r
+\r
+      if (IfInfo == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto ON_ERROR;\r
+      }\r
+      //\r
+      // Get the interface info.\r
+      //\r
+      Status = Ip6Cfg->GetData (\r
+                         Ip6Cfg,\r
+                         Ip6ConfigDataTypeInterfaceInfo,\r
+                         &IfInfoSize,\r
+                         IfInfo\r
+                         );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);\r
+        goto ON_ERROR;\r
+      }\r
+      //\r
+      // Check whether the source address is one of the interface addresses.\r
+      //\r
+      for (AddrIndex = 0; AddrIndex < IfInfo->AddressInfoCount; AddrIndex++) {\r
+\r
+        Addr = &(IfInfo->AddressInfo[AddrIndex].Address);\r
+        if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) {\r
+          //\r
+          // Match a certain interface address.\r
+          //\r
+          break;\r
+        }\r
+      }\r
+\r
+      if (AddrIndex < IfInfo->AddressInfoCount) {\r
+        //\r
+        // Found a nic handle with right interface address.\r
+        //\r
+        break;\r
+      }\r
+    }\r
+\r
+    FreePool (IfInfo);\r
+    IfInfo = NULL;\r
+  }\r
+  //\r
+  // No exact interface address matched.\r
+  //\r
+\r
+  if (HandleIndex == HandleNum) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_SOURCE_NOT_FOUND), gShellNetwork2HiiHandle, mIp6SrcString);\r
+    Status = EFI_NOT_FOUND;\r
+    goto ON_ERROR;\r
+  }\r
+\r
+  Private->NicHandle = HandleBuffer[HandleIndex];\r
+\r
+  ASSERT (Ip6Sb != NULL);\r
+  Status = Ip6Sb->CreateChild (Ip6Sb, &Private->Ip6ChildHandle);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_ERROR;\r
+  }\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Private->Ip6ChildHandle,\r
+                  &gEfiIp6ProtocolGuid,\r
+                  (VOID **) &Private->Ip6,\r
+                  Private->ImageHandle,\r
+                  Private->Ip6ChildHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_ERROR;\r
+  }\r
+\r
+  ZeroMem (&Ip6Config, sizeof (EFI_IP6_CONFIG_DATA));\r
+\r
+  //\r
+  // Configure the ip6 instance for icmp6 packet exchange.\r
+  //\r
+  Ip6Config.DefaultProtocol   = 58;\r
+  Ip6Config.AcceptAnyProtocol = FALSE;\r
+  Ip6Config.AcceptIcmpErrors  = TRUE;\r
+  Ip6Config.AcceptPromiscuous = FALSE;\r
+  Ip6Config.TrafficClass      = 0;\r
+  Ip6Config.HopLimit          = 128;\r
+  Ip6Config.FlowLabel         = 0;\r
+  Ip6Config.ReceiveTimeout    = 0;\r
+  Ip6Config.TransmitTimeout   = 0;\r
+\r
+  IP6_COPY_ADDRESS (&Ip6Config.StationAddress, &Private->SrcAddress);\r
+\r
+  IP6_COPY_ADDRESS (&Ip6Config.DestinationAddress, &Private->DstAddress);\r
+\r
+  Status = Private->Ip6->Configure (Private->Ip6, &Ip6Config);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_CONFIG), gShellNetwork2HiiHandle, Status);\r
+    goto ON_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+  if (HandleBuffer != NULL) {\r
+    FreePool (HandleBuffer);\r
+  }\r
+\r
+  if (IfInfo != NULL) {\r
+    FreePool (IfInfo);\r
+  }\r
+\r
+  if ((Ip6Sb != NULL) && (Private->Ip6ChildHandle != NULL)) {\r
+    Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Destroy the IP6 instance.\r
+\r
+  @param[in]    Private    The pointer of PING6_PRIVATE_DATA.\r
+\r
+**/\r
+VOID\r
+Ping6DestroyIpInstance (\r
+  IN PING6_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_SERVICE_BINDING_PROTOCOL    *Ip6Sb;\r
+\r
+  gBS->CloseProtocol (\r
+         Private->Ip6ChildHandle,\r
+         &gEfiIp6ProtocolGuid,\r
+         Private->ImageHandle,\r
+         Private->Ip6ChildHandle\r
+         );\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  Private->NicHandle,\r
+                  &gEfiIp6ServiceBindingProtocolGuid,\r
+                  (VOID **) &Ip6Sb\r
+                  );\r
+\r
+  if (!EFI_ERROR(Status)) {\r
+    Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);\r
+  }\r
+}\r
+\r
+/**\r
+  The Ping6 Process.\r
+\r
+  @param[in]   ImageHandle    The firmware allocated handle for the UEFI image.\r
+  @param[in]   SendNumber     The send request count.\r
+  @param[in]   BufferSize     The send buffer size.\r
+  @param[in]   SrcAddress     The source IPv6 address.\r
+  @param[in]   DstAddress     The destination IPv6 address.\r
+\r
+  @retval SHELL_SUCCESS    The ping6 processed successfullly.\r
+  @retval others           The ping6 processed unsuccessfully.\r
+\r
+**/\r
+SHELL_STATUS\r
+ShellPing6 (\r
+  IN EFI_HANDLE          ImageHandle,\r
+  IN UINT32              SendNumber,\r
+  IN UINT32              BufferSize,\r
+  IN EFI_IPv6_ADDRESS    *SrcAddress,\r
+  IN EFI_IPv6_ADDRESS    *DstAddress\r
+  )\r
+{\r
+  EFI_STATUS             Status;\r
+  EFI_INPUT_KEY          Key;\r
+  PING6_PRIVATE_DATA     *Private;\r
+  PING6_ICMP6_TX_INFO    *TxInfo;\r
+  LIST_ENTRY             *Entry;\r
+  LIST_ENTRY             *NextEntry;\r
+  SHELL_STATUS           ShellStatus;\r
+\r
+  ShellStatus = SHELL_SUCCESS;\r
+  Private = AllocateZeroPool (sizeof (PING6_PRIVATE_DATA));\r
+\r
+  ASSERT (Private != NULL);\r
+\r
+  Private->ImageHandle = ImageHandle;\r
+  Private->SendNum     = SendNumber;\r
+  Private->BufferSize  = BufferSize;\r
+  Private->RttMin      = ~((UINT64 )(0x0));\r
+  Private->Status      = EFI_NOT_READY;\r
+\r
+  InitializeListHead (&Private->TxList);\r
+\r
+  IP6_COPY_ADDRESS (&Private->SrcAddress, SrcAddress);\r
+  IP6_COPY_ADDRESS (&Private->DstAddress, DstAddress);\r
+\r
+  //\r
+  // Open and configure a ip6 instance for ping6.\r
+  //\r
+  Status = Ping6CreateIpInstance (Private);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Print the command line itself.\r
+  //\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_START), gShellNetwork2HiiHandle, mIp6DstString, Private->BufferSize);\r
+  //\r
+  // Create a ipv6 token to receive the first icmp6 echo reply packet.\r
+  //\r
+  Status = Ping6OnReceiveEchoReply (Private);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Create and start timer to send icmp6 echo request packet per second.\r
+  //\r
+  Status = gBS->CreateEvent (\r
+                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
+                  TPL_CALLBACK,\r
+                  Ping6OnTimerRoutine6,\r
+                  Private,\r
+                  &Private->Timer\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Create a ipv6 token to send the first icmp6 echo request packet.\r
+  //\r
+  Status = Ping6SendEchoRequest (Private);\r
+  //\r
+  // EFI_NOT_READY for IPsec is enable and IKE is not established.\r
+  //\r
+  if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    if(Status == EFI_NOT_FOUND) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_NOSOURCE_INDOMAIN), gShellNetwork2HiiHandle, mIp6DstString);\r
+    }\r
+\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  Status = gBS->SetTimer (\r
+                  Private->Timer,\r
+                  TimerPeriodic,\r
+                  PING6_ONE_SECOND\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Control the ping6 process by two factors:\r
+  // 1. Hot key\r
+  // 2. Private->Status\r
+  //   2.1. success means all icmp6 echo request packets get reply packets.\r
+  //   2.2. timeout means the last icmp6 echo reply request timeout to get reply.\r
+  //   2.3. noready means ping6 process is on-the-go.\r
+  //\r
+  while (Private->Status == EFI_NOT_READY) {\r
+    Private->Ip6->Poll (Private->Ip6);\r
+\r
+    //\r
+    // Terminate the ping6 process by 'esc' or 'ctl-c'.\r
+    //\r
+    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+\r
+    if (!EFI_ERROR(Status)) {\r
+      if ((Key.UnicodeChar == 0x1b) || (Key.UnicodeChar == 0x03) ||\r
+         ((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_ESC))) {\r
+        goto ON_STAT;\r
+      }\r
+    }\r
+  }\r
+\r
+ON_STAT:\r
+  //\r
+  // Display the statistics in all.\r
+  //\r
+  gBS->SetTimer (Private->Timer, TimerCancel, 0);\r
+\r
+  if (Private->TxCount != 0) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_PING6_STAT),\r
+      gShellNetwork2HiiHandle,\r
+      Private->TxCount,\r
+      Private->RxCount,\r
+      (100 * (Private->TxCount - Private->RxCount)) / Private->TxCount,\r
+      Private->RttSum\r
+      );\r
+  }\r
+\r
+  if (Private->RxCount != 0) {\r
+    ShellPrintHiiEx (\r
+      -1,\r
+      -1,\r
+      NULL,\r
+      STRING_TOKEN (STR_PING6_RTT),\r
+      gShellNetwork2HiiHandle,\r
+      Private->RttMin,\r
+      Private->RttMax,\r
+      DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL)\r
+      );\r
+  }\r
+\r
+ON_EXIT:\r
+\r
+  if (Private != NULL) {\r
+    Private->Status = EFI_ABORTED;\r
+\r
+    NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {\r
+      TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);\r
+\r
+      Status = Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);\r
+\r
+      RemoveEntryList (&TxInfo->Link);\r
+      Ping6DestroyTxInfo (TxInfo);\r
+    }\r
+\r
+    if (Private->Timer != NULL) {\r
+      gBS->CloseEvent (Private->Timer);\r
+    }\r
+\r
+    if (Private->Ip6 != NULL) {\r
+      Status = Private->Ip6->Cancel (Private->Ip6, &Private->RxToken);\r
+    }\r
+\r
+    if (Private->RxToken.Event != NULL) {\r
+      gBS->CloseEvent (Private->RxToken.Event);\r
+    }\r
+\r
+    if (Private->Ip6ChildHandle != NULL) {\r
+      Ping6DestroyIpInstance (Private);\r
+    }\r
+\r
+    FreePool (Private);\r
+  }\r
+\r
+  return ShellStatus;\r
+}\r
+\r
+/**\r
+  Function for 'ping6' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+\r
+  @retval SHELL_SUCCESS  The ping6 processed successfullly.\r
+  @retval others         The ping6 processed unsuccessfully.\r
+\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunPing6 (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  SHELL_STATUS        ShellStatus;\r
+  EFI_IPv6_ADDRESS    DstAddress;\r
+  EFI_IPv6_ADDRESS    SrcAddress;\r
+  UINT64              BufferSize;\r
+  UINTN               SendNumber;\r
+  LIST_ENTRY          *ParamPackage;\r
+  CONST CHAR16        *ValueStr;\r
+  CONST CHAR16        *ValueStrPtr;\r
+  UINTN               NonOptionCount;\r
+  CHAR16              *ProblemParam;\r
+\r
+  ProblemParam = NULL;\r
+  ShellStatus = SHELL_SUCCESS;\r
+\r
+  Status = ShellCommandLineParseEx (Ping6ParamList, &ParamPackage, &ProblemParam, TRUE, FALSE);\r
+  if (EFI_ERROR(Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), gShellNetwork2HiiHandle);\r
+    ShellStatus = SHELL_INVALID_PARAMETER;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  SendNumber = 10;\r
+  BufferSize = 16;\r
+\r
+  //\r
+  // Parse the paramter of count number.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-n");\r
+  ValueStrPtr = ValueStr;\r
+  if (ValueStr != NULL) {\r
+    SendNumber = ShellStrToUintn (ValueStrPtr);\r
+\r
+    //\r
+    // ShellStrToUintn will return 0 when input is 0 or an invalid input string.\r
+    //\r
+    if ((SendNumber == 0) || (SendNumber > PING6_MAX_SEND_NUMBER)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SEND_NUMBER), gShellNetwork2HiiHandle, ValueStr);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+  //\r
+  // Parse the paramter of buffer size.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");\r
+  ValueStrPtr = ValueStr;\r
+  if (ValueStr != NULL) {\r
+    BufferSize = ShellStrToUintn (ValueStrPtr);\r
+\r
+    //\r
+    // ShellStrToUintn will return 0 when input is 0 or an invalid input string.\r
+    //\r
+    if ((BufferSize < 16) || (BufferSize > PING6_MAX_BUFFER_SIZE)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_BUFFER_SIZE), gShellNetwork2HiiHandle, ValueStr);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+\r
+  ZeroMem (&SrcAddress, sizeof (EFI_IPv6_ADDRESS));\r
+  ZeroMem (&DstAddress, sizeof (EFI_IPv6_ADDRESS));\r
+\r
+  //\r
+  // Parse the paramter of source ip address.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");\r
+  ValueStrPtr = ValueStr;\r
+  if (ValueStr != NULL) {\r
+    mIp6SrcString = ValueStr;\r
+    Status = NetLibStrToIp6 (ValueStrPtr, &SrcAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP), gShellNetwork2HiiHandle, ValueStr);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+  //\r
+  // Parse the paramter of destination ip address.\r
+  //\r
+  NonOptionCount = ShellCommandLineGetCount(ParamPackage);\r
+  ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32)(NonOptionCount-1));\r
+  if (NonOptionCount != 2) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), gShellNetwork2HiiHandle);\r
+    ShellStatus = SHELL_INVALID_PARAMETER;\r
+    goto ON_EXIT;\r
+  }\r
+  ValueStrPtr = ValueStr;\r
+  if (ValueStr != NULL) {\r
+    mIp6DstString = ValueStr;\r
+    Status = NetLibStrToIp6 (ValueStrPtr, &DstAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP), gShellNetwork2HiiHandle, ValueStr);\r
+      ShellStatus = SHELL_INVALID_PARAMETER;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+  //\r
+  // Get frequency to calculate the time from ticks.\r
+  //\r
+  Status = Ping6GetFrequency ();\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    ShellStatus = SHELL_ACCESS_DENIED;\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // Enter into ping6 process.\r
+  //\r
+  ShellStatus = ShellPing6 (\r
+              ImageHandle,\r
+              (UINT32)SendNumber,\r
+              (UINT32)BufferSize,\r
+              &SrcAddress,\r
+              &DstAddress\r
+              );\r
+\r
+ON_EXIT:\r
+  ShellCommandLineFreeVarList (ParamPackage);\r
+  return ShellStatus;\r
+}\r
+\r
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c
new file mode 100644 (file)
index 0000000..6837b3a
--- /dev/null
@@ -0,0 +1,91 @@
+/** @file\r
+  Main file for NULL named library for network2 shell command functions.\r
+\r
+  Copyright (c) 2016, Intel Corporation. All rights reserved. <BR>\r
+  This program and the accompanying materials are licensed and made available under\r
+  the terms and conditions of the BSD License which accompanies this distribution.\r
+  The full text of the license may be found at http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include "UefiShellNetwork2CommandsLib.h"\r
+\r
+CONST CHAR16 gShellNetwork2FileName[] = L"ShellCommands";\r
+EFI_HANDLE gShellNetwork2HiiHandle = NULL;\r
+\r
+/**\r
+  return the file name of the help text file if not using HII.\r
+\r
+  @return The string pointer to the file name.\r
+**/\r
+CONST CHAR16*\r
+EFIAPI\r
+ShellCommandGetManFileNameNetwork2 (\r
+  VOID\r
+  )\r
+{\r
+  return (gShellNetwork2FileName);\r
+}\r
+\r
+/**\r
+  Constructor for the Shell Network2 Commands library.\r
+\r
+  Install the handlers for Network2 UEFI Shell 2.0 profile commands.\r
+\r
+  @param ImageHandle            The image handle of the process.\r
+  @param SystemTable            The EFI System Table pointer.\r
+\r
+  @retval EFI_SUCCESS           The shell command handlers were installed sucessfully.\r
+  @retval EFI_UNSUPPORTED       The shell level required was not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellNetwork2CommandsLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  gShellNetwork2HiiHandle = NULL;\r
+\r
+  //\r
+  // check our bit of the profiles mask\r
+  //\r
+  if ((PcdGet8(PcdShellProfileMask) & BIT4) == 0) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+\r
+  gShellNetwork2HiiHandle = HiiAddPackages (&gShellNetwork2HiiGuid, gImageHandle, UefiShellNetwork2CommandsLibStrings, NULL);\r
+  if (gShellNetwork2HiiHandle == NULL) {\r
+    return (EFI_DEVICE_ERROR);\r
+  }\r
+  //\r
+  // install our shell command handlers\r
+  //\r
+  ShellCommandRegisterCommandName(L"ping6",    ShellCommandRunPing6     , ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE , gShellNetwork2HiiHandle, STRING_TOKEN(STR_GET_HELP_PING6));\r
+  ShellCommandRegisterCommandName(L"ifconfig6",ShellCommandRunIfconfig6 , ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE , gShellNetwork2HiiHandle, STRING_TOKEN(STR_GET_HELP_IFCONFIG6));\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
+/**\r
+  Destructor for the library.  free any resources.\r
+\r
+  @param ImageHandle            The image handle of the process.\r
+  @param SystemTable            The EFI System Table pointer.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ShellNetwork2CommandsLibDestructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  if (gShellNetwork2HiiHandle != NULL) {\r
+    HiiRemovePackages(gShellNetwork2HiiHandle);\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h
new file mode 100644 (file)
index 0000000..138cc8c
--- /dev/null
@@ -0,0 +1,72 @@
+/** @file\r
+  Main file for NULL named library for network2 shell command functions.\r
+\r
+  Copyright (c) 2016, Intel Corporation. All rights reserved. <BR>\r
+  This program and the accompanying materials are licensed and made available under\r
+  the terms and conditions of the BSD License which accompanies this distribution.\r
+  The full text of the license may be found at http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_\r
+#define _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_\r
+\r
+#include <Protocol/Cpu.h>\r
+#include <Protocol/ServiceBinding.h>\r
+#include <Protocol/Ip6.h>\r
+#include <Protocol/Ip6Config.h>\r
+\r
+#include <Guid/ShellLibHiiGuid.h>\r
+\r
+#include <Library/ShellLib.h>\r
+#include <Library/ShellCommandLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/NetLib.h>\r
+\r
+extern EFI_HANDLE gShellNetwork2HiiHandle;\r
+\r
+/**\r
+  Function for 'ping6' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+\r
+  @retval SHELL_SUCCESS  The ping6 processed successfullly.\r
+  @retval others         The ping6 processed unsuccessfully.\r
+\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunPing6 (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  );\r
+\r
+/**\r
+  Function for 'ifconfig6' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+\r
+  @retval SHELL_SUCCESS   The ifconfig6 command processed successfully.\r
+  @retval others          The ifconfig6 command process failed.\r
+\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunIfconfig6 (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
new file mode 100644 (file)
index 0000000..426efcc
--- /dev/null
@@ -0,0 +1,63 @@
+##  @file\r
+# Provides shell network2 functions\r
+#\r
+# Copyright (c) 2016, Intel Corporation. All rights reserved. <BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = UefiShellNetwork2CommandsLib\r
+  FILE_GUID                      = D94E3B82-908E-46bf-A7B9-C7B7F17B1B7D\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|UEFI_APPLICATION UEFI_DRIVER\r
+  CONSTRUCTOR                    = ShellNetwork2CommandsLibConstructor\r
+  DESTRUCTOR                     = ShellNetwork2CommandsLibDestructor\r
+\r
+[Sources.common]\r
+  UefiShellNetwork2CommandsLib.uni\r
+  UefiShellNetwork2CommandsLib.c\r
+  UefiShellNetwork2CommandsLib.h\r
+  Ping6.c\r
+  Ifconfig6.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  ShellCommandLib\r
+  ShellLib\r
+  UefiLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  PcdLib\r
+  HiiLib\r
+  FileHandleLib\r
+  NetLib\r
+\r
+[Pcd]\r
+  gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES\r
+\r
+[Protocols]\r
+  gEfiCpuArchProtocolGuid                       ## CONSUMES\r
+  gEfiIp6ProtocolGuid                           ## SOMETIMES_CONSUMES\r
+  gEfiIp6ServiceBindingProtocolGuid             ## SOMETIMES_CONSUMES\r
+  gEfiIp6ConfigProtocolGuid                     ## SOMETIMES_CONSUMES\r
+\r
+[Guids]\r
+  gShellNetwork2HiiGuid                         ## SOMETIMES_CONSUMES ## HII\r
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni
new file mode 100644 (file)
index 0000000..fb2bfab
--- /dev/null
@@ -0,0 +1,151 @@
+/** @file\r
+\r
+  String definitions for UEFI Shell network 2 commands\r
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions\r
+  of the BSD License which accompanies this distribution.  The full\r
+  text of the license may be found at<BR>\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  Module Name:\r
+\r
+   UefiShellNetwork2CommandsLib.uni\r
+\r
+  Abstract:\r
+\r
+   String definitions for UEFI Shell 2.0 network 2 commands\r
+**/\r
+\r
+#langdef   en-US "english"\r
+\r
+#string STR_PING6_INVALID_IP               #language en-US  "%Ping6: Invalid IP6 address, %s\r\n"\r
+#string STR_PING6_INVALID_INPUT            #language en-US  "%Ping6: Invalid input, please type 'Ping6 -?'for help\r\n"\r
+#string STR_PING6_INVALID_SEND_NUMBER      #language en-US  "%Ping6: Invalid send number, %s\r\n"\r
+#string STR_PING6_INVALID_BUFFER_SIZE      #language en-US  "%Ping6: Invalid buffer size, %s\r\n"\r
+#string STR_PING6_INVALID_SOURCE           #language en-US  "%Ping6: Require source interface option\r\n"\r
+#string STR_PING6_IP6_CONFIG               #language en-US  "%Ping6: The process of Ip6 Configure %r\r\n"\r
+#string STR_PING6_IP6CFG_GETDATA           #language en-US  "%Ping6: Get data of the interface information %r\r\n"\r
+#string STR_PING6_SEND_REQUEST             #language en-US  "Echo request sequence %d fails.\r\n"\r
+#string STR_PING6_SOURCE_NOT_FOUND         #language en-US  "Source %s not found.\r\n"\r
+#string STR_PING6_NOSOURCE_INDOMAIN        #language en-US  "No sources in %s's multicast domain.\r\n"\r
+#string STR_PING6_START                    #language en-US  "Ping %s %d data bytes\r\n"\r
+#string STR_PING6_TIMEOUT                  #language en-US  "Echo request sequence %d timeout.\r\n"\r
+#string STR_PING6_REPLY_INFO               #language en-US  "%d bytes from %s : icmp_seq=%d ttl=%d time%c%dms\r\n"\r
+#string STR_PING6_STAT                     #language en-US  "\n%d packets transmitted, %d received, %d%% packet loss, time %dms\r\n"\r
+#string STR_PING6_RTT                      #language en-US  "\nRtt(round trip time) min=%dms max=%dms avg=%dms\r\n"\r
+\r
+#string STR_IFCONFIG6_ERR_IP6CFG_GETDATA       #language en-US    "Get data of the interface information %hr\r\n"\r
+#string STR_IFCONFIG6_INFO_BREAK               #language en-US    "-----------------------------------------------------------------"\r
+#string STR_IFCONFIG6_INFO_COLON               #language en-US    ":"\r
+#string STR_IFCONFIG6_INFO_JOINT               #language en-US    " >> "\r
+#string STR_IFCONFIG6_INFO_NEWLINE             #language en-US    "\r\n"\r
+#string STR_IFCONFIG6_INFO_IF_NAME             #language en-US    "\n%Hname         : %s%N\r\n"\r
+#string STR_IFCONFIG6_INFO_POLICY_AUTO         #language en-US    "%Hpolicy       : automatic%N\r\n"\r
+#string STR_IFCONFIG6_INFO_POLICY_MAN          #language en-US    "%Hpolicy       : manual%N\r\n"\r
+#string STR_IFCONFIG6_INFO_DAD_TRANSMITS       #language en-US    "%Hdad xmits    : %d%N\r\n"\r
+#string STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD   #language en-US    "%Hinterface id : %N"\r
+#string STR_IFCONFIG6_INFO_MAC_ADDR_HEAD       #language en-US    "%Hmac addr     : %N"\r
+#string STR_IFCONFIG6_INFO_MAC_ADDR_BODY       #language en-US    "%02x"\r
+#string STR_IFCONFIG6_INFO_IP_ADDR_HEAD        #language en-US    "\n%Hhost addr    : %N\r\n"\r
+#string STR_IFCONFIG6_INFO_DNS_ADDR_HEAD       #language en-US    "\n%Hdns server   : %N\r\n"\r
+#string STR_IFCONFIG6_INFO_IP_ADDR_BODY        #language en-US    "%02x"\r
+#string STR_IFCONFIG6_INFO_IP_ADDR_BODY4BIT    #language en-US    "%x"\r
+#string STR_IFCONFIG6_INFO_ROUTE_HEAD          #language en-US    "\n%Hroute table  : %N\r\n"\r
+#string STR_IFCONFIG6_INFO_PREFIX_LEN          #language en-US    "/%d"\r
+#string STR_IFCONFIG6_LINE_HELP                #language en-US    "Displays or modifies the IPv6 configuration"\r
+#string STR_IFCONFIG6_ERR_LACK_INTERFACE       #language en-US    "Lack interface name.\r\n"\r
+                                                                  "Usage: IfConfig6 -s <Name> \r\n"\r
+                                                                  "Example: IfConfig6 -s eth0 auto\r\n"\r
+#string STR_IFCONFIG6_LACK_OPTION              #language en-US    "Flags lack. Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_CONFLICT_OPTIONS         #language en-US    "Flags conflict. Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_LACK_COMMAND         #language en-US    "Lack interface config option.\r\n"\r
+                                                                  "Hint: Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_INVALID_INTERFACE    #language en-US    "Invalid interface name.\r\n"\r
+                                                                  "Hint: Use {IfConfig6 -l} to check existing interface names.\r\n"\r
+#string STR_IFCONFIG6_ERR_INVALID_COMMAND      #language en-US    "Invalid command. Bad command %H%s%N is skipped.\r\n"\r
+                                                                  "Hint: Incorrect option or arguments. Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_LACK_ARGUMENTS       #language en-US    "Lack arguments. Bad command %H%s%N is skipped.\r\n"\r
+                                                                  "Hint: Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_LACK_OPTION          #language en-US    "Lack options.\r\n"\r
+                                                                  "Hint: Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_MAN_HOST             #language en-US    "Manual address configuration failed. Please retry.\r\n"\r
+#string STR_IFCONFIG6_ERR_DUPLICATE_COMMAND    #language en-US    "Duplicate commands. Bad command %H%s%N is skipped.\r\n"\r
+                                                                  "Hint: Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_CONFLICT_COMMAND     #language en-US    "Conflict commands. Bad command %H%s%N is skipped.\r\n"\r
+                                                                  "Hint: Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_UNKNOWN_COMMAND      #language en-US    "Unknown commands. Bad command %H%s%N is skipped.\r\n"\r
+                                                                  "Hint: Please type 'IfConfig6 -?' for help info.\r\n"\r
+#string STR_IFCONFIG6_ERR_ADDRESS_FAILED       #language en-US    "It failed to set .\r\n"\r
+\r
+\r
+#string STR_GET_HELP_PING6                     #language en-US ""\r
+".TH ping6 0 "Ping a target machine with UEFI IPv6 network stack."\r\n"\r
+".SH NAME\r\n"\r
+"Ping a target machine with UEFI IPv6 network stack.\r\n"\r
+".SH SYNOPSIS\r\n"\r
+" \r\n"\r
+"Ping6 [-l size] [-n count] [-s SourceIp] TargetIp\r\n"\r
+".SH OPTIONS\r\n"\r
+" \r\n"\r
+"  -l size     Send buffer size, in bytes(default=16, min=16, max=32768).\r\n"\r
+"  -n count    Send request count, (default=10, min=1, max=10000).\r\n"\r
+"  -s SourceIp Source IPv6 address.\r\n"\r
+"  TargetIp    Target IPv6 address.\r\n"\r
+".SH EXAMPLES\r\n"\r
+" \r\n"\r
+"Examples:\r\n"\r
+"  * To ping the target host by sending 5 request with 1000 bytes from 2002::1\r\n"\r
+"    Shell:\> Ping6 -s 2002::1 2002::2 -l 1000 -n 5\r\n"\r
+" \r\n"\r
+"  * To ping the target host with 1000 bytes\r\n"\r
+"    Shell:\> Ping6 2002::2 -l 1000\r\n"\r
+\r
+#string STR_GET_HELP_IFCONFIG6                 #language en-US    ""\r
+".TH ifconfig6 0 "Displays or modifies IPv6 configuration for network interface."\r\n"\r
+".SH NAME\r\n"\r
+"Displays or modifies IPv6 configuration for network interface.\r\n"\r
+".SH SYNOPSIS\r\n"\r
+" \r\n"\r
+"IfConfig6 -r [Name] | -l [Name] \r\n"\r
+"IfConfig6 -s <Name> [dad <Num>] [auto | [man [id <mac>] [host <IPv6> gw <IPv6>]\r\n"\r
+"             [dns <IPv6>]]]\r\n"\r
+".SH OPTIONS\r\n"\r
+" \r\n"\r
+"  Name                     Adapter name, i.e., eth0\r\n"\r
+"  -r [Name]                Reconfigure all or specified interface, and set\r\n"\r
+"                           automatic policy. If specified interface is already\r\n"\r
+"                           set to automatic,then refresh the IPv6 configuration.\r\n"\r
+"  -l [Name]                List the configuration of the specified interface.\r\n"\r
+"  -s <Name> dad <Num>      Set dad transmits count of the specified interface.\r\n"\r
+"  -s <Name> auto           Set automatic policy of the specified interface.\r\n"\r
+"  -s <Name> man id <Mac>   Set alternative interface id of the specified \r\n"\r
+"                           interface. Must under manual policy.\r\n"\r
+"  -s <Name> man host <IPv6> gw <IPv6>\r\n"\r
+"                           Set static host IP and gateway address of the\r\n"\r
+"                           specified interface. Must under manual policy.\r\n"\r
+"  -s <Name> man dns <IPv6> Set DNS server IP addresses of the specified\r\n"\r
+"                           interface.Must under manual policy.\r\n"\r
+".SH EXAMPLES\r\n"\r
+" \r\n"\r
+"EXAMPLES:\r\n"\r
+"  * To list the configuration for the interface eth0:\r\n"\r
+"    Shell:\> ifConfig6 -l eth0\r\n"\r
+" \r\n"\r
+"  * To use automatic configuration to request the IPv6 address configuration\r\n"\r
+"    dynamically for the interface eth0:\r\n"\r
+"    Shell:\> ifconfig6 -s eth0 auto\r\n"\r
+" \r\n"\r
+"  * To set the dad transmits count for eth0 under automatic policy:\r\n"\r
+"    Shell:\> ifconfig6 -s eth0 auto dad 10\r\n"\r
+" \r\n"\r
+"  * To set the alternative interface id of eth0 under manual policy:\r\n"\r
+"    Shell:\> ifconfig6 -s eth0 man id ff:dd:aa:88:66:cc\r\n"\r
+" \r\n"\r
+"  * To use the static IP6 addresses configuration for the interface eth0,\r\n"\r
+"    and this configuration survives the network reload:\r\n"\r
+"    Shell:\> ifconfig6 -s eth0 man host 2002::1/64 2002::2/64 gw 2002::3/64\r\n"\r
index 76a2b7d..39f8012 100644 (file)
@@ -2,7 +2,7 @@
 # This Package provides all definitions for EFI and UEFI Shell\r
 #\r
 # (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR>\r
-# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 #\r
 # This program and the accompanying materials are licensed and made available under\r
 # the terms and conditions of the BSD License which accompanies this distribution.\r
@@ -53,6 +53,7 @@
   gShellLevel2HiiGuid             = {0xf95a7ccc, 0x4c55, 0x4426, {0xa7, 0xb4, 0xdc, 0x89, 0x61, 0x95, 0xb, 0xae}}\r
   gShellLevel3HiiGuid             = {0x4344558d, 0x4ef9, 0x4725, {0xb1, 0xe4, 0x33, 0x76, 0xe8, 0xd6, 0x97, 0x4f}}\r
   gShellNetwork1HiiGuid           = {0xf3d301bb, 0xf4a5, 0x45a8, {0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae}}\r
+  gShellNetwork2HiiGuid           = {0x174b2b5, 0xf505, 0x4b12, {0xaa, 0x60, 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37}}\r
   gShellTftpHiiGuid               = {0x738a9314, 0x82c1, 0x4592, {0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}}\r
   gShellBcfgHiiGuid               = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6}}\r
 \r
@@ -94,6 +95,7 @@
   #  bit 1 = Debug1\r
   #  bit 2 = Install1\r
   #  bit 3 = Network1\r
+  #  bit 4 = Network2\r
   gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask|0xFF|UINT8|0x0000000D\r
 \r
   ## This is the character count for allocation for consistent mappings\r
index b29adb8..364a622 100644 (file)
@@ -28,7 +28,7 @@
   UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf\r
   DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf\r
   DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf\r
-  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf  \r
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf\r
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
   UefiLib|MdePkg/Library/UefiLib/UefiLib.inf\r
@@ -46,7 +46,7 @@
   ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf\r
   ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf\r
   HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf\r
-  \r
+\r
   PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
   BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf\r
   IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
@@ -88,6 +88,7 @@
   ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf\r
   ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf\r
   ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf\r
+  ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf\r
   ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf\r
 \r
   ShellPkg/Library/UefiDpLib/UefiDpLib.inf {\r
       NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf\r
       NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf\r
       NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf\r
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf\r
 !ifdef $(INCLUDE_DP)\r
       NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf\r
 !endif #$(INCLUDE_DP)\r