Add NetworkPkg (P.UDK2010.UP3.Network.P1)
authorhhtian <hhtian@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 1 Nov 2010 06:13:54 +0000 (06:13 +0000)
committerhhtian <hhtian@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 1 Nov 2010 06:13:54 +0000 (06:13 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10986 6f19259b-4bc3-4df7-8a09-765794883524

142 files changed:
NetworkPkg/Application/IfConfig6/IfConfig6.c [new file with mode: 0644]
NetworkPkg/Application/IfConfig6/IfConfig6.h [new file with mode: 0644]
NetworkPkg/Application/IfConfig6/IfConfig6.inf [new file with mode: 0644]
NetworkPkg/Application/IfConfig6/IfConfig6Strings.uni [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Delete.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Delete.h [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Dump.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Dump.h [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/ForEach.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/ForEach.h [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Helper.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Helper.h [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Indexer.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Indexer.h [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/IpSecConfig.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/IpSecConfig.h [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/IpSecConfig.inf [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Match.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/Match.h [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c [new file with mode: 0644]
NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h [new file with mode: 0644]
NetworkPkg/Application/Ping6/Ia32/Tsc.c [new file with mode: 0644]
NetworkPkg/Application/Ping6/Ipf/Itc.c [new file with mode: 0644]
NetworkPkg/Application/Ping6/Ping6.c [new file with mode: 0644]
NetworkPkg/Application/Ping6/Ping6.h [new file with mode: 0644]
NetworkPkg/Application/Ping6/Ping6.inf [new file with mode: 0644]
NetworkPkg/Application/Ping6/Ping6Strings.uni [new file with mode: 0644]
NetworkPkg/Application/Ping6/X64/Tsc.c [new file with mode: 0644]
NetworkPkg/Application/VConfig/VConfig.c [new file with mode: 0644]
NetworkPkg/Application/VConfig/VConfig.inf [new file with mode: 0644]
NetworkPkg/Application/VConfig/VConfigStrings.uni [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Driver.h [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Io.c [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Io.h [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c [new file with mode: 0644]
NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Common.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Common.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Config.vfr [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6ConfigImpl.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6ConfigNv.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6ConfigNv.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Driver.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Driver.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Dxe.inf [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6DxeStrings.uni [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Icmp.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Icmp.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6If.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6If.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Impl.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Impl.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Input.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Input.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Mld.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Mld.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Nd.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Nd.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6NvData.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Option.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Option.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Output.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Output.h [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Route.c [new file with mode: 0644]
NetworkPkg/Ip6Dxe/Ip6Route.h [new file with mode: 0644]
NetworkPkg/IpSecDxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecConfigImpl.c [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecConfigImpl.h [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecCryptIo.c [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecCryptIo.h [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecDebug.c [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecDebug.h [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecDriver.c [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecDxe.inf [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecImpl.c [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecImpl.h [new file with mode: 0644]
NetworkPkg/IpSecDxe/IpSecSaEngine.c [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Driver.c [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Driver.h [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Impl.c [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Impl.h [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Option.c [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Option.h [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Rrq.c [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Support.c [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Support.h [new file with mode: 0644]
NetworkPkg/Mtftp6Dxe/Mtftp6Wrq.c [new file with mode: 0644]
NetworkPkg/NetworkPkg.dec [new file with mode: 0644]
NetworkPkg/NetworkPkg.dsc [new file with mode: 0644]
NetworkPkg/TcpDxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/TcpDxe/SockImpl.c [new file with mode: 0644]
NetworkPkg/TcpDxe/SockImpl.h [new file with mode: 0644]
NetworkPkg/TcpDxe/SockInterface.c [new file with mode: 0644]
NetworkPkg/TcpDxe/Socket.h [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpDispatcher.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpDriver.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpDriver.h [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpDxe.inf [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpFunc.h [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpInput.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpIo.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpMain.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpMain.h [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpMisc.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpOption.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpOption.h [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpOutput.c [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpProto.h [new file with mode: 0644]
NetworkPkg/TcpDxe/TcpTimer.c [new file with mode: 0644]
NetworkPkg/Udp6Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Udp6Dxe/Udp6Driver.c [new file with mode: 0644]
NetworkPkg/Udp6Dxe/Udp6Driver.h [new file with mode: 0644]
NetworkPkg/Udp6Dxe/Udp6Dxe.inf [new file with mode: 0644]
NetworkPkg/Udp6Dxe/Udp6Impl.c [new file with mode: 0644]
NetworkPkg/Udp6Dxe/Udp6Impl.h [new file with mode: 0644]
NetworkPkg/Udp6Dxe/Udp6Main.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcDriver.h [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcMtftp.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcMtftp.h [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/PxeBcSupport.h [new file with mode: 0644]
NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf [new file with mode: 0644]

diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6.c b/NetworkPkg/Application/IfConfig6/IfConfig6.c
new file mode 100644 (file)
index 0000000..b2eada6
--- /dev/null
@@ -0,0 +1,1781 @@
+/** @file\r
+  The implementation for Shell application IfConfig6.\r
+\r
+  Copyright (c) 2009 - 2010, 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 <Library/ShellLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.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
+#include <Protocol/Ip6.h>\r
+#include <Protocol/Ip6Config.h>\r
+\r
+#include "IfConfig6.h"\r
+\r
+EFI_HII_HANDLE      mHiiHandle;\r
+\r
+EFI_GUID            mEfiIfConfig6Guid     = EFI_IFCONFIG6_GUID;\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  mSetCheckList[] = {\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
+SplitStrToList (\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 == L'\0') {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Copy the CONST string to a local copy.\r
+  //\r
+  Str     = (CHAR16 *) AllocateZeroPool (StrSize (String));\r
+  ASSERT (Str != NULL);\r
+  Str     = StrCpy (Str, String);\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]    CheckList    The pointer of Event.\r
+  @param[in]    Context      The pointer of Context.\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), mHiiHandle, Node[Index]);\r
+    if (Index + 1 < Size) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);\r
+    }\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);\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), mHiiHandle);\r
+      }\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);\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), mHiiHandle, Ip->Addr[Index]);\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), mHiiHandle, Ip->Addr[Index + 1]);\r
+    }\r
+\r
+    if (Index + 2 < PREFIXMAXLEN) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);\r
+    }\r
+  }\r
+\r
+  if (PrefixLen != NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), mHiiHandle, *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]        Address    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
+  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]        Address    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 EFI_ABORTED;\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), mHiiHandle, 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), mHiiHandle, 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), mHiiHandle, 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), mHiiHandle, 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), mHiiHandle, 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), mHiiHandle, 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), mHiiHandle, 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 EFI_SUCCESS    The IfConfig6 list processed successfully.\r
+  @retval others         The IfConfig6 list process failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6ShowInterfaceInfo (\r
+  IN LIST_ENTRY    *IfList\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  LIST_ENTRY                *Entry;\r
+  IFCONFIG6_INTERFACE_CB    *IfCb;\r
+  UINTN                     Index;\r
+\r
+  Entry  = IfList->ForwardLink;\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (IsListEmpty (IfList)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);\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), mHiiHandle);\r
+\r
+    //\r
+    // Print interface name.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME), mHiiHandle, 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), mHiiHandle);\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN), mHiiHandle);\r
+    }\r
+\r
+    //\r
+    // Print dad transmit.\r
+    //\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS), mHiiHandle, 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), mHiiHandle);\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), mHiiHandle);\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), mHiiHandle);\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), mHiiHandle);\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), mHiiHandle);\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), mHiiHandle);\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), mHiiHandle);\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), mHiiHandle);\r
+\r
+      IfConfig6PrintIpAddr (\r
+        &IfCb->IfInfo->RouteTable[Index].Gateway,\r
+        NULL\r
+        );\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);\r
+    }\r
+\r
+    Entry = Entry->ForwardLink;\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), mHiiHandle);\r
+\r
+  return Status;\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 EFI_SUCCESS    The IfConfig6 clean processed successfully.\r
+  @retval others         The IfConfig6 clean process failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6ClearInterfaceInfo (\r
+  IN LIST_ENTRY    *IfList\r
+  )\r
+{\r
+  EFI_STATUS                Status;\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
+\r
+  if (IsListEmpty (IfList)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);\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
+      break;\r
+    }\r
+\r
+    Entry  = Entry->ForwardLink;\r
+  }\r
+\r
+  return Status;\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 EFI_SUCCESS    The IfConfig6 set processed successfully.\r
+  @retval others         The IfConfig6 set process failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6SetInterfaceInfo (\r
+  IN LIST_ENTRY    *IfList,\r
+  IN ARG_LIST      *VarArg\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\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), mHiiHandle);\r
+    return EFI_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
+\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
+    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
+    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
+                  mSetCheckList,\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), mHiiHandle, VarArg->Arg);\r
+          break;\r
+\r
+        case VarCheckConflict:\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), mHiiHandle, VarArg->Arg);\r
+          break;\r
+\r
+        case VarCheckUnknown:\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), mHiiHandle, 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
+        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
+        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
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"host");\r
+          continue;\r
+        } else {\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
+        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), mHiiHandle, Status);\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), mHiiHandle, Status);\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      IfInfo = AllocateZeroPool (DataSize);\r
+\r
+      if (IfInfo == NULL) {\r
+        Status = EFI_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), mHiiHandle, Status);\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), mHiiHandle);\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
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"gw");\r
+          continue;\r
+        } else {\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
+        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
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"dns");\r
+          continue;\r
+        } else {\r
+          goto ON_EXIT;\r
+        }\r
+      }\r
+      //\r
+      // Set static dhs 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
+        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
+        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
+        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
+        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
+        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 Status;\r
+\r
+}\r
+\r
+/**\r
+  The IfConfig6 main process.\r
+\r
+  @param[in]   Private    The pointer of IFCONFIG6_PRIVATE_DATA.\r
+\r
+  @retval EFI_SUCCESS    IfConfig6 processed successfully.\r
+  @retval others         The IfConfig6 process failed.\r
+\r
+**/\r
+EFI_STATUS\r
+IfConfig6 (\r
+  IN IFCONFIG6_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  EFI_STATUS    Status;\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
+    goto ON_EXIT;\r
+  }\r
+\r
+  switch (Private->OpCode) {\r
+  case IfConfig6OpList:\r
+    Status = IfConfig6ShowInterfaceInfo (&Private->IfList);\r
+    break;\r
+\r
+  case IfConfig6OpClear:\r
+    Status = IfConfig6ClearInterfaceInfo (&Private->IfList);\r
+    break;\r
+\r
+  case IfConfig6OpSet:\r
+    Status = IfConfig6SetInterfaceInfo (&Private->IfList, Private->VarArg);\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_ABORTED;\r
+  }\r
+\r
+ON_EXIT:\r
+\r
+  return Status;\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
+  This is the declaration of an EFI image entry point. This entry point is\r
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including\r
+  both device drivers and bus drivers.\r
+\r
+  The entry point for the IfConfig6 application which parses the command line input and calls the IfConfig6 process.\r
+\r
+  @param[in] ImageHandle    The image handle of this application.\r
+  @param[in] SystemTable    The pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS    The operation completed successfully.\r
+  @retval Others         Some errors occur.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IfConfig6Initialize (\r
+  IN  EFI_HANDLE         ImageHandle,\r
+  IN  EFI_SYSTEM_TABLE    *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                Status;\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
+\r
+  //\r
+  // Register our string package with HII and return the handle to it.\r
+  //\r
+  mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, IfConfig6Strings, NULL);\r
+  ASSERT (mHiiHandle != NULL);\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), mHiiHandle, ProblemParam);\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), mHiiHandle);\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), mHiiHandle);\r
+    goto ON_EXIT;\r
+  }\r
+  //\r
+  // To show the help information of ifconfig6 command.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-?")) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_HELP), mHiiHandle);\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  Status = EFI_INVALID_PARAMETER;\r
+\r
+  Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));\r
+\r
+  if (Private == NULL) {\r
+    Status = EFI_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             = (CHAR16 *) AllocateZeroPool (StrSize (ValueStr));\r
+      ASSERT (Str != NULL);\r
+\r
+      Str             = StrCpy (Str, ValueStr);\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             = (CHAR16 *) AllocateZeroPool (StrSize (ValueStr));\r
+      ASSERT (Str != NULL);\r
+\r
+      Str             = StrCpy (Str, ValueStr);\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), mHiiHandle);\r
+      goto ON_EXIT;\r
+    }\r
+    //\r
+    // To split the configuration into multi-section.\r
+    //\r
+    ArgList         = SplitStrToList (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), mHiiHandle);\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+  //\r
+  // Main process of ifconfig6.\r
+  //\r
+  Status = IfConfig6 (Private);\r
+\r
+ON_EXIT:\r
+\r
+  ShellCommandLineFreeVarList (ParamPackage);\r
+  HiiRemovePackages (mHiiHandle);\r
+  if (Private != NULL)\r
+    IfConfig6Cleanup (Private);\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6.h b/NetworkPkg/Application/IfConfig6/IfConfig6.h
new file mode 100644 (file)
index 0000000..eea7df5
--- /dev/null
@@ -0,0 +1,84 @@
+/** @file\r
+  The interface function declaration of shell application IfConfig6.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _IFCONFIG6_H_\r
+#define _IFCONFIG6_H_\r
+\r
+#define EFI_IFCONFIG6_GUID \\r
+  { \\r
+    0xbab7296b, 0x222c, 0x4408, {0x9e, 0x6c, 0xc2, 0x5c, 0x18, 0x7e, 0xff, 0x33} \\r
+  }\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
+#endif\r
diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6.inf b/NetworkPkg/Application/IfConfig6/IfConfig6.inf
new file mode 100644 (file)
index 0000000..dd3ab64
--- /dev/null
@@ -0,0 +1,52 @@
+## @file\r
+#  Component description file for Shell application IfConfig6.\r
+#\r
+#  Copyright (c) 2009 - 2010, 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
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = IfConfig6\r
+  FILE_GUID                      = 6F71926E-60CE-428d-AA58-A3D9FB879429\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = IfConfig6Initialize\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF\r
+#\r
+[Sources]\r
+  IfConfig6Strings.uni\r
+  IfConfig6.c\r
+  IfConfig6.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  \r
+[LibraryClasses]\r
+  BaseLib\r
+  UefiBootServicesTableLib\r
+  UefiApplicationEntryPoint\r
+  BaseMemoryLib\r
+  ShellLib\r
+  MemoryAllocationLib\r
+  DebugLib\r
+  HiiLib\r
+  NetLib\r
+\r
+[Protocols]\r
+  gEfiIp6ServiceBindingProtocolGuid             ## CONSUMS\r
+  gEfiIp6ConfigProtocolGuid                     ## CONSUMS\r
diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6Strings.uni b/NetworkPkg/Application/IfConfig6/IfConfig6Strings.uni
new file mode 100644 (file)
index 0000000..a5e7fd0
Binary files /dev/null and b/NetworkPkg/Application/IfConfig6/IfConfig6Strings.uni differ
diff --git a/NetworkPkg/Application/IpsecConfig/Delete.c b/NetworkPkg/Application/IpsecConfig/Delete.c
new file mode 100644 (file)
index 0000000..caeb1c8
--- /dev/null
@@ -0,0 +1,110 @@
+/** @file\r
+  The implementation of delete policy entry function in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 "IpSecConfig.h"\r
+#include "Indexer.h"\r
+#include "Delete.h"\r
+#include "Match.h"\r
+#include "ForEach.h"\r
+\r
+/**\r
+  Private function to delete entry information in database.\r
+\r
+  @param[in] Selector    The pointer to EFI_IPSEC_CONFIG_SELECTOR structure.\r
+  @param[in] Data        The pointer to Data.\r
+  @param[in] Context     The pointer to DELETE_POLICY_ENTRY_CONTEXT.\r
+\r
+  @retval EFI_ABORTED    Abort the iteration.\r
+  @retval EFI_SUCCESS    Continue the iteration.\r
+**/\r
+EFI_STATUS\r
+DeletePolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_SELECTOR      *Selector,\r
+  IN VOID                           *Data,\r
+  IN DELETE_POLICY_ENTRY_CONTEXT    *Context\r
+  )\r
+{\r
+  if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {\r
+    Context->Status = mIpSecConfig->SetData (\r
+                                      mIpSecConfig,\r
+                                      Context->DataType,\r
+                                      Selector,\r
+                                      NULL,\r
+                                      NULL\r
+                                      );\r
+    //\r
+    // Abort the iteration after the insertion.\r
+    //\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Flush or delete entry information in the database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS      Delete entry information successfully.\r
+  @retval EFI_NOT_FOUND    Can't find the specified entry.\r
+  @retval Others           Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+FlushOrDeletePolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  DELETE_POLICY_ENTRY_CONTEXT    Context;\r
+  CONST CHAR16                   *ValueStr;\r
+\r
+  //\r
+  // If user wants to remove all.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-f")) {\r
+    Status = mIpSecConfig->SetData (\r
+                             mIpSecConfig,\r
+                             DataType,\r
+                             NULL,\r
+                             NULL,\r
+                             NULL\r
+                             );\r
+  } else {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");\r
+    if (ValueStr == NULL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);\r
+    if (!EFI_ERROR (Status)) {\r
+      Context.DataType  = DataType;\r
+      Context.Status    = EFI_NOT_FOUND;\r
+      ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) DeletePolicyEntry, &Context);\r
+      Status = Context.Status;\r
+\r
+      if (Status == EFI_NOT_FOUND) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);\r
+      } else if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DELETE_FAILED), mHiiHandle, mAppName);\r
+      }\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/NetworkPkg/Application/IpsecConfig/Delete.h b/NetworkPkg/Application/IpsecConfig/Delete.h
new file mode 100644 (file)
index 0000000..49f3b0d
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+  The internal structure and function declaration of delete policy entry function\r
+  in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef __DELETE_H_\r
+#define __DELETE_H_\r
+\r
+typedef struct {\r
+  EFI_IPSEC_CONFIG_DATA_TYPE    DataType;\r
+  POLICY_ENTRY_INDEXER          Indexer;\r
+  EFI_STATUS                    Status;      //Indicate whether deletion succeeds.\r
+} DELETE_POLICY_ENTRY_CONTEXT;\r
+\r
+/**\r
+  Flush or delete entry information in the database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS      Delete entry information successfully.\r
+  @retval EFI_NOT_FOUND    Can't find the specified entry.\r
+  @retval Others           Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+FlushOrDeletePolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  );\r
+\r
+#endif\r
diff --git a/NetworkPkg/Application/IpsecConfig/Dump.c b/NetworkPkg/Application/IpsecConfig/Dump.c
new file mode 100644 (file)
index 0000000..004ab10
--- /dev/null
@@ -0,0 +1,530 @@
+/** @file\r
+  The implementation of dump policy entry function in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 "IpSecConfig.h"\r
+#include "Dump.h"\r
+#include "ForEach.h"\r
+#include "Helper.h"\r
+\r
+/**\r
+  Private function called to get the version infomation from an EFI_IP_ADDRESS_INFO structure.\r
+\r
+  @param[in] AddressInfo    The pointer to the EFI_IP_ADDRESS_INFO structure.\r
+\r
+  @return the value of version.\r
+**/\r
+UINTN\r
+GetVerFromAddrInfo (\r
+  IN EFI_IP_ADDRESS_INFO    *AddressInfo\r
+)\r
+{\r
+  if((AddressInfo->PrefixLength <= 32) && (AddressInfo->Address.Addr[1] == 0) &&\r
+     (AddressInfo->Address.Addr[2] == 0) && (AddressInfo->Address.Addr[3] == 0)) {\r
+    return IP_VERSION_4;\r
+  } else {\r
+    return IP_VERSION_6;\r
+  }\r
+}\r
+\r
+/**\r
+  Private function called to get the version information from a EFI_IP_ADDRESS structure.\r
+\r
+  @param[in] Address    The pointer to the EFI_IP_ADDRESS structure.\r
+\r
+  @return The value of the version.\r
+**/\r
+UINTN\r
+GetVerFromIpAddr (\r
+  IN EFI_IP_ADDRESS    *Address\r
+)\r
+{\r
+  if ((Address->Addr[1] == 0) && (Address->Addr[2] == 0) && (Address->Addr[3] == 0)) {\r
+    return IP_VERSION_4;\r
+  } else {\r
+    return IP_VERSION_6;\r
+  }\r
+}\r
+\r
+/**\r
+  Private function called to print an ASCII string in unicode char format.\r
+\r
+  @param[in] Str       The pointer to the ASCII string.\r
+  @param[in] Length    The value of the ASCII string length.\r
+**/\r
+VOID\r
+DumpAsciiString (\r
+  IN CHAR8    *Str,\r
+  IN UINTN    Length\r
+  )\r
+{\r
+  UINTN    Index;\r
+  for (Index = 0; Index < Length; Index++) {\r
+    Print (L"%c", (CHAR16) Str[Index]);\r
+  }\r
+}\r
+\r
+/**\r
+  Private function called to print EFI_IP_ADDRESS_INFO content.\r
+\r
+  @param[in] AddressInfo    The pointer to the EFI_IP_ADDRESS_INFO structure.\r
+**/\r
+VOID\r
+DumpAddressInfo (\r
+  IN EFI_IP_ADDRESS_INFO    *AddressInfo\r
+  )\r
+{\r
+  if (IP_VERSION_4 == GetVerFromAddrInfo (AddressInfo)) {\r
+    Print (\r
+      L"%d.%d.%d.%d",\r
+      (UINTN) AddressInfo->Address.v4.Addr[0],\r
+      (UINTN) AddressInfo->Address.v4.Addr[1],\r
+      (UINTN) AddressInfo->Address.v4.Addr[2],\r
+      (UINTN) AddressInfo->Address.v4.Addr[3]\r
+      );\r
+    if (AddressInfo->PrefixLength != 32) {\r
+      Print (L"/%d", (UINTN) AddressInfo->PrefixLength);\r
+    }\r
+  }\r
+\r
+  if (IP_VERSION_6 == GetVerFromAddrInfo (AddressInfo)) {\r
+    Print (\r
+      L"%x:%x:%x:%x:%x:%x:%x:%x",\r
+      (((UINT16) AddressInfo->Address.v6.Addr[0]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[1]),\r
+      (((UINT16) AddressInfo->Address.v6.Addr[2]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[3]),\r
+      (((UINT16) AddressInfo->Address.v6.Addr[4]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[5]),\r
+      (((UINT16) AddressInfo->Address.v6.Addr[6]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[7]),\r
+      (((UINT16) AddressInfo->Address.v6.Addr[8]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[9]),\r
+      (((UINT16) AddressInfo->Address.v6.Addr[10]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[11]),\r
+      (((UINT16) AddressInfo->Address.v6.Addr[12]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[13]),\r
+      (((UINT16) AddressInfo->Address.v6.Addr[14]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[15])\r
+      );\r
+    if (AddressInfo->PrefixLength != 128) {\r
+      Print (L"/%d", AddressInfo->PrefixLength);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Private function called to print EFI_IP_ADDRESS content.\r
+\r
+  @param[in] IpAddress    The pointer to the EFI_IP_ADDRESS structure.\r
+**/\r
+VOID\r
+DumpIpAddress (\r
+  IN EFI_IP_ADDRESS    *IpAddress\r
+  )\r
+{\r
+  if (IP_VERSION_4 == GetVerFromIpAddr (IpAddress)) {\r
+    Print (\r
+      L"%d.%d.%d.%d",\r
+      (UINTN) IpAddress->v4.Addr[0],\r
+      (UINTN) IpAddress->v4.Addr[1],\r
+      (UINTN) IpAddress->v4.Addr[2],\r
+      (UINTN) IpAddress->v4.Addr[3]\r
+      );\r
+  }\r
+\r
+  if (IP_VERSION_6 == GetVerFromIpAddr (IpAddress)) {\r
+    Print (\r
+      L"%x:%x:%x:%x:%x:%x:%x:%x",\r
+      (((UINT16) IpAddress->v6.Addr[0]) << 8) | ((UINT16) IpAddress->v6.Addr[1]),\r
+      (((UINT16) IpAddress->v6.Addr[2]) << 8) | ((UINT16) IpAddress->v6.Addr[3]),\r
+      (((UINT16) IpAddress->v6.Addr[4]) << 8) | ((UINT16) IpAddress->v6.Addr[5]),\r
+      (((UINT16) IpAddress->v6.Addr[6]) << 8) | ((UINT16) IpAddress->v6.Addr[7]),\r
+      (((UINT16) IpAddress->v6.Addr[8]) << 8) | ((UINT16) IpAddress->v6.Addr[9]),\r
+      (((UINT16) IpAddress->v6.Addr[10]) << 8) | ((UINT16) IpAddress->v6.Addr[11]),\r
+      (((UINT16) IpAddress->v6.Addr[12]) << 8) | ((UINT16) IpAddress->v6.Addr[13]),\r
+      (((UINT16) IpAddress->v6.Addr[14]) << 8) | ((UINT16) IpAddress->v6.Addr[15])\r
+      );\r
+  }\r
+\r
+}\r
+\r
+/**\r
+  Private function called to print EFI_IPSEC_SPD_SELECTOR content.\r
+\r
+  @param[in] Selector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.\r
+**/\r
+VOID\r
+DumpSpdSelector (\r
+  IN EFI_IPSEC_SPD_SELECTOR    *Selector\r
+  )\r
+{\r
+  UINT32    Index;\r
+  CHAR16    *Str;\r
+\r
+  for (Index = 0; Index < Selector->LocalAddressCount; Index++) {\r
+    if (Index > 0) {\r
+      Print (L",");\r
+    }\r
+\r
+    DumpAddressInfo (&Selector->LocalAddress[Index]);\r
+  }\r
+\r
+  if (Index == 0) {\r
+    Print (L"localhost");\r
+  }\r
+\r
+  Print (L" -> ");\r
+\r
+  for (Index = 0; Index < Selector->RemoteAddressCount; Index++) {\r
+    if (Index > 0) {\r
+      Print (L",");\r
+    }\r
+\r
+    DumpAddressInfo (&Selector->RemoteAddress[Index]);\r
+  }\r
+\r
+  Str = MapIntegerToString (Selector->NextLayerProtocol, mMapIpProtocol);\r
+  if (Str != NULL) {\r
+    Print (L" %s", Str);\r
+  } else {\r
+    Print (L" proto:%d", (UINTN) Selector->NextLayerProtocol);\r
+  }\r
+\r
+  if ((Selector->NextLayerProtocol == EFI_IP4_PROTO_TCP) || (Selector->NextLayerProtocol == EFI_IP4_PROTO_UDP)) {\r
+    Print (L" port:");\r
+    if (Selector->LocalPort != EFI_IPSEC_ANY_PORT) {\r
+      Print (L"%d", Selector->LocalPort);\r
+      if (Selector->LocalPortRange != 0) {\r
+        Print (L"~%d", (UINTN) Selector->LocalPort + Selector->LocalPortRange);\r
+      }\r
+    } else {\r
+      Print (L"any");\r
+    }\r
+\r
+    Print (L" -> ");\r
+    if (Selector->RemotePort != EFI_IPSEC_ANY_PORT) {\r
+      Print (L"%d", Selector->RemotePort);\r
+      if (Selector->RemotePortRange != 0) {\r
+        Print (L"~%d", (UINTN) Selector->RemotePort + Selector->RemotePortRange);\r
+      }\r
+    } else {\r
+      Print (L"any");\r
+    }\r
+  } else if (Selector->NextLayerProtocol == EFI_IP4_PROTO_ICMP) {\r
+    Print (L" class/code:");\r
+    if (Selector->LocalPort != 0) {\r
+      Print (L"%d", (UINTN) (UINT8) Selector->LocalPort);\r
+    } else {\r
+      Print (L"any");\r
+    }\r
+\r
+    Print (L"/");\r
+    if (Selector->RemotePort != 0) {\r
+      Print (L"%d", (UINTN) (UINT8) Selector->RemotePort);\r
+    } else {\r
+      Print (L"any");\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Print EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA content.\r
+\r
+  @param[in] Selector      The pointer to the EFI_IPSEC_SPD_SELECTOR structure.\r
+  @param[in] Data          The pointer to the EFI_IPSEC_SPD_DATA structure.\r
+  @param[in] EntryIndex    The pointer to the Index in SPD Database.\r
+\r
+  @retval EFI_SUCCESS    Dump SPD information successfully.\r
+**/\r
+EFI_STATUS\r
+DumpSpdEntry (\r
+  IN EFI_IPSEC_SPD_SELECTOR    *Selector,\r
+  IN EFI_IPSEC_SPD_DATA        *Data,\r
+  IN UINTN                     *EntryIndex\r
+  )\r
+{\r
+  BOOLEAN    HasPre;\r
+  CHAR16     DataName[128];\r
+  CHAR16     *String1;\r
+  CHAR16     *String2;\r
+  CHAR16     *String3;\r
+  UINT8      Index;\r
+\r
+  Print (L"%d.", (*EntryIndex)++);\r
+\r
+  //\r
+  // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400\r
+  // Protect  PF:0x34323423 Name:First Entry\r
+  // ext-sequence sequence-overflow fragcheck life:[B0,S1024,H3600]\r
+  // ESP algo1 algo2 Tunnel [xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx set]\r
+  //\r
+\r
+  DumpSpdSelector (Selector);\r
+  Print (L"\n  ");\r
+\r
+  Print (L"%s ", MapIntegerToString (Data->Action, mMapIpSecAction));\r
+  Print (L"PF:%08x ", Data->PackageFlag);\r
+\r
+  Index = 0;\r
+  while (Data->Name[Index] != 0) {\r
+    DataName[Index] = (CHAR16) Data->Name[Index];\r
+    Index++;\r
+    ASSERT (Index < 128);\r
+  }\r
+  DataName[Index] = L'\0';\r
+\r
+  Print (L"Name:%s", DataName);\r
+\r
+  if (Data->Action == EfiIPsecActionProtect) {\r
+    Print (L"\n  ");\r
+    if (Data->ProcessingPolicy->ExtSeqNum) {\r
+      Print (L"ext-sequence ");\r
+    }\r
+\r
+    if (Data->ProcessingPolicy->SeqOverflow) {\r
+      Print (L"sequence-overflow ");\r
+    }\r
+\r
+    if (Data->ProcessingPolicy->FragCheck) {\r
+      Print (L"fragment-check ");\r
+    }\r
+\r
+    HasPre = FALSE;\r
+    if (Data->ProcessingPolicy->SaLifetime.ByteCount != 0) {\r
+      Print (HasPre ? L"," : L"life:[");\r
+      Print (L"%lxB", Data->ProcessingPolicy->SaLifetime.ByteCount);\r
+      HasPre = TRUE;\r
+    }\r
+\r
+    if (Data->ProcessingPolicy->SaLifetime.SoftLifetime != 0) {\r
+      Print (HasPre ? L"," : L"life:[");\r
+      Print (L"%lxs", Data->ProcessingPolicy->SaLifetime.SoftLifetime);\r
+      HasPre = TRUE;\r
+    }\r
+\r
+    if (Data->ProcessingPolicy->SaLifetime.HardLifetime != 0) {\r
+      Print (HasPre ? L"," : L"life:[");\r
+      Print (L"%lxS", Data->ProcessingPolicy->SaLifetime.HardLifetime);\r
+      HasPre = TRUE;\r
+    }\r
+\r
+    if (HasPre) {\r
+      Print (L"]");\r
+    }\r
+\r
+    if (HasPre || Data->ProcessingPolicy->ExtSeqNum ||\r
+        Data->ProcessingPolicy->SeqOverflow || Data->ProcessingPolicy->FragCheck) {\r
+      Print (L"\n  ");\r
+    }\r
+\r
+    String1 = MapIntegerToString (Data->ProcessingPolicy->Proto, mMapIpSecProtocol);\r
+    String2 = MapIntegerToString (Data->ProcessingPolicy->AuthAlgoId, mMapAuthAlgo);\r
+    String3 = MapIntegerToString (Data->ProcessingPolicy->EncAlgoId, mMapEncAlgo);\r
+    Print (\r
+      L"%s Auth:%s Encrypt:%s ",\r
+      String1,\r
+      String2,\r
+      String3\r
+      );\r
+\r
+    Print (L"%s ", MapIntegerToString (Data->ProcessingPolicy->Mode, mMapIpSecMode));\r
+    if (Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {\r
+      Print (L"[");\r
+      DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress);\r
+      Print (L" -> ");\r
+      DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress);\r
+      Print (L" %s]", MapIntegerToString (Data->ProcessingPolicy->TunnelOption->DF, mMapDfOption));\r
+    }\r
+  }\r
+\r
+  Print (L"\n");\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Print EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA content.\r
+\r
+  @param[in] SaId          The pointer to the EFI_IPSEC_SA_ID structure.\r
+  @param[in] Data          The pointer to the EFI_IPSEC_SA_DATA structure.\r
+  @param[in] EntryIndex    The pointer to the Index in the SAD Database.\r
+\r
+  @retval EFI_SUCCESS    Dump SAD information successfully.\r
+**/\r
+EFI_STATUS\r
+DumpSadEntry (\r
+  IN EFI_IPSEC_SA_ID      *SaId,\r
+  IN EFI_IPSEC_SA_DATA    *Data,\r
+  IN UINTN                *EntryIndex\r
+  )\r
+{\r
+  BOOLEAN    HasPre;\r
+  CHAR16     *String1;\r
+  CHAR16     *String2;\r
+\r
+  //\r
+  // SPI:1234 ESP Destination:xxx.xxx.xxx.xxx\r
+  //  Mode:Transport SeqNum:134 AntiReplayWin:64 life:[0B,1023s,3400S] PathMTU:34\r
+  //  Auth:xxxx/password Encrypt:yyyy/password\r
+  //  xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400\r
+  //\r
+\r
+  Print (L"%d.", (*EntryIndex)++);\r
+  Print (L"0x%x %s ", (UINTN) SaId->Spi, MapIntegerToString (SaId->Proto, mMapIpSecProtocol));\r
+  Print (L"Destination:");\r
+  DumpIpAddress (&SaId->DestAddress);\r
+  Print (L"\n");\r
+\r
+  Print (\r
+    L"  Mode:%s SeqNum:%lx AntiReplayWin:%d ",\r
+    MapIntegerToString (Data->Mode, mMapIpSecMode),\r
+    Data->SNCount,\r
+    (UINTN) Data->AntiReplayWindows\r
+    );\r
+\r
+  HasPre = FALSE;\r
+  if (Data->SaLifetime.ByteCount != 0) {\r
+    Print (HasPre ? L"," : L"life:[");\r
+    Print (L"%lxB", Data->SaLifetime.ByteCount);\r
+    HasPre = TRUE;\r
+  }\r
+\r
+  if (Data->SaLifetime.SoftLifetime != 0) {\r
+    Print (HasPre ? L"," : L"life:[");\r
+    Print (L"%lxs", Data->SaLifetime.SoftLifetime);\r
+    HasPre = TRUE;\r
+  }\r
+\r
+  if (Data->SaLifetime.HardLifetime != 0) {\r
+    Print (HasPre ? L"," : L"life:[");\r
+    Print (L"%lxS", Data->SaLifetime.HardLifetime);\r
+    HasPre = TRUE;\r
+  }\r
+\r
+  if (HasPre) {\r
+    Print (L"] ");\r
+  }\r
+\r
+  Print (L"PathMTU:%d\n", (UINTN) Data->PathMTU);\r
+\r
+  if (SaId->Proto == EfiIPsecAH) {\r
+    Print (\r
+      L"  Auth:%s/%s\n",\r
+      MapIntegerToString (Data->AlgoInfo.AhAlgoInfo.AuthAlgoId, mMapAuthAlgo),\r
+      Data->AlgoInfo.AhAlgoInfo.AuthKey\r
+      );\r
+  } else {\r
+    String1 = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.AuthAlgoId, mMapAuthAlgo);\r
+    String2 = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.EncAlgoId, mMapEncAlgo);\r
+    Print (\r
+      L"  Auth:%s/%s Encrypt:%s/%s\n",\r
+      String1,\r
+      Data->AlgoInfo.EspAlgoInfo.AuthKey,\r
+      String2,\r
+      Data->AlgoInfo.EspAlgoInfo.EncKey\r
+      );\r
+  }\r
+\r
+  if (Data->SpdSelector != NULL) {\r
+    Print (L"  ");\r
+    DumpSpdSelector (Data->SpdSelector);\r
+    Print (L"\n");\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Print EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA content.\r
+\r
+  @param[in] PadId         The pointer to the EFI_IPSEC_PAD_ID structure.\r
+  @param[in] Data          The pointer to the EFI_IPSEC_PAD_DATA structure.\r
+  @param[in] EntryIndex    The pointer to the Index in the PAD Database.\r
+\r
+  @retval EFI_SUCCESS    Dump PAD information successfully.\r
+**/\r
+EFI_STATUS\r
+DumpPadEntry (\r
+  IN EFI_IPSEC_PAD_ID      *PadId,\r
+  IN EFI_IPSEC_PAD_DATA    *Data,\r
+  IN UINTN                 *EntryIndex\r
+  )\r
+{\r
+  CHAR16    *String1;\r
+  CHAR16    *String2;\r
+\r
+  //\r
+  // ADDR:10.23.17.34/15\r
+  // IDEv1 PreSharedSecret IKE-ID\r
+  // password\r
+  //\r
+\r
+  Print (L"%d.", (*EntryIndex)++);\r
+\r
+  if (PadId->PeerIdValid) {\r
+    Print (L"ID:%s", PadId->Id.PeerId);\r
+  } else {\r
+    Print (L"ADDR:");\r
+    DumpAddressInfo (&PadId->Id.IpAddress);\r
+  }\r
+\r
+  Print (L"\n");\r
+\r
+  String1 = MapIntegerToString (Data->AuthProtocol, mMapAuthProto);\r
+  String2 = MapIntegerToString (Data->AuthMethod, mMapAuthMethod);\r
+  Print (\r
+    L"  %s %s",\r
+    String1,\r
+    String2\r
+    );\r
+\r
+  if (Data->IkeIdFlag) {\r
+    Print (L"IKE-ID");\r
+  }\r
+\r
+  Print (L"\n");\r
+\r
+  if (Data->AuthData != NULL) {\r
+    DumpAsciiString (Data->AuthData, Data->AuthDataSize);\r
+    Print (L"\n");\r
+  }\r
+\r
+  if (Data->RevocationData != NULL) {\r
+    Print (L"  %s\n", Data->RevocationData);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+\r
+}\r
+\r
+VISIT_POLICY_ENTRY  mDumpPolicyEntry[] = {\r
+  (VISIT_POLICY_ENTRY) DumpSpdEntry,\r
+  (VISIT_POLICY_ENTRY) DumpSadEntry,\r
+  (VISIT_POLICY_ENTRY) DumpPadEntry\r
+};\r
+\r
+/**\r
+  Print all entry information in the database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS    Dump all information successfully.\r
+  @retval Others         Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+ListPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  )\r
+{\r
+  UINTN  EntryIndex;\r
+\r
+  EntryIndex = 0;\r
+  return ForeachPolicyEntry (DataType, mDumpPolicyEntry[DataType], &EntryIndex);\r
+}\r
+\r
diff --git a/NetworkPkg/Application/IpsecConfig/Dump.h b/NetworkPkg/Application/IpsecConfig/Dump.h
new file mode 100644 (file)
index 0000000..3c475dd
--- /dev/null
@@ -0,0 +1,34 @@
+/** @file\r
+  The function declaration of dump policy entry function in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _DUMP_H_\r
+#define _DUMP_H_\r
+\r
+/**\r
+  Print all entry information in the database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS    Dump all information successfully.\r
+  @retval Others         Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+ListPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  );\r
+\r
+#endif\r
diff --git a/NetworkPkg/Application/IpsecConfig/ForEach.c b/NetworkPkg/Application/IpsecConfig/ForEach.c
new file mode 100644 (file)
index 0000000..7b3b9b1
--- /dev/null
@@ -0,0 +1,115 @@
+/** @file\r
+  The implementation to go through each entry in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 "IpSecConfig.h"\r
+#include "ForEach.h"\r
+\r
+\r
+/**\r
+  Enumerate all entries in the database to execute specified operations according to datatype.\r
+\r
+  @param[in] DataType    The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] Routine     The pointer to the function of a specified operation.\r
+  @param[in] Context     The pointer to the context of a function.\r
+\r
+  @retval EFI_SUCCESS    Execute specified operation successfully.\r
+**/\r
+EFI_STATUS\r
+ForeachPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN VISIT_POLICY_ENTRY            Routine,\r
+  IN VOID                          *Context\r
+  )\r
+{\r
+  EFI_STATUS                   GetNextStatus;\r
+  EFI_STATUS                   GetDataStatus;\r
+  EFI_IPSEC_CONFIG_SELECTOR    *Selector;\r
+  VOID                         *Data;\r
+  UINTN                        SelectorSize;\r
+  UINTN                        DataSize;\r
+  BOOLEAN                      FirstGetNext;\r
+\r
+  FirstGetNext = TRUE;\r
+  SelectorSize = sizeof (EFI_IPSEC_CONFIG_SELECTOR);\r
+  Selector     = AllocateZeroPool (SelectorSize);\r
+\r
+  DataSize     = 0;\r
+  Data         = NULL;\r
+\r
+  while (TRUE) {\r
+    GetNextStatus = mIpSecConfig->GetNextSelector (\r
+                                    mIpSecConfig,\r
+                                    DataType,\r
+                                    &SelectorSize,\r
+                                    Selector\r
+                                    );\r
+    if (GetNextStatus == EFI_BUFFER_TOO_SMALL) {\r
+      gBS->FreePool (Selector);\r
+      Selector = FirstGetNext ? AllocateZeroPool (SelectorSize) : AllocatePool (SelectorSize);\r
+\r
+      GetNextStatus = mIpSecConfig->GetNextSelector (\r
+                                      mIpSecConfig,\r
+                                      DataType,\r
+                                      &SelectorSize,\r
+                                      Selector\r
+                                      );\r
+    }\r
+\r
+    if (EFI_ERROR (GetNextStatus)) {\r
+      break;\r
+    }\r
+\r
+    FirstGetNext = FALSE;\r
+\r
+    GetDataStatus = mIpSecConfig->GetData (\r
+                                    mIpSecConfig,\r
+                                    DataType,\r
+                                    Selector,\r
+                                    &DataSize,\r
+                                    Data\r
+                                    );\r
+    if (GetDataStatus == EFI_BUFFER_TOO_SMALL) {\r
+      if (Data != NULL) {\r
+        gBS->FreePool (Data);\r
+      }\r
+\r
+      Data = AllocateZeroPool (DataSize);\r
+      GetDataStatus = mIpSecConfig->GetData (\r
+                                      mIpSecConfig,\r
+                                      DataType,\r
+                                      Selector,\r
+                                      &DataSize,\r
+                                      Data\r
+                                      );\r
+    }\r
+\r
+    ASSERT_EFI_ERROR (GetDataStatus);\r
+\r
+    if (EFI_ERROR (Routine (Selector, Data, Context))) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Data != NULL) {\r
+    gBS->FreePool (Data);\r
+  }\r
+\r
+  if (Selector != NULL) {\r
+    gBS->FreePool (Selector);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/NetworkPkg/Application/IpsecConfig/ForEach.h b/NetworkPkg/Application/IpsecConfig/ForEach.h
new file mode 100644 (file)
index 0000000..fc30930
--- /dev/null
@@ -0,0 +1,54 @@
+/** @file\r
+  The internal structure and function declaration of the implementation\r
+  to go through each entry in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _FOREACH_H_\r
+#define _FOREACH_H_\r
+\r
+/**\r
+  The prototype for the DumpSpdEntry()/DumpSadEntry()/DumpPadEntry().\r
+  Print EFI_IPSEC_CONFIG_SELECTOR and corresponding content.\r
+\r
+  @param[in] Selector    The pointer to the EFI_IPSEC_CONFIG_SELECTOR union.\r
+  @param[in] Data        The pointer to the corresponding data.\r
+  @param[in] Context     The pointer to the Index in SPD/SAD/PAD Database.\r
+\r
+  @retval EFI_SUCCESS    Dump SPD/SAD/PAD information successfully.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(*VISIT_POLICY_ENTRY) (\r
+  IN EFI_IPSEC_CONFIG_SELECTOR    *Selector,\r
+  IN VOID                         *Data,\r
+  IN VOID                         *Context\r
+  );\r
+\r
+/**\r
+  Enumerate all entry in the database to execute a specified operation according to datatype.\r
+\r
+  @param[in] DataType    The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] Routine     The pointer to function of a specified operation.\r
+  @param[in] Context     The pointer to the context of a function.\r
+\r
+  @retval EFI_SUCCESS    Execute specified operation successfully.\r
+**/\r
+EFI_STATUS\r
+ForeachPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN VISIT_POLICY_ENTRY            Routine,\r
+  IN VOID                          *Context\r
+  );\r
+\r
+#endif\r
diff --git a/NetworkPkg/Application/IpsecConfig/Helper.c b/NetworkPkg/Application/IpsecConfig/Helper.c
new file mode 100644 (file)
index 0000000..5013ad9
--- /dev/null
@@ -0,0 +1,419 @@
+/** @file\r
+  The assistant function implementation for IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 "IpSecConfig.h"\r
+#include "Helper.h"\r
+\r
+/**\r
+  Helper function called to change an input parameter in the string format to a number.\r
+\r
+  @param[in]      FlagStr         The pointer to the flag string.\r
+  @param[in]      Maximum         Greatest value number.\r
+  @param[in, out] ValuePtr        The pointer to the input parameter in string format.\r
+  @param[in]      ByteCount       The valid byte count\r
+  @param[in]      Map             The pointer to the STR2INT table.\r
+  @param[in]      ParamPackage    The pointer to the ParamPackage list.\r
+  @param[in]      FormatMask      The bit mask.\r
+                                  BIT 0 set indicates the value of a flag might be a number.\r
+                                  BIT 1 set indicates the value of a flag might be a string that needs to be looked up.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_NOT_FOUND            The input parameter can't be found.\r
+  @retval EFI_INVALID_PARAMETER    The input parameter is an invalid input.\r
+**/\r
+EFI_STATUS\r
+GetNumber (\r
+  IN     CHAR16        *FlagStr,\r
+  IN     UINT64        Maximum,\r
+  IN OUT VOID          *ValuePtr,\r
+  IN     UINTN         ByteCount,\r
+  IN     STR2INT       *Map,\r
+  IN     LIST_ENTRY    *ParamPackage,\r
+  IN     UINT32        FormatMask\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  UINT64          Value64;\r
+  BOOLEAN         Converted;\r
+  UINTN           Index;\r
+  CONST CHAR16    *ValueStr;\r
+\r
+  ASSERT (FormatMask & (FORMAT_NUMBER | FORMAT_STRING));\r
+\r
+  Converted = FALSE;\r
+  Value64   = 0;\r
+  ValueStr  = ShellCommandLineGetValue (ParamPackage, FlagStr);\r
+\r
+  if (ValueStr == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  } else {\r
+    //\r
+    // Try to convert to integer directly if MaybeNumber is TRUE.\r
+    //\r
+    if ((FormatMask & FORMAT_NUMBER) != 0) {\r
+      Value64 = StrToUInteger (ValueStr, &Status);\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Convert successfully.\r
+        //\r
+        if (Value64 > Maximum) {\r
+          //\r
+          // But the result is invalid\r
+          //\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+            mHiiHandle,\r
+            mAppName,\r
+            FlagStr,\r
+            ValueStr\r
+            );\r
+          return EFI_INVALID_PARAMETER;\r
+        }\r
+\r
+        Converted = TRUE;\r
+      }\r
+    }\r
+\r
+    if (!Converted && ((FormatMask & FORMAT_STRING) != 0)) {\r
+      //\r
+      // Convert falied, so use String->Integer map.\r
+      //\r
+      Value64 = MapStringToInteger (ValueStr, Map);\r
+      if (Value64 == (UINT32) -1) {\r
+        //\r
+        // Cannot find the string in the map.\r
+        //\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+          mHiiHandle,\r
+          mAppName,\r
+          FlagStr,\r
+          ValueStr\r
+          );\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ACCEPT_PARAMETERS), mHiiHandle);\r
+        for (Index = 0; Map[Index].String != NULL; Index++) {\r
+          Print (L" %s", Map[Index].String);\r
+        }\r
+\r
+        Print (L"\n");\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+\r
+    CopyMem (ValuePtr, &Value64, ByteCount);\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
+/**\r
+  Helper function called to convert a string containing an Ipv4 or Ipv6 Internet Protocol address\r
+  into a proper address for the EFI_IP_ADDRESS structure.\r
+\r
+  @param[in]  Ptr    The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.\r
+  @param[out] Ip     The pointer to the EFI_IP_ADDRESS structure to contain the result.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EfiInetAddr2 (\r
+  IN  CHAR16            *Ptr,\r
+  OUT EFI_IP_ADDRESS    *Ip\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  if ((Ptr == NULL) || (Ip == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Parse the input address as Ipv4 Address first.\r
+  //\r
+  Status = NetLibStrToIp4 (Ptr, &Ip->v4);\r
+  if (!EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = NetLibStrToIp6 (Ptr, &Ip->v6);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Helper function called to calculate the prefix length associated with the string\r
+  containing an Ipv4 or Ipv6 Internet Protocol address.\r
+\r
+  @param[in]  Ptr     The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.\r
+  @param[out] Addr    The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid parameter.\r
+  @retval Others                   Other mistake case.\r
+**/\r
+EFI_STATUS\r
+EfiInetAddrRange (\r
+  IN  CHAR16                 *Ptr,\r
+  OUT EFI_IP_ADDRESS_INFO    *Addr\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  if ((Ptr == NULL) || (Addr == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = NetLibStrToIp4 (Ptr, &Addr->Address.v4);\r
+  if (!EFI_ERROR (Status)) {\r
+    if ((UINT32)(*Addr->Address.v4.Addr) == 0) {\r
+      Addr->PrefixLength = 0;\r
+    } else {\r
+      Addr->PrefixLength = 32;\r
+    }\r
+    return Status;\r
+  }\r
+\r
+  Status = NetLibStrToIp6andPrefix (Ptr, &Addr->Address.v6, &Addr->PrefixLength);\r
+  if (!EFI_ERROR (Status) && (Addr->PrefixLength == 0xFF)) {\r
+    Addr->PrefixLength = 128;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Helper function called to calculate the port range associated with the string.\r
+\r
+  @param[in]  Ptr          The pointer to the string containing a port and range.\r
+  @param[out] Port         The pointer to the Port to contain the result.\r
+  @param[out] PortRange    The pointer to the PortRange to contain the result.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid parameter.\r
+  @retval Others                   Other mistake case.\r
+**/\r
+EFI_STATUS\r
+EfiInetPortRange (\r
+  IN  CHAR16    *Ptr,\r
+  OUT UINT16    *Port,\r
+  OUT UINT16    *PortRange\r
+  )\r
+{\r
+  CHAR16        *BreakPtr;\r
+  CHAR16        Ch;\r
+  EFI_STATUS    Status;\r
+\r
+  for (BreakPtr = Ptr; (*BreakPtr != L'\0') && (*BreakPtr != L':'); BreakPtr++) {\r
+    ;\r
+  }\r
+\r
+  Ch        = *BreakPtr;\r
+  *BreakPtr = L'\0';\r
+  *Port     = (UINT16) StrToUInteger (Ptr, &Status);\r
+  *BreakPtr = Ch;\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *PortRange = 0;\r
+  if (*BreakPtr == L':') {\r
+    BreakPtr++;\r
+    *PortRange = (UINT16) StrToUInteger (BreakPtr, &Status);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    if (*PortRange < *Port) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    *PortRange = (UINT16) (*PortRange - *Port);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Helper function called to transfer a string to an unsigned integer.\r
+\r
+  @param[in]  Str       The pointer to the string.\r
+  @param[out] Status    The operation status.\r
+\r
+  @return The integer value of converted Str.\r
+**/\r
+UINT64\r
+StrToUInteger (\r
+  IN  CONST CHAR16    *Str,\r
+  OUT EFI_STATUS      *Status\r
+  )\r
+{\r
+  UINT64    Value;\r
+  UINT64    NewValue;\r
+  CHAR16    *StrTail;\r
+  CHAR16    Char;\r
+  UINTN     Base;\r
+  UINTN     Len;\r
+\r
+  Base    = 10;\r
+  Value   = 0;\r
+  *Status = EFI_ABORTED;\r
+\r
+  //\r
+  // Skip leading white space.\r
+  //\r
+  while ((*Str != 0) && (*Str == ' ')) {\r
+    Str++;\r
+  }\r
+  //\r
+  // For NULL Str, just return.\r
+  //\r
+  if (*Str == 0) {\r
+    return 0;\r
+  }\r
+  //\r
+  // Skip white space in tail.\r
+  //\r
+  Len     = StrLen (Str);\r
+  StrTail = (CHAR16 *) (Str + Len - 1);\r
+  while (*StrTail == ' ') {\r
+    *StrTail = 0;\r
+    StrTail--;\r
+  }\r
+\r
+  Len = StrTail - Str + 1;\r
+\r
+  //\r
+  // Check hex prefix '0x'.\r
+  //\r
+  if ((Len >= 2) && (*Str == '0') && ((*(Str + 1) == 'x') || (*(Str + 1) == 'X'))) {\r
+    Str += 2;\r
+    Len -= 2;\r
+    Base = 16;\r
+  }\r
+\r
+  if (Len == 0) {\r
+    return 0;\r
+  }\r
+  //\r
+  // Convert the string to value.\r
+  //\r
+  for (; Str <= StrTail; Str++) {\r
+\r
+    Char = *Str;\r
+\r
+    if (Base == 16) {\r
+      if (RShiftU64 (Value, 60) != 0) {\r
+        //\r
+        // Overflow here x16.\r
+        //\r
+        return 0;\r
+      }\r
+\r
+      NewValue = LShiftU64 (Value, 4);\r
+    } else {\r
+      if (RShiftU64 (Value, 61) != 0) {\r
+        //\r
+        // Overflow here x8.\r
+        //\r
+        return 0;\r
+      }\r
+\r
+      NewValue  = LShiftU64 (Value, 3);\r
+      Value     = LShiftU64 (Value, 1);\r
+      NewValue += Value;\r
+      if (NewValue < Value) {\r
+        //\r
+        // Overflow here.\r
+        //\r
+        return 0;\r
+      }\r
+    }\r
+\r
+    Value = NewValue;\r
+\r
+    if ((Base == 16) && (Char >= 'a') && (Char <= 'f')) {\r
+      Char = (CHAR16) (Char - 'a' + 'A');\r
+    }\r
+\r
+    if ((Base == 16) && (Char >= 'A') && (Char <= 'F')) {\r
+      Value += (Char - 'A') + 10;\r
+    } else if ((Char >= '0') && (Char <= '9')) {\r
+      Value += (Char - '0');\r
+    } else {\r
+      //\r
+      // Unexpected Char encountered.\r
+      //\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  *Status = EFI_SUCCESS;\r
+  return Value;\r
+}\r
+\r
+/**\r
+  Helper function called to transfer a string to an unsigned integer according to the map table.\r
+\r
+  @param[in] Str    The pointer to the string.\r
+  @param[in] Map    The pointer to the map table.\r
+\r
+  @return The integer value of converted Str. If not found, then return -1.\r
+**/\r
+UINT32\r
+MapStringToInteger (\r
+  IN CONST CHAR16    *Str,\r
+  IN STR2INT         *Map\r
+  )\r
+{\r
+  STR2INT       *Item;\r
+\r
+  for (Item = Map; Item->String != NULL; Item++) {\r
+    if (StrCmp (Item->String, Str) == 0) {\r
+      return Item->Integer;\r
+    }\r
+  }\r
+\r
+  return (UINT32) -1;\r
+}\r
+\r
+/**\r
+  Helper function called to transfer an unsigned integer to a string according to the map table.\r
+\r
+  @param[in] Integer    The pointer to the string.\r
+  @param[in] Map        The pointer to the map table.\r
+\r
+  @return The converted Str. If not found, then return NULL.\r
+**/\r
+CHAR16 *\r
+MapIntegerToString (\r
+  IN UINT32     Integer,\r
+  IN STR2INT    *Map\r
+  )\r
+{\r
+  STR2INT    *Item;\r
+\r
+  for (Item = Map; Item->String != NULL; Item++) {\r
+    if (Integer == Item->Integer) {\r
+      return Item->String;\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
diff --git a/NetworkPkg/Application/IpsecConfig/Helper.h b/NetworkPkg/Application/IpsecConfig/Helper.h
new file mode 100644 (file)
index 0000000..d893145
--- /dev/null
@@ -0,0 +1,143 @@
+/** @file\r
+  The assistant function declaration for IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _HELPER_H_\r
+#define _HELPER_H_\r
+\r
+#define  FORMAT_NUMBER 0x1\r
+#define  FORMAT_STRING 0x2\r
+\r
+/**\r
+  Helper function called to change input parameter in string format to number.\r
+\r
+  @param[in]      FlagStr         The pointer to the flag string.\r
+  @param[in]      Maximum         most value number.\r
+  @param[in, out] ValuePtr        The pointer to the input parameter in string format.\r
+  @param[in]      ByteCount       The valid byte count\r
+  @param[in]      Map             The pointer to the STR2INT table.\r
+  @param[in]      ParamPackage    The pointer to the ParamPackage list.\r
+  @param[in]      FormatMask      The bit mask.\r
+                                  BIT 0 set indicates the value of flag might be number.\r
+                                  BIT 1 set indicates the value of flag might be a string that needs to be looked up.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_NOT_FOUND            The input parameter can't be found.\r
+  @retval EFI_INVALID_PARAMETER    The input parameter is an invalid input.\r
+**/\r
+EFI_STATUS\r
+GetNumber (\r
+  IN     CHAR16        *FlagStr,\r
+  IN     UINT64        Maximum,\r
+  IN OUT VOID          *ValuePtr,\r
+  IN     UINTN         ByteCount,\r
+  IN     STR2INT       *Map,\r
+  IN     LIST_ENTRY    *ParamPackage,\r
+  IN     UINT32        FormatMask\r
+  );\r
+\r
+/**\r
+  Helper function called to convert a string containing an (Ipv4) Internet Protocol dotted address\r
+  into a proper address for the EFI_IP_ADDRESS structure.\r
+\r
+  @param[in]  Ptr    The pointer to the string containing an (Ipv4) Internet Protocol dotted address.\r
+  @param[out] Ip     The pointer to the Ip address structure to contain the result.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid parameter.\r
+**/\r
+EFI_STATUS\r
+EfiInetAddr2 (\r
+  IN  CHAR16            *Ptr,\r
+  OUT EFI_IP_ADDRESS    *Ip\r
+  );\r
+\r
+/**\r
+  Helper function called to calculate the prefix length associated with the string\r
+  containing an Ipv4 or Ipv6 Internet Protocol address.\r
+\r
+  @param[in]  Ptr     The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.\r
+  @param[out] Addr    The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid parameter.\r
+  @retval Others                   Other mistake case.\r
+**/\r
+EFI_STATUS\r
+EfiInetAddrRange (\r
+  IN  CHAR16                 *Ptr,\r
+  OUT EFI_IP_ADDRESS_INFO    *Addr\r
+  );\r
+\r
+/**\r
+  Helper function called to calculate the port range associated with the string.\r
+\r
+  @param[in]  Ptr          The pointer to the string containing a port and range.\r
+  @param[out] Port         The pointer to the Port to contain the result.\r
+  @param[out] PortRange    The pointer to the PortRange to contain the result.\r
+\r
+  @retval EFI_SUCCESS              The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid parameter.\r
+  @retval Others                   Other mistake case.\r
+**/\r
+EFI_STATUS\r
+EfiInetPortRange (\r
+  IN  CHAR16    *Ptr,\r
+  OUT UINT16    *Port,\r
+  OUT UINT16    *PortRange\r
+  );\r
+\r
+/**\r
+  Helper function called to transfer a string to an unsigned integer.\r
+\r
+  @param[in]  Str       The pointer to the string.\r
+  @param[out] Status    The operation status.\r
+\r
+  @return The integer value of a converted str.\r
+**/\r
+UINT64\r
+StrToUInteger (\r
+  IN  CONST CHAR16    *Str,\r
+  OUT EFI_STATUS      *Status\r
+  );\r
+\r
+/**\r
+  Helper function called to transfer a string to an unsigned integer according to the map table.\r
+\r
+  @param[in] Str    The pointer to the string.\r
+  @param[in] Map    The pointer to the map table.\r
+\r
+  @return The integer value of converted str. If not found, then return -1.\r
+**/\r
+UINT32\r
+MapStringToInteger (\r
+  IN CONST CHAR16    *Str,\r
+  IN STR2INT         *Map\r
+  );\r
+\r
+/**\r
+  Helper function called to transfer an unsigned integer to a string according to the map table.\r
+\r
+  @param[in] Integer    The pointer to the string.\r
+  @param[in] Map        The pointer to the map table.\r
+\r
+  @return The converted str. If not found, then return NULL.\r
+**/\r
+CHAR16 *\r
+MapIntegerToString (\r
+  IN UINT32     Integer,\r
+  IN STR2INT    *Map\r
+  );\r
+\r
+#endif\r
diff --git a/NetworkPkg/Application/IpsecConfig/Indexer.c b/NetworkPkg/Application/IpsecConfig/Indexer.c
new file mode 100644 (file)
index 0000000..1762bbe
--- /dev/null
@@ -0,0 +1,248 @@
+/** @file\r
+  The implementation of construct ENTRY_INDEXER in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 "IpSecConfig.h"\r
+#include "Indexer.h"\r
+#include "Helper.h"\r
+\r
+/**\r
+  Fill in SPD_ENTRY_INDEXER through ParamPackage list.\r
+\r
+  @param[in, out] Indexer         The pointer to the SPD_ENTRY_INDEXER structure.\r
+  @param[in]      ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS    Filled in SPD_ENTRY_INDEXER successfully.\r
+**/\r
+EFI_STATUS\r
+ConstructSpdIndexer (\r
+  IN OUT SPD_ENTRY_INDEXER    *Indexer,\r
+  IN     LIST_ENTRY           *ParamPackage\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  UINT64          Value64;\r
+  CONST CHAR16    *ValueStr;\r
+\r
+  ValueStr = NULL;\r
+\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  ASSERT (ValueStr != NULL);\r
+\r
+  Value64 = StrToUInteger (ValueStr, &Status);\r
+  if (!EFI_ERROR (Status)) {\r
+    Indexer->Index = (UINTN) Value64;\r
+    Indexer->Name  = NULL;\r
+  } else {\r
+    UnicodeStrToAsciiStr (ValueStr, (CHAR8 *) Indexer->Name);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Fill in SAD_ENTRY_INDEXER through ParamPackage list.\r
+\r
+  @param[in, out] Indexer         The pointer to the SAD_ENTRY_INDEXER structure.\r
+  @param[in]      ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS              Filled in SPD_ENTRY_INDEXER successfully.\r
+  @retval EFI_INVALID_PARAMETER    The mistaken user input in ParamPackage list.\r
+**/\r
+EFI_STATUS\r
+ConstructSadIndexer (\r
+  IN OUT SAD_ENTRY_INDEXER    *Indexer,\r
+  IN     LIST_ENTRY           *ParamPackage\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  EFI_STATUS      Status1;\r
+  UINT64          Value64;\r
+  CONST CHAR16    *ValueStr;\r
+\r
+  ValueStr = NULL;\r
+\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  ASSERT (ValueStr != NULL);\r
+\r
+  Value64 = StrToUInteger (ValueStr, &Status);\r
+  if (!EFI_ERROR (Status)) {\r
+    Indexer->Index = (UINTN) Value64;\r
+    ZeroMem (&Indexer->SaId, sizeof (EFI_IPSEC_SA_ID));\r
+  } else {\r
+    if ((!ShellCommandLineGetFlag (ParamPackage, L"--lookup-spi")) ||\r
+        (!ShellCommandLineGetFlag (ParamPackage, L"--lookup-ipsec-proto")) ||\r
+        (!ShellCommandLineGetFlag (ParamPackage, L"--lookup-dest"))) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--lookup-spi --lookup-ipsec-proto --lookup-dest"\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    Status = GetNumber (\r
+              L"--lookup-spi",\r
+              (UINT32) -1,\r
+              &Indexer->SaId.Spi,\r
+              sizeof (UINT32),\r
+              NULL,\r
+              ParamPackage,\r
+              FORMAT_NUMBER\r
+              );\r
+    Status1 = GetNumber (\r
+                L"--lookup-ipsec-proto",\r
+                0,\r
+                &Indexer->SaId.Proto,\r
+                sizeof (EFI_IPSEC_PROTOCOL_TYPE),\r
+                mMapIpSecProtocol,\r
+                ParamPackage,\r
+                FORMAT_STRING\r
+                );\r
+\r
+    if (EFI_ERROR (Status) || EFI_ERROR (Status1)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-dest");\r
+    ASSERT (ValueStr != NULL);\r
+\r
+    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &Indexer->SaId.DestAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--lookup-dest",\r
+        ValueStr\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Fill in PAD_ENTRY_INDEXER through ParamPackage list.\r
+\r
+  @param[in, out] Indexer         The pointer to the PAD_ENTRY_INDEXER structure.\r
+  @param[in]      ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS              Filled in PAD_ENTRY_INDEXER successfully.\r
+  @retval EFI_INVALID_PARAMETER    The mistaken user input in ParamPackage list.\r
+**/\r
+EFI_STATUS\r
+ConstructPadIndexer (\r
+  IN OUT PAD_ENTRY_INDEXER    *Indexer,\r
+  IN     LIST_ENTRY           *ParamPackage\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  UINT64          Value64;\r
+  CONST CHAR16    *ValueStr;\r
+\r
+  ValueStr = NULL;\r
+\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {\r
+    ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  ASSERT (ValueStr != NULL);\r
+\r
+  Value64 = StrToUInteger (ValueStr, &Status);\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    Indexer->Index = (UINTN) Value64;\r
+    ZeroMem (&Indexer->PadId, sizeof (EFI_IPSEC_PAD_ID));\r
+  } else {\r
+\r
+    if (ShellCommandLineGetFlag (ParamPackage, L"--lookup-peer-address")) {\r
+      ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-peer-address");\r
+      ASSERT (ValueStr != NULL);\r
+\r
+      Indexer->PadId.PeerIdValid = FALSE;\r
+      Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &Indexer->PadId.Id.IpAddress);\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+          mHiiHandle,\r
+          mAppName,\r
+          L"--lookup-peer-address",\r
+          ValueStr\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else {\r
+      ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-peer-id");\r
+      if (ValueStr == NULL) {\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+          mHiiHandle,\r
+          mAppName,\r
+          L"--lookup-peer-address --lookup-peer-id"\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      Indexer->PadId.PeerIdValid = TRUE;\r
+      StrnCpy ((CHAR16 *) Indexer->PadId.Id.PeerId, ValueStr, ARRAY_SIZE (Indexer->PadId.Id.PeerId) - 1);\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+CONSTRUCT_POLICY_ENTRY_INDEXER mConstructPolicyEntryIndexer[] = {\r
+  (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructSpdIndexer,\r
+  (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructSadIndexer,\r
+  (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructPadIndexer\r
+};\r
diff --git a/NetworkPkg/Application/IpsecConfig/Indexer.h b/NetworkPkg/Application/IpsecConfig/Indexer.h
new file mode 100644 (file)
index 0000000..078f38a
--- /dev/null
@@ -0,0 +1,58 @@
+/** @file\r
+  The internal structure and function declaration to construct ENTRY_INDEXER in\r
+  IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _INDEXER_H_\r
+#define _INDEXER_H_\r
+\r
+typedef struct {\r
+  UINT8    *Name;\r
+  UINTN    Index;    // Used only if Name is NULL.\r
+} SPD_ENTRY_INDEXER;\r
+\r
+typedef struct {\r
+  EFI_IPSEC_SA_ID    SaId;\r
+  UINTN              Index;\r
+} SAD_ENTRY_INDEXER;\r
+\r
+typedef struct {\r
+  EFI_IPSEC_PAD_ID    PadId;\r
+  UINTN               Index;\r
+} PAD_ENTRY_INDEXER;\r
+\r
+typedef union {\r
+  SPD_ENTRY_INDEXER    Spd;\r
+  SAD_ENTRY_INDEXER    Sad;\r
+  PAD_ENTRY_INDEXER    Pad;\r
+} POLICY_ENTRY_INDEXER;\r
+\r
+/**\r
+  The prototype for the ConstructSpdIndexer()/ConstructSadIndexer()/ConstructPadIndexer().\r
+  Fill in SPD_ENTRY_INDEXER/SAD_ENTRY_INDEXER/PAD_ENTRY_INDEXER through ParamPackage list.\r
+\r
+  @param[in, out] Indexer         The pointer to the POLICY_ENTRY_INDEXER union.\r
+  @param[in]      ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS    Filled in POLICY_ENTRY_INDEXER successfully.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(* CONSTRUCT_POLICY_ENTRY_INDEXER) (\r
+  IN POLICY_ENTRY_INDEXER    *Indexer,\r
+  IN LIST_ENTRY              *ParamPackage\r
+);\r
+\r
+extern CONSTRUCT_POLICY_ENTRY_INDEXER mConstructPolicyEntryIndexer[];\r
+#endif\r
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfig.c b/NetworkPkg/Application/IpsecConfig/IpSecConfig.c
new file mode 100644 (file)
index 0000000..8006d84
--- /dev/null
@@ -0,0 +1,809 @@
+/** @file\r
+  The main process for IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/HiiLib.h>\r
+\r
+#include <Protocol/IpSec.h>\r
+\r
+#include "IpSecConfig.h"\r
+#include "Dump.h"\r
+#include "Indexer.h"\r
+#include "PolicyEntryOperation.h"\r
+#include "Delete.h"\r
+#include "Helper.h"\r
+\r
+//\r
+// Used for ShellCommandLineParseEx only\r
+// and to ensure user inputs are in valid format\r
+//\r
+SHELL_PARAM_ITEM    mIpSecConfigParamList[] = {\r
+  { L"-p",                    TypeValue },\r
+  { L"-a",                    TypeValue },\r
+  { L"-i",                    TypeValue },\r
+  { L"-e",                    TypeValue },\r
+  { L"-d",                    TypeValue },\r
+  { L"-f",                    TypeFlag },\r
+  { L"-l",                    TypeFlag },\r
+  { L"-enable",               TypeFlag },\r
+  { L"-disable",              TypeFlag },\r
+  { L"-status",               TypeFlag },\r
+  { L"-?",                    TypeFlag },\r
+\r
+  //\r
+  // SPD Selector\r
+  //\r
+  { L"--local",               TypeValue },\r
+  { L"--remote",              TypeValue },\r
+  { L"--proto",               TypeValue },\r
+  { L"--local-port",          TypeValue },\r
+  { L"--remote-port",         TypeValue },\r
+  { L"--icmp-type",           TypeValue },\r
+  { L"--icmp-code",           TypeValue },\r
+\r
+  //\r
+  // SPD Data\r
+  //\r
+  { L"--name",                TypeValue },\r
+  { L"--packet-flag",         TypeValue },\r
+  { L"--action",              TypeValue },\r
+  { L"--lifebyte",            TypeValue },\r
+  { L"--lifetime-soft",       TypeValue },\r
+  { L"--lifetime",            TypeValue },\r
+  { L"--mode",                TypeValue },\r
+  { L"--tunnel-local",        TypeValue },\r
+  { L"--tunnel-remote",       TypeValue },\r
+  { L"--dont-fragment",       TypeValue },\r
+  { L"--ipsec-proto",         TypeValue },\r
+  { L"--auth-algo",           TypeValue },\r
+  { L"--encrypt-algo",        TypeValue },\r
+\r
+  { L"--ext-sequence",        TypeFlag  },\r
+  { L"--sequence-overflow",   TypeFlag  },\r
+  { L"--fragment-check",      TypeFlag  },\r
+  { L"--ext-sequence-",       TypeFlag  },\r
+  { L"--sequence-overflow-",  TypeFlag  },\r
+  { L"--fragment-check-",     TypeFlag  },\r
+\r
+  //\r
+  // SA ID\r
+  // --ipsec-proto\r
+  //\r
+  { L"--spi",                 TypeValue },\r
+  { L"--dest",                TypeValue },\r
+  { L"--lookup-spi",          TypeValue },\r
+  { L"--lookup-ipsec-proto",  TypeValue },\r
+  { L"--lookup-dest",         TypeValue },\r
+\r
+  //\r
+  // SA DATA\r
+  // --mode\r
+  // --auth-algo\r
+  // --encrypt-algo\r
+  //\r
+  { L"--sequence-number",     TypeValue },\r
+  { L"--antireplay-window",   TypeValue },\r
+  { L"--auth-key",            TypeValue },\r
+  { L"--encrypt-key",         TypeValue },\r
+  { L"--path-mtu",            TypeValue },\r
+\r
+  //\r
+  // PAD ID\r
+  //\r
+  { L"--peer-id",             TypeValue },\r
+  { L"--peer-address",        TypeValue },\r
+  { L"--auth-proto",          TypeValue },\r
+  { L"--auth-method",         TypeValue },\r
+  { L"--ike-id",              TypeValue },\r
+  { L"--ike-id-",             TypeValue },\r
+  { L"--auth-data",           TypeValue },\r
+  { L"--revocation-data",     TypeValue },\r
+  { L"--lookup-peer-id",      TypeValue },\r
+  { L"--lookup-peer-address", TypeValue },\r
+\r
+  { NULL,                     TypeMax   },\r
+};\r
+\r
+//\r
+// -P\r
+//\r
+STR2INT mMapPolicy[] = {\r
+  { L"SPD",       IPsecConfigDataTypeSpd },\r
+  { L"SAD",       IPsecConfigDataTypeSad },\r
+  { L"PAD",       IPsecConfigDataTypePad },\r
+  { NULL,         0 },\r
+};\r
+\r
+//\r
+// --proto\r
+//\r
+STR2INT mMapIpProtocol[] = {\r
+  { L"TCP",       EFI_IP4_PROTO_TCP },\r
+  { L"UDP",       EFI_IP4_PROTO_UDP },\r
+  { L"ICMP",      EFI_IP4_PROTO_ICMP },\r
+  { NULL,         0 },\r
+};\r
+\r
+//\r
+// --action\r
+//\r
+STR2INT mMapIpSecAction[] = {\r
+  { L"Bypass",    EfiIPsecActionBypass },\r
+  { L"Discard",   EfiIPsecActionDiscard },\r
+  { L"Protect",   EfiIPsecActionProtect },\r
+  { NULL,         0 },\r
+};\r
+\r
+//\r
+// --mode\r
+//\r
+STR2INT mMapIpSecMode[] = {\r
+  { L"Transport", EfiIPsecTransport },\r
+  { L"Tunnel",    EfiIPsecTunnel },\r
+  { NULL,         0 },\r
+};\r
+\r
+//\r
+// --dont-fragment\r
+//\r
+STR2INT mMapDfOption[] = {\r
+  { L"clear",     EfiIPsecTunnelClearDf },\r
+  { L"set",       EfiIPsecTunnelSetDf },\r
+  { L"copy",      EfiIPsecTunnelCopyDf },\r
+  { NULL,         0 },\r
+};\r
+\r
+//\r
+// --ipsec-proto\r
+//\r
+STR2INT mMapIpSecProtocol[] = {\r
+  { L"AH",        EfiIPsecAH },\r
+  { L"ESP",       EfiIPsecESP },\r
+  { NULL,         0 },\r
+};\r
+\r
+//\r
+// --auth-algo\r
+//\r
+STR2INT mMapAuthAlgo[] = {\r
+  { L"NONE",         EFI_IPSEC_AALG_NONE },\r
+  { L"MD5HMAC",      EFI_IPSEC_AALG_MD5HMAC },\r
+  { L"SHA1HMAC",     EFI_IPSEC_AALG_SHA1HMAC },\r
+  { L"SHA2-256HMAC", EFI_IPSEC_AALG_SHA2_256HMAC },\r
+  { L"SHA2-384HMAC", EFI_IPSEC_AALG_SHA2_384HMAC },\r
+  { L"SHA2-512HMAC", EFI_IPSEC_AALG_SHA2_512HMAC },\r
+  { L"AES-XCBC-MAC", EFI_IPSEC_AALG_AES_XCBC_MAC },\r
+  { L"NULL",         EFI_IPSEC_AALG_NULL },\r
+  { NULL,            0 },\r
+};\r
+\r
+//\r
+// --encrypt-algo\r
+//\r
+STR2INT mMapEncAlgo[] = {\r
+  { L"NONE",         EFI_IPSEC_EALG_NONE },\r
+  { L"DESCBC",       EFI_IPSEC_EALG_DESCBC },\r
+  { L"3DESCBC",      EFI_IPSEC_EALG_3DESCBC },\r
+  { L"CASTCBC",      EFI_IPSEC_EALG_CASTCBC },\r
+  { L"BLOWFISHCBC",  EFI_IPSEC_EALG_BLOWFISHCBC },\r
+  { L"NULL",         EFI_IPSEC_EALG_NULL },\r
+  { L"AESCBC",       EFI_IPSEC_EALG_AESCBC },\r
+  { L"AESCTR",       EFI_IPSEC_EALG_AESCTR },\r
+  { L"AES-CCM-ICV8", EFI_IPSEC_EALG_AES_CCM_ICV8 },\r
+  { L"AES-CCM-ICV12",EFI_IPSEC_EALG_AES_CCM_ICV12 },\r
+  { L"AES-CCM-ICV16",EFI_IPSEC_EALG_AES_CCM_ICV16 },\r
+  { L"AES-GCM-ICV8", EFI_IPSEC_EALG_AES_GCM_ICV8 },\r
+  { L"AES-GCM-ICV12",EFI_IPSEC_EALG_AES_GCM_ICV12 },\r
+  { L"AES-GCM-ICV16",EFI_IPSEC_EALG_AES_GCM_ICV16 },\r
+  { NULL,            0 },\r
+};\r
+\r
+//\r
+// --auth-proto\r
+//\r
+STR2INT mMapAuthProto[] = {\r
+  { L"IKEv1",        EfiIPsecAuthProtocolIKEv1 },\r
+  { L"IKEv2",        EfiIPsecAuthProtocolIKEv2 },\r
+  { NULL,            0 },\r
+};\r
+\r
+//\r
+// --auth-method\r
+//\r
+STR2INT mMapAuthMethod[] = {\r
+  { L"PreSharedSecret", EfiIPsecAuthMethodPreSharedSecret },\r
+  { L"Certificates",    EfiIPsecAuthMethodCertificates },\r
+  { NULL,               0 },\r
+};\r
+\r
+EFI_IPSEC_PROTOCOL           *mIpSec;\r
+EFI_IPSEC_CONFIG_PROTOCOL    *mIpSecConfig;\r
+EFI_HII_HANDLE               mHiiHandle;\r
+EFI_GUID                     mEfiIpSecConfigGuid = EFI_IPSEC_CONFIG_GUID;\r
+CHAR16                       mAppName[]          = L"IpSecConfig";\r
+\r
+//\r
+// Used for IpSecConfigRetriveCheckListByName only to check the validation of user input\r
+//\r
+VAR_CHECK_ITEM    mIpSecConfigVarCheckList[] = {\r
+  { L"-enable",              BIT(1)|BIT(0),  BIT(1),  BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-disable",             BIT(1)|BIT(0),  BIT(1),  BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-status",              BIT(1)|BIT(0),  BIT(1),  BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-p",                   BIT(1),         0,       BIT(2)|BIT(1)|BIT(0), 0 },\r
+\r
+  { L"-a",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-i",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-d",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-e",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-l",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },\r
+  { L"-f",                   BIT(0),         0,       BIT(2)|BIT(1)|BIT(0), 0 },\r
+\r
+  { L"-?",                   BIT(0),         BIT(0),  BIT(2)|BIT(1)|BIT(0), 0 },\r
+\r
+  //\r
+  // SPD Selector\r
+  //\r
+  { L"--local",              0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--remote",             0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--proto",              0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--local-port",         0,              0,       BIT(2)|BIT(1),        BIT(0) },\r
+  { L"--remote-port",        0,              0,       BIT(2)|BIT(1),        BIT(0) },\r
+  { L"--icmp-type",          0,              0,       BIT(2)|BIT(1),        BIT(1) },\r
+  { L"--icmp-code",          0,              0,       BIT(2)|BIT(1),        BIT(1) },\r
+\r
+  //\r
+  // SPD Data\r
+  //\r
+  { L"--name",               0,              0,       BIT(2),               0 },\r
+  { L"--packet-flag",        0,              0,       BIT(2),               0 },\r
+  { L"--action",             0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--lifebyte",           0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--lifetime-soft",      0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--lifetime",           0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--mode",               0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--tunnel-local",       0,              0,       BIT(2),               0 },\r
+  { L"--tunnel-remote",      0,              0,       BIT(2),               0 },\r
+  { L"--dont-fragment",      0,              0,       BIT(2),               0 },\r
+  { L"--ipsec-proto",        0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--auth-algo",          0,              0,       BIT(2)|BIT(1),        0 },\r
+  { L"--encrypt-algo",       0,              0,       BIT(2)|BIT(1),        0 },\r
+\r
+  { L"--ext-sequence",       0,              0,       BIT(2),               BIT(2) },\r
+  { L"--sequence-overflow",  0,              0,       BIT(2),               BIT(2) },\r
+  { L"--fragment-check",     0,              0,       BIT(2),               BIT(2) },\r
+  { L"--ext-sequence-",      0,              0,       BIT(2),               BIT(3) },\r
+  { L"--sequence-overflow-", 0,              0,       BIT(2),               BIT(3) },\r
+  { L"--fragment-check-",    0,              0,       BIT(2),               BIT(3) },\r
+\r
+  //\r
+  // SA ID\r
+  // --ipsec-proto\r
+  //\r
+  { L"--spi",                0,              0,       BIT(1),               0 },\r
+  { L"--dest",               0,              0,       BIT(1),               0 },\r
+  { L"--lookup-spi",         0,              0,       BIT(1),               0 },\r
+  { L"--lookup-ipsec-proto", 0,              0,       BIT(1),               0 },\r
+  { L"--lookup-dest",        0,              0,       BIT(1),               0 },\r
+\r
+  //\r
+  // SA DATA\r
+  // --mode\r
+  // --auth-algo\r
+  // --encrypt-algo\r
+  //\r
+  { L"--sequence-number",    0,              0,       BIT(1),               0 },\r
+  { L"--antireplay-window",  0,              0,       BIT(1),               0 },\r
+  { L"--auth-key",           0,              0,       BIT(1),               0 },\r
+  { L"--encrypt-key",        0,              0,       BIT(1),               0 },\r
+  { L"--path-mtu",           0,              0,       BIT(1),               0 },\r
+\r
+  //\r
+  // The example to add a PAD:\r
+  // "-A --peer-id Mike [--peer-address 10.23.2.2] --auth-proto IKE1/IKE2\r
+  //     --auth-method PreSharedSeceret/Certificate --ike-id\r
+  //     --auth-data 343343 --revocation-data 2342432"\r
+  // The example to delete a PAD:\r
+  // "-D * --lookup-peer-id Mike [--lookup-peer-address 10.23.2.2]"\r
+  // "-D 1"\r
+  // The example to edit a PAD:\r
+  // "-E * --lookup-peer-id Mike --auth-method Certificate"\r
+\r
+  //\r
+  // PAD ID\r
+  //\r
+  { L"--peer-id",            0,              0,       BIT(0),               BIT(4) },\r
+  { L"--peer-address",       0,              0,       BIT(0),               BIT(5) },\r
+  { L"--auth-proto",         0,              0,       BIT(0),               0 },\r
+  { L"--auth-method",        0,              0,       BIT(0),               0 },\r
+  { L"--IKE-ID",             0,              0,       BIT(0),               BIT(6) },\r
+  { L"--IKE-ID-",            0,              0,       BIT(0),               BIT(7) },\r
+  { L"--auth-data",          0,              0,       BIT(0),               0 },\r
+  { L"--revocation-data",    0,              0,       BIT(0),               0 },\r
+  { L"--lookup-peer-id",     0,              0,       BIT(0),               BIT(4) },\r
+  { L"--lookup-peer-address",0,              0,       BIT(0),               BIT(5) },\r
+\r
+  { NULL,                    0,              0,       0,                    0 },\r
+};\r
+\r
+/**\r
+  The function to allocate the proper sized buffer for various\r
+  EFI interfaces.\r
+\r
+  @param[in, out] Status        Current status.\r
+  @param[in, out] Buffer        Current allocated buffer, or NULL.\r
+  @param[in]      BufferSize    Current buffer size needed\r
+\r
+  @retval TRUE     If the buffer was reallocated and the caller should try the API again.\r
+  @retval FALSE    If the buffer was not reallocated successfully.\r
+**/\r
+BOOLEAN\r
+GrowBuffer (\r
+  IN OUT EFI_STATUS    *Status,\r
+  IN OUT VOID          **Buffer,\r
+  IN     UINTN         BufferSize\r
+  )\r
+{\r
+  BOOLEAN    TryAgain;\r
+\r
+  ASSERT (Status != NULL);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // If this is an initial request, buffer will be null with a new buffer size.\r
+  //\r
+  if ((NULL == *Buffer) && (BufferSize != 0)) {\r
+    *Status = EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  //\r
+  // If the status code is "buffer too small", resize the buffer.\r
+  //\r
+  TryAgain = FALSE;\r
+  if (*Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+    if (*Buffer != NULL) {\r
+      FreePool (*Buffer);\r
+    }\r
+\r
+    *Buffer = AllocateZeroPool (BufferSize);\r
+\r
+    if (*Buffer != NULL) {\r
+      TryAgain = TRUE;\r
+    } else {\r
+      *Status = EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
+\r
+  //\r
+  // If there's an error, free the buffer.\r
+  //\r
+  if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) {\r
+    FreePool (*Buffer);\r
+    *Buffer = NULL;\r
+  }\r
+\r
+  return TryAgain;\r
+}\r
+\r
+/**\r
+  Function returns an array of handles that support the requested protocol\r
+  in a buffer allocated from a pool.\r
+\r
+  @param[in]      SearchType    Specifies which handle(s) are to be returned.\r
+  @param[in]      Protocol      Provides the protocol to search by.\r
+                                This parameter is only valid for SearchType ByProtocol.\r
+\r
+  @param[in]      SearchKey     Supplies the search key depending on the SearchType.\r
+  @param[in, out] NoHandles     The number of handles returned in Buffer.\r
+  @param[out]     Buffer        A pointer to the buffer to return the requested array of\r
+                                handles that support Protocol.\r
+\r
+  @retval EFI_SUCCESS    The resulting array of handles was returned.\r
+  @retval Others         Other mistake case.\r
+**/\r
+EFI_STATUS\r
+LocateHandle (\r
+  IN     EFI_LOCATE_SEARCH_TYPE    SearchType,\r
+  IN     EFI_GUID                  *Protocol  OPTIONAL,\r
+  IN     VOID                      *SearchKey OPTIONAL,\r
+  IN OUT UINTN                     *NoHandles,\r
+     OUT EFI_HANDLE                **Buffer\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  UINTN         BufferSize;\r
+\r
+  ASSERT (NoHandles != NULL);\r
+  ASSERT (Buffer != NULL);\r
+\r
+  //\r
+  // Initialize for GrowBuffer loop.\r
+  //\r
+  Status      = EFI_SUCCESS;\r
+  *Buffer     = NULL;\r
+  BufferSize  = 50 * sizeof (EFI_HANDLE);\r
+\r
+  //\r
+  // Call the real function.\r
+  //\r
+  while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {\r
+    Status = gBS->LocateHandle (\r
+                    SearchType,\r
+                    Protocol,\r
+                    SearchKey,\r
+                    &BufferSize,\r
+                    *Buffer\r
+                    );\r
+  }\r
+\r
+  *NoHandles = BufferSize / sizeof (EFI_HANDLE);\r
+  if (EFI_ERROR (Status)) {\r
+    *NoHandles = 0;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Find the first instance of this protocol in the system and return its interface.\r
+\r
+  @param[in]  ProtocolGuid    The guid of the protocol.\r
+  @param[out] Interface       The pointer to the first instance of the protocol.\r
+\r
+  @retval EFI_SUCCESS    A protocol instance matching ProtocolGuid was found.\r
+  @retval Others         A protocol instance matching ProtocolGuid was not found.\r
+**/\r
+EFI_STATUS\r
+LocateProtocol (\r
+  IN  EFI_GUID    *ProtocolGuid,\r
+  OUT VOID        **Interface\r
+  )\r
+\r
+{\r
+  EFI_STATUS    Status;\r
+  UINTN         NumberHandles;\r
+  UINTN         Index;\r
+  EFI_HANDLE    *Handles;\r
+\r
+  *Interface    = NULL;\r
+  Handles       = NULL;\r
+  NumberHandles = 0;\r
+\r
+  Status        = LocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO, "LibLocateProtocol: Handle not found\n"));\r
+    return Status;\r
+  }\r
+\r
+  for (Index = 0; Index < NumberHandles; Index++) {\r
+    ASSERT (Handles != NULL);\r
+    Status = gBS->HandleProtocol (\r
+                    Handles[Index],\r
+                    ProtocolGuid,\r
+                    Interface\r
+                    );\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Handles != NULL) {\r
+    FreePool (Handles);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Helper function called to check the conflicted flags.\r
+\r
+  @param[in] CheckList       The pointer to the VAR_CHECK_ITEM table.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS              No conflicted flags.\r
+  @retval EFI_INVALID_PARAMETER    The input parameter is erroroneous or there are some conflicted flags.\r
+**/\r
+EFI_STATUS\r
+IpSecConfigRetriveCheckListByName (\r
+  IN VAR_CHECK_ITEM    *CheckList,\r
+  IN LIST_ENTRY        *ParamPackage\r
+)\r
+{\r
+\r
+  LIST_ENTRY        *Node;\r
+  VAR_CHECK_ITEM    *Item;\r
+  UINT32            Attribute1;\r
+  UINT32            Attribute2;\r
+  UINT32            Attribute3;\r
+  UINT32            Attribute4;\r
+  UINT32            Index;\r
+\r
+  Attribute1 = 0;\r
+  Attribute2 = 0;\r
+  Attribute3 = 0;\r
+  Attribute4 = 0;\r
+  Index      = 0;\r
+  Item       = mIpSecConfigVarCheckList;\r
+\r
+  if ((ParamPackage == NULL) || (CheckList == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Enumerate through the list of parameters that are input by user.\r
+  //\r
+  for (Node = GetFirstNode (ParamPackage); !IsNull (ParamPackage, Node); Node = GetNextNode (ParamPackage, Node)) {\r
+    if (((SHELL_PARAM_PACKAGE *) Node)->Name != NULL) {\r
+      //\r
+         // Enumerate the check list that defines the conflicted attributes of each flag.\r
+      //\r
+      for (; Item->VarName != NULL; Item++) {\r
+        if (StrCmp (((SHELL_PARAM_PACKAGE *) Node)->Name, Item->VarName) == 0) {\r
+          Index++;\r
+          if (Index == 1) {\r
+            Attribute1 = Item->Attribute1;\r
+            Attribute2 = Item->Attribute2;\r
+            Attribute3 = Item->Attribute3;\r
+            Attribute4 = Item->Attribute4;\r
+          } else {\r
+            Attribute1 &= Item->Attribute1;\r
+            Attribute2 |= Item->Attribute2;\r
+            Attribute3 &= Item->Attribute3;\r
+            Attribute4 |= Item->Attribute4;\r
+            if (Attribute1 != 0) {\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+\r
+            if (Attribute2 != 0) {\r
+              if ((Index == 2) && (StrCmp (Item->VarName, L"-p") == 0)) {\r
+                continue;\r
+              }\r
+\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+\r
+            if (Attribute3 == 0) {\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+            if (((Attribute4 & 0xFF) == 0x03) || ((Attribute4 & 0xFF) == 0x0C) ||\r
+                ((Attribute4 & 0xFF) == 0x30) || ((Attribute4 & 0xFF) == 0xC0)) {\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+          }\r
+          break;\r
+        }\r
+      }\r
+\r
+      Item = mIpSecConfigVarCheckList;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This is the declaration of an EFI image entry point. This entry point is\r
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including\r
+  both device drivers and bus drivers.\r
+\r
+  The entry point for IpSecConfig application that parse the command line input and call an IpSecConfig process.\r
+\r
+  @param[in] ImageHandle    The image handle of this application.\r
+  @param[in] SystemTable    The pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS    The operation completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeIpSecConfig (\r
+  IN EFI_HANDLE          ImageHandle,\r
+  IN EFI_SYSTEM_TABLE    *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_IPSEC_CONFIG_DATA_TYPE    DataType;\r
+  UINT8                         Value;\r
+  LIST_ENTRY                    *ParamPackage;\r
+  CONST CHAR16                  *ValueStr;\r
+  CHAR16                        *ProblemParam;\r
+  UINTN                         NonOptionCount;\r
+\r
+  //\r
+  // Register our string package with HII and return the handle to it.\r
+  //\r
+  mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, IpSecConfigStrings, NULL);\r
+  ASSERT (mHiiHandle != NULL);\r
+\r
+  Status = ShellCommandLineParseEx (mIpSecConfigParamList, &ParamPackage, &ProblemParam, TRUE, FALSE);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, ProblemParam);\r
+    goto Done;\r
+  }\r
+\r
+  Status = IpSecConfigRetriveCheckListByName (mIpSecConfigVarCheckList, ParamPackage);\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_MISTAKEN_OPTIONS), mHiiHandle);\r
+    goto Done;\r
+  }\r
+\r
+  Status = LocateProtocol (&gEfiIpSecConfigProtocolGuid, (VOID **) &mIpSecConfig);\r
+  if (EFI_ERROR (Status) || mIpSecConfig == NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);\r
+    goto Done;\r
+  }\r
+\r
+  Status = LocateProtocol (&gEfiIpSecProtocolGuid, (VOID **) &mIpSec);\r
+  if (EFI_ERROR (Status) || mIpSec == NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Enable IPsec.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-enable")) {\r
+    if (!(mIpSec->DisabledFlag)) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_ENABLE), mHiiHandle, mAppName);\r
+    } else {\r
+      //\r
+      // Set enable flag.\r
+      //\r
+      Value  = IPSEC_STATUS_ENABLED;\r
+      Status = gRT->SetVariable (\r
+                      IPSECCONFIG_STATUS_NAME,\r
+                      &gEfiIpSecConfigProtocolGuid,\r
+                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                      sizeof (Value),\r
+                      &Value\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        mIpSec->DisabledFlag = FALSE;\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_SUCCESS), mHiiHandle, mAppName);\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_FAILED), mHiiHandle, mAppName);\r
+      }\r
+    }\r
+\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Disable IPsec.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-disable")) {\r
+    if (mIpSec->DisabledFlag) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_DISABLE), mHiiHandle, mAppName);\r
+    } else {\r
+      //\r
+      // Set disable flag; however, leave it to be disabled in the callback function of DisabledEvent.\r
+      //\r
+      gBS->SignalEvent (mIpSec->DisabledEvent);\r
+      if (mIpSec->DisabledFlag) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_SUCCESS), mHiiHandle, mAppName);\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_FAILED), mHiiHandle, mAppName);\r
+      }\r
+    }\r
+\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  //IPsec Status.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-status")) {\r
+    if (mIpSec->DisabledFlag) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_DISABLE), mHiiHandle, mAppName);\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_ENABLE), mHiiHandle, mAppName);\r
+    }\r
+\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Try to get policy database type.\r
+  //\r
+  DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) -1;\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-p");\r
+  if (ValueStr != NULL) {\r
+    DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) MapStringToInteger (ValueStr, mMapPolicy);\r
+    if (DataType == -1) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_DB), mHiiHandle, mAppName, ValueStr);\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-?")) {\r
+    switch (DataType) {\r
+      case (EFI_IPSEC_CONFIG_DATA_TYPE) -1:\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_HELP), mHiiHandle);\r
+        break;\r
+\r
+      case IPsecConfigDataTypeSpd:\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_SPD_HELP), mHiiHandle);\r
+        break;\r
+\r
+      case IPsecConfigDataTypeSad:\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_SAD_HELP), mHiiHandle);\r
+        break;\r
+\r
+      case IPsecConfigDataTypePad:\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PAD_HELP), mHiiHandle);\r
+        break;\r
+\r
+      default:\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_DB), mHiiHandle);\r
+        break;\r
+    }\r
+\r
+    goto Done;\r
+  }\r
+\r
+  NonOptionCount = ShellCommandLineGetCount ();\r
+  if ((NonOptionCount - 1) > 0) {\r
+    ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32) (NonOptionCount - 1));\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_REDUNDANCY_MANY), mHiiHandle, mAppName, ValueStr);\r
+    goto Done;\r
+  }\r
+\r
+  if (DataType == -1) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_DB), mHiiHandle, mAppName);\r
+    goto Done;\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"-a")) {\r
+    Status = AddOrInsertPolicyEntry (DataType, ParamPackage);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
+    Status = AddOrInsertPolicyEntry (DataType, ParamPackage);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {\r
+    Status = EditPolicyEntry (DataType, ParamPackage);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {\r
+    Status = FlushOrDeletePolicyEntry (DataType, ParamPackage);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-f")) {\r
+    Status = FlushOrDeletePolicyEntry (DataType, ParamPackage);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {\r
+    Status = ListPolicyEntry (DataType, ParamPackage);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+  } else {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, mAppName);\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  ShellCommandLineFreeVarList (ParamPackage);\r
+  HiiRemovePackages (mHiiHandle);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfig.h b/NetworkPkg/Application/IpsecConfig/IpSecConfig.h
new file mode 100644 (file)
index 0000000..d1a7681
--- /dev/null
@@ -0,0 +1,123 @@
+/** @file\r
+  The internal structure and function declaration in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _IPSEC_CONFIG_H_\r
+#define _IPSEC_CONFIG_H_\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/ShellLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/NetLib.h>\r
+\r
+#include <Protocol/IpSecConfig.h>\r
+\r
+#define EFI_IPSEC_CONFIG_GUID \\r
+  { \\r
+    0x9db0c3ac, 0xd9d2, 0x4f96, {0x9e, 0xd7, 0x6d, 0xa6, 0x12, 0xa4, 0xf3, 0x27} \\r
+  }\r
+\r
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))\r
+\r
+#define IPSECCONFIG_STATUS_NAME    L"IpSecStatus"\r
+\r
+#define BIT(x)   (UINT32) (1 << (x))\r
+\r
+#define IPSEC_STATUS_DISABLED    0x0\r
+#define IPSEC_STATUS_ENABLED     0x1\r
+\r
+#define EFI_IP4_PROTO_ICMP       0x1\r
+#define EFI_IP4_PROTO_TCP        0x6\r
+#define EFI_IP4_PROTO_UDP        0x11\r
+\r
+#define EFI_IPSEC_ANY_PROTOCOL    0xFFFF\r
+#define EFI_IPSEC_ANY_PORT        0\r
+\r
+typedef struct _VAR_CHECK_ITEM {\r
+  CHAR16      *VarName;\r
+  UINT32      Attribute1;\r
+  UINT32      Attribute2;\r
+  UINT32      Attribute3;\r
+  UINT32      Attribute4;\r
+} VAR_CHECK_ITEM;\r
+\r
+typedef struct _SHELL_PARAM_PACKAGE{\r
+  LIST_ENTRY     Link;\r
+  CHAR16         *Name;\r
+  ParamType      Type;\r
+  CHAR16         *Value;\r
+  UINTN          OriginalPosition;\r
+} SHELL_PARAM_PACKAGE;\r
+\r
+typedef struct _STR2INT {\r
+  CHAR16        *String;\r
+  UINT32        Integer;\r
+} STR2INT;\r
+\r
+extern EFI_IPSEC_CONFIG_PROTOCOL    *mIpSecConfig;\r
+extern EFI_HII_HANDLE               mHiiHandle;\r
+extern CHAR16                       mAppName[];\r
+\r
+//\r
+// -P\r
+//\r
+extern STR2INT mMapPolicy[];\r
+\r
+//\r
+// --proto\r
+//\r
+extern STR2INT mMapIpProtocol[];\r
+\r
+//\r
+// --action\r
+//\r
+extern STR2INT mMapIpSecAction[];\r
+\r
+//\r
+// --mode\r
+//\r
+extern STR2INT mMapIpSecMode[];\r
+\r
+//\r
+// --dont-fragment\r
+//\r
+extern STR2INT mMapDfOption[];\r
+\r
+//\r
+// --ipsec-proto\r
+//\r
+extern STR2INT mMapIpSecProtocol[];\r
+//\r
+// --auth-algo\r
+//\r
+extern STR2INT mMapAuthAlgo[];\r
+\r
+//\r
+// --encrypt-algo\r
+//\r
+extern STR2INT mMapEncAlgo[];\r
+//\r
+// --auth-proto\r
+//\r
+extern STR2INT mMapAuthProto[];\r
+\r
+//\r
+// --auth-method\r
+//\r
+extern STR2INT mMapAuthMethod[];\r
+\r
+#endif\r
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf b/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf
new file mode 100644 (file)
index 0000000..1e0d4f4
--- /dev/null
@@ -0,0 +1,61 @@
+## @file\r
+#  Component description file for IpSecConfig6 application.\r
+#\r
+#  Copyright (c) 2009 - 2010, 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
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = IpSecConfig\r
+  FILE_GUID                      = 0922E604-F5EC-42ef-980D-A35E9A2B1844\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = InitializeIpSecConfig\r
+\r
+[Sources]\r
+  IpSecConfigStrings.uni\r
+  IpSecConfig.c\r
+  IpSecConfig.h\r
+  Dump.c\r
+  Dump.h\r
+  Indexer.c\r
+  Indexer.h\r
+  Match.c\r
+  Match.h\r
+  Delete.h\r
+  Delete.c\r
+  Helper.c\r
+  Helper.h\r
+  ForEach.c\r
+  ForEach.h\r
+  PolicyEntryOperation.c\r
+  PolicyEntryOperation.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  UefiApplicationEntryPoint\r
+  BaseMemoryLib\r
+  ShellLib\r
+  MemoryAllocationLib\r
+  DebugLib\r
+  HiiLib\r
+  NetLib\r
+  UefiLib\r
+\r
+[Protocols]\r
+  gEfiIpSecProtocolGuid                         ##CONSUMS\r
+  gEfiIpSecConfigProtocolGuid                   ##CONSUMS\r
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni b/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni
new file mode 100644 (file)
index 0000000..fb0e27d
Binary files /dev/null and b/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni differ
diff --git a/NetworkPkg/Application/IpsecConfig/Match.c b/NetworkPkg/Application/IpsecConfig/Match.c
new file mode 100644 (file)
index 0000000..d6595ee
--- /dev/null
@@ -0,0 +1,163 @@
+/** @file\r
+  The implementation of match policy entry function in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 "IpSecConfig.h"\r
+#include "Indexer.h"\r
+#include "Match.h"\r
+\r
+/**\r
+  Private function to validate a buffer that should be filled with zero.\r
+\r
+  @param[in] Memory    The pointer to the buffer.\r
+  @param[in] Size      The size of the buffer.\r
+\r
+  @retval TRUE     The memory is filled with zero.\r
+  @retval FALSE    The memory isn't filled with zero.\r
+**/\r
+BOOLEAN\r
+IsMemoryZero (\r
+  IN VOID     *Memory,\r
+  IN UINTN    Size\r
+  )\r
+{\r
+  UINTN    Index;\r
+\r
+  for (Index = 0; Index < Size; Index++) {\r
+    if (*((UINT8 *) Memory + Index) != 0) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Find the matching SPD with Indexer.\r
+\r
+  @param[in] Selector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.\r
+  @param[in] Data        The pointer to the EFI_IPSEC_SPD_DATA structure.\r
+  @param[in] Indexer     The pointer to the SPD_ENTRY_INDEXER structure.\r
+\r
+  @retval TRUE     The matched SPD is found.\r
+  @retval FALSE    The matched SPD is not found.\r
+**/\r
+BOOLEAN\r
+MatchSpdEntry (\r
+  IN EFI_IPSEC_SPD_SELECTOR    *Selector,\r
+  IN EFI_IPSEC_SPD_DATA        *Data,\r
+  IN SPD_ENTRY_INDEXER         *Indexer\r
+  )\r
+{\r
+  BOOLEAN    Match;\r
+\r
+  Match = FALSE;\r
+  if (Indexer->Name != NULL) {\r
+    if ((Data->Name != NULL) && (AsciiStrCmp ((CHAR8 *) Indexer->Name, (CHAR8 *) Data->Name) == 0)) {\r
+      Match = TRUE;\r
+    }\r
+  } else {\r
+    if (Indexer->Index == 0) {\r
+      Match = TRUE;\r
+    }\r
+\r
+    Indexer->Index--;\r
+  }\r
+\r
+  return Match;\r
+}\r
+\r
+/**\r
+  Find the matching SAD with Indexer.\r
+\r
+  @param[in] SaId       The pointer to the EFI_IPSEC_SA_ID structure.\r
+  @param[in] Data       The pointer to the EFI_IPSEC_SA_DATA structure.\r
+  @param[in] Indexer    The pointer to the SPD_ENTRY_INDEXER structure.\r
+\r
+  @retval TRUE     The matched SAD is found.\r
+  @retval FALSE    The matched SAD is not found.\r
+**/\r
+BOOLEAN\r
+MatchSadEntry (\r
+  IN EFI_IPSEC_SA_ID      *SaId,\r
+  IN EFI_IPSEC_SA_DATA    *Data,\r
+  IN SAD_ENTRY_INDEXER    *Indexer\r
+  )\r
+{\r
+  BOOLEAN    Match;\r
+\r
+  Match = FALSE;\r
+  if (!IsMemoryZero (&Indexer->SaId, sizeof (EFI_IPSEC_SA_ID))) {\r
+    Match = (BOOLEAN) (CompareMem (&Indexer->SaId, SaId, sizeof (EFI_IPSEC_SA_ID)) == 0);\r
+  } else {\r
+    if (Indexer->Index == 0) {\r
+      Match = TRUE;\r
+    }\r
+    Indexer->Index--;\r
+  }\r
+\r
+  return Match;\r
+}\r
+\r
+/**\r
+  Find the matching PAD with Indexer.\r
+\r
+  @param[in] PadId      The pointer to the EFI_IPSEC_PAD_ID structure.\r
+  @param[in] Data       The pointer to the EFI_IPSEC_PAD_DATA structure.\r
+  @param[in] Indexer    The pointer to the SPD_ENTRY_INDEXER structure.\r
+\r
+  @retval TRUE     The matched PAD is found.\r
+  @retval FALSE    The matched PAD is not found.\r
+**/\r
+BOOLEAN\r
+MatchPadEntry (\r
+  IN EFI_IPSEC_PAD_ID      *PadId,\r
+  IN EFI_IPSEC_PAD_DATA    *Data,\r
+  IN PAD_ENTRY_INDEXER     *Indexer\r
+  )\r
+{\r
+  BOOLEAN                       Match;\r
+\r
+  Match = FALSE;\r
+  if (!IsMemoryZero (&Indexer->PadId, sizeof (EFI_IPSEC_PAD_ID))) {\r
+    Match = (BOOLEAN) ((Indexer->PadId.PeerIdValid == PadId->PeerIdValid) &&\r
+                       ((PadId->PeerIdValid &&\r
+                         (StrCmp (\r
+                            (CONST CHAR16 *) Indexer->PadId.Id.PeerId,\r
+                            (CONST CHAR16 *) PadId->Id.PeerId\r
+                            ) == 0)) ||\r
+                        ((!PadId->PeerIdValid) &&\r
+                         (Indexer->PadId.Id.IpAddress.PrefixLength == PadId->Id.IpAddress.PrefixLength) &&\r
+                         (CompareMem (\r
+                            &Indexer->PadId.Id.IpAddress.Address,\r
+                            &PadId->Id.IpAddress.Address,\r
+                            sizeof (EFI_IP_ADDRESS)\r
+                            ) == 0))));\r
+  } else {\r
+    if (Indexer->Index == 0) {\r
+      Match = TRUE;\r
+    }\r
+\r
+    Indexer->Index--;\r
+  }\r
+\r
+  return Match;\r
+}\r
+\r
+MATCH_POLICY_ENTRY mMatchPolicyEntry[] = {\r
+  (MATCH_POLICY_ENTRY) MatchSpdEntry,\r
+  (MATCH_POLICY_ENTRY) MatchSadEntry,\r
+  (MATCH_POLICY_ENTRY) MatchPadEntry\r
+};\r
+\r
diff --git a/NetworkPkg/Application/IpsecConfig/Match.h b/NetworkPkg/Application/IpsecConfig/Match.h
new file mode 100644 (file)
index 0000000..1d73c5c
--- /dev/null
@@ -0,0 +1,41 @@
+/** @file\r
+  The internal structure and function declaration of \r
+  match policy entry function in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _MATCH_H_\r
+#define _MATCH_H_\r
+\r
+/**\r
+  The prototype for the MatchSpdEntry()/MatchSadEntry()/MatchPadEntry().\r
+  The functionality is to find the matching SPD/SAD/PAD with Indexer.\r
+\r
+  @param[in] Selector    The pointer to the EFI_IPSEC_CONFIG_SELECTOR union.\r
+  @param[in] Data        The pointer to corresponding Data.\r
+  @param[in] Indexer     The pointer to the POLICY_ENTRY_INDEXER union.\r
+\r
+  @retval TRUE     The matched SPD/SAD/PAD is found.\r
+  @retval FALSE    The matched SPD/SAD/PAD is not found.\r
+**/\r
+typedef\r
+BOOLEAN\r
+(* MATCH_POLICY_ENTRY) (\r
+  IN EFI_IPSEC_CONFIG_SELECTOR    *Selector,\r
+  IN VOID                         *Data,\r
+  IN POLICY_ENTRY_INDEXER         *Indexer\r
+  );\r
+\r
+extern MATCH_POLICY_ENTRY mMatchPolicyEntry[];\r
+\r
+#endif\r
diff --git a/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c b/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c
new file mode 100644 (file)
index 0000000..ddfbb4c
--- /dev/null
@@ -0,0 +1,2016 @@
+/** @file\r
+  The implementation of policy entry operation function in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 "IpSecConfig.h"\r
+#include "Indexer.h"\r
+#include "Match.h"\r
+#include "Helper.h"\r
+#include "ForEach.h"\r
+#include "PolicyEntryOperation.h"\r
+\r
+/**\r
+  Fill in EFI_IPSEC_SPD_SELECTOR through ParamPackage list.\r
+\r
+  @param[out]     Selector        The pointer to the EFI_IPSEC_SPD_SELECTOR structure.\r
+  @param[in]      ParamPackage    The pointer to the ParamPackage list.\r
+  @param[in, out] ParamPackage    The pointer to the Mask.\r
+\r
+  @retval EFI_SUCCESS              Fill in EFI_IPSEC_SPD_SELECTOR successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateSpdSelector (\r
+     OUT EFI_IPSEC_SPD_SELECTOR    *Selector,\r
+  IN     LIST_ENTRY                *ParamPackage,\r
+  IN OUT UINT32                    *Mask\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  EFI_STATUS      ReturnStatus;\r
+  CONST CHAR16    *ValueStr;\r
+\r
+  Status       = EFI_SUCCESS;\r
+  ReturnStatus = EFI_SUCCESS;\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local");\r
+  if (ValueStr != NULL) {\r
+    Selector->LocalAddressCount = 1;\r
+    Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->LocalAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--local",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= LOCAL;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote");\r
+  if (ValueStr != NULL) {\r
+    Selector->RemoteAddressCount = 1;\r
+    Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->RemoteAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--remote",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= REMOTE;\r
+    }\r
+  }\r
+\r
+  Selector->NextLayerProtocol = EFI_IPSEC_ANY_PROTOCOL;\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.\r
+  //\r
+  Status = GetNumber (\r
+             L"--proto",\r
+             (UINT16) -1,\r
+             &Selector->NextLayerProtocol,\r
+             sizeof (UINT16),\r
+             mMapIpProtocol,\r
+             ParamPackage,\r
+             FORMAT_NUMBER | FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= PROTO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Selector->LocalPort  = EFI_IPSEC_ANY_PORT;\r
+  Selector->RemotePort = EFI_IPSEC_ANY_PORT;\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local-port");\r
+  if (ValueStr != NULL) {\r
+    Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->LocalPort, &Selector->LocalPortRange);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--local-port",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= LOCAL_PORT;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote-port");\r
+  if (ValueStr != NULL) {\r
+    Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->RemotePort, &Selector->RemotePortRange);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--remote-port",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= REMOTE_PORT;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.\r
+  //\r
+  Status = GetNumber (\r
+             L"--icmp-type",\r
+             (UINT8) -1,\r
+             &Selector->LocalPort,\r
+             sizeof (UINT16),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= ICMP_TYPE;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.\r
+  //\r
+  Status = GetNumber (\r
+             L"--icmp-code",\r
+             (UINT8) -1,\r
+             &Selector->RemotePort,\r
+             sizeof (UINT16),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= ICMP_CODE;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+/**\r
+  Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA through ParamPackage list.\r
+\r
+  @param[out] Selector        The pointer to the EFI_IPSEC_SPD_SELECTOR structure.\r
+  @param[out] Data            The pointer to the EFI_IPSEC_SPD_DATA structure.\r
+  @param[in]  ParamPackage    The pointer to the ParamPackage list.\r
+  @param[out] Mask            The pointer to the Mask.\r
+  @param[in]  CreateNew       The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateSpdEntry (\r
+  OUT EFI_IPSEC_SPD_SELECTOR    **Selector,\r
+  OUT EFI_IPSEC_SPD_DATA        **Data,\r
+  IN  LIST_ENTRY                *ParamPackage,\r
+  OUT UINT32                    *Mask,\r
+  IN  BOOLEAN                   CreateNew\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  EFI_STATUS      ReturnStatus;\r
+  CONST CHAR16    *ValueStr;\r
+  UINTN           DataSize;\r
+\r
+  Status    = EFI_SUCCESS;\r
+  *Mask     = 0;\r
+\r
+  *Selector = AllocateZeroPool (sizeof (EFI_IPSEC_SPD_SELECTOR) + 2 * sizeof (EFI_IP_ADDRESS_INFO));\r
+  ASSERT (*Selector != NULL);\r
+\r
+  (*Selector)->LocalAddress  = (EFI_IP_ADDRESS_INFO *) (*Selector + 1);\r
+  (*Selector)->RemoteAddress = (*Selector)->LocalAddress + 1;\r
+\r
+  ReturnStatus = CreateSpdSelector (*Selector, ParamPackage, Mask);\r
+\r
+  //\r
+  // SPD DATA\r
+  // NOTE: Allocate enough memory and add padding for different arch.\r
+  //\r
+  DataSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SPD_DATA));\r
+  DataSize  = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_PROCESS_POLICY));\r
+  DataSize += sizeof (EFI_IPSEC_TUNNEL_OPTION);\r
+\r
+  *Data = AllocateZeroPool (DataSize);\r
+  ASSERT (*Data != NULL);\r
+\r
+  (*Data)->ProcessingPolicy               = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER (\r
+                                                                           (*Data + 1),\r
+                                                                           sizeof (UINTN)\r
+                                                                           );\r
+  (*Data)->ProcessingPolicy->TunnelOption = (EFI_IPSEC_TUNNEL_OPTION *) ALIGN_POINTER (\r
+                                                                          ((*Data)->ProcessingPolicy + 1),\r
+                                                                          sizeof (UINTN)\r
+                                                                          );\r
+\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the Name in EFI_IPSEC_SPD_DATA.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--name");\r
+  if (ValueStr != NULL) {\r
+    UnicodeStrToAsciiStr (ValueStr, (CHAR8 *) (*Data)->Name);\r
+    *Mask |= NAME;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the PackageFlag in EFI_IPSEC_SPD_DATA.\r
+  //\r
+  Status = GetNumber (\r
+             L"--packet-flag",\r
+             (UINT8) -1,\r
+             &(*Data)->PackageFlag,\r
+             sizeof (UINT32),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= PACKET_FLAG;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the Action in EFI_IPSEC_SPD_DATA.\r
+  //\r
+  Status = GetNumber (\r
+             L"--action",\r
+             (UINT8) -1,\r
+             &(*Data)->Action,\r
+             sizeof (UINT32),\r
+             mMapIpSecAction,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= ACTION;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the ExtSeqNum in EFI_IPSEC_SPD_DATA.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence")) {\r
+    (*Data)->ProcessingPolicy->ExtSeqNum   = TRUE;\r
+    *Mask |= EXT_SEQUENCE;\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence-")) {\r
+    (*Data)->ProcessingPolicy->ExtSeqNum   = FALSE;\r
+    *Mask |= EXT_SEQUENCE;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the SeqOverflow in EFI_IPSEC_SPD_DATA.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow")) {\r
+    (*Data)->ProcessingPolicy->SeqOverflow = TRUE;\r
+    *Mask |= SEQUENCE_OVERFLOW;\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow-")) {\r
+    (*Data)->ProcessingPolicy->SeqOverflow = FALSE;\r
+    *Mask |= SEQUENCE_OVERFLOW;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the FragCheck in EFI_IPSEC_SPD_DATA.\r
+  //\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check")) {\r
+    (*Data)->ProcessingPolicy->FragCheck   = TRUE;\r
+    *Mask |= FRAGMENT_CHECK;\r
+  } else if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check-")) {\r
+    (*Data)->ProcessingPolicy->FragCheck   = FALSE;\r
+    *Mask |= FRAGMENT_CHECK;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the ProcessingPolicy in EFI_IPSEC_SPD_DATA.\r
+  //\r
+  Status = GetNumber (\r
+             L"--lifebyte",\r
+             (UINT64) -1,\r
+             &(*Data)->ProcessingPolicy->SaLifetime.ByteCount,\r
+             sizeof (UINT64),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= LIFEBYTE;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--lifetime",\r
+             (UINT64) -1,\r
+             &(*Data)->ProcessingPolicy->SaLifetime.HardLifetime,\r
+             sizeof (UINT64),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= LIFETIME;\r
+  }\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--lifetime-soft",\r
+             (UINT64) -1,\r
+             &(*Data)->ProcessingPolicy->SaLifetime.SoftLifetime,\r
+             sizeof (UINT64),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= LIFETIME_SOFT;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  (*Data)->ProcessingPolicy->Mode = EfiIPsecTransport;\r
+  Status = GetNumber (\r
+             L"--mode",\r
+             0,\r
+             &(*Data)->ProcessingPolicy->Mode,\r
+             sizeof (UINT32),\r
+             mMapIpSecMode,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= MODE;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-local");\r
+  if (ValueStr != NULL) {\r
+    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->LocalTunnelAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--tunnel-local",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= TUNNEL_LOCAL;\r
+    }\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-remote");\r
+  if (ValueStr != NULL) {\r
+    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->RemoteTunnelAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--tunnel-remote",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= TUNNEL_REMOTE;\r
+    }\r
+  }\r
+\r
+  (*Data)->ProcessingPolicy->TunnelOption->DF = EfiIPsecTunnelCopyDf;\r
+  Status = GetNumber (\r
+             L"--dont-fragment",\r
+             0,\r
+             &(*Data)->ProcessingPolicy->TunnelOption->DF,\r
+             sizeof (UINT32),\r
+             mMapDfOption,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= DONT_FRAGMENT;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  (*Data)->ProcessingPolicy->Proto = EfiIPsecESP;\r
+  Status = GetNumber (\r
+             L"--ipsec-proto",\r
+             0,\r
+             &(*Data)->ProcessingPolicy->Proto,\r
+             sizeof (UINT32),\r
+             mMapIpSecProtocol,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= IPSEC_PROTO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--encrypt-algo",\r
+             0,\r
+             &(*Data)->ProcessingPolicy->EncAlgoId,\r
+             sizeof (UINT8),\r
+             mMapEncAlgo,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= ENCRYPT_ALGO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--auth-algo",\r
+             0,\r
+             &(*Data)->ProcessingPolicy->AuthAlgoId,\r
+             sizeof (UINT8),\r
+             mMapAuthAlgo,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= AUTH_ALGO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Cannot check Mode against EfiIPsecTunnel, because user may want to change tunnel_remote only so the Mode is not set.\r
+  //\r
+  if ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE | DONT_FRAGMENT)) == 0) {\r
+    (*Data)->ProcessingPolicy->TunnelOption = NULL;\r
+  }\r
+\r
+  if ((*Mask & (EXT_SEQUENCE | SEQUENCE_OVERFLOW | FRAGMENT_CHECK | LIFEBYTE |\r
+                LIFETIME_SOFT | LIFETIME | MODE | TUNNEL_LOCAL | TUNNEL_REMOTE |\r
+                DONT_FRAGMENT | IPSEC_PROTO | AUTH_ALGO | ENCRYPT_ALGO)) == 0) {\r
+    if ((*Data)->Action != EfiIPsecActionProtect) {\r
+      //\r
+      // User may not provide additional parameter for Protect action, so we cannot simply set ProcessingPolicy to NULL.\r
+      //\r
+      (*Data)->ProcessingPolicy = NULL;\r
+    }\r
+  }\r
+\r
+  if (CreateNew) {\r
+    if ((*Mask & (LOCAL | REMOTE | PROTO | ACTION)) != (LOCAL | REMOTE | PROTO | ACTION)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--local --remote --proto --action"\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else if (((*Data)->Action == EfiIPsecActionProtect) &&\r
+               ((*Data)->ProcessingPolicy->Mode == EfiIPsecTunnel) &&\r
+               ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE))) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--tunnel-local --tunnel-remote"\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+/**\r
+  Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA through ParamPackage list.\r
+\r
+  @param[out] SaId            The pointer to the EFI_IPSEC_SA_ID structure.\r
+  @param[out] Data            The pointer to the EFI_IPSEC_SA_DATA structure.\r
+  @param[in]  ParamPackage    The pointer to the ParamPackage list.\r
+  @param[out] Mask            The pointer to the Mask.\r
+  @param[in]  CreateNew       The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+EFI_STATUS\r
+CreateSadEntry (\r
+  OUT EFI_IPSEC_SA_ID      **SaId,\r
+  OUT EFI_IPSEC_SA_DATA    **Data,\r
+  IN  LIST_ENTRY           *ParamPackage,\r
+  OUT UINT32               *Mask,\r
+  IN  BOOLEAN              CreateNew\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  EFI_STATUS      ReturnStatus;\r
+  UINTN           AuthKeyLength;\r
+  UINTN           EncKeyLength;\r
+  CONST CHAR16    *ValueStr;\r
+  UINTN           DataSize;\r
+\r
+  Status        = EFI_SUCCESS;\r
+  ReturnStatus  = EFI_SUCCESS;\r
+  *Mask         = 0;\r
+  AuthKeyLength = 0;\r
+  EncKeyLength  = 0;\r
+\r
+  *SaId = AllocateZeroPool (sizeof (EFI_IPSEC_SA_ID));\r
+  ASSERT (*SaId != NULL);\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the Spi in EFI_IPSEC_SA_ID.\r
+  //\r
+  Status = GetNumber (L"--spi", (UINT32) -1, &(*SaId)->Spi, sizeof (UINT32), NULL, ParamPackage, FORMAT_NUMBER);\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= SPI;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the Proto in EFI_IPSEC_SA_ID.\r
+  //\r
+  Status = GetNumber (\r
+             L"--ipsec-proto",\r
+             0,\r
+             &(*SaId)->Proto,\r
+             sizeof (EFI_IPSEC_PROTOCOL_TYPE),\r
+             mMapIpSecProtocol,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= IPSEC_PROTO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--dest");\r
+  if (ValueStr != NULL) {\r
+    Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*SaId)->DestAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--dest",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= DEST;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in EFI_IPSEC_SA_DATA.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");\r
+  if (ValueStr != NULL) {\r
+    AuthKeyLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");\r
+  if (ValueStr != NULL) {\r
+    EncKeyLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);\r
+  }\r
+\r
+  //\r
+  // EFI_IPSEC_SA_DATA:\r
+  //   +------------\r
+  //   | EFI_IPSEC_SA_DATA\r
+  //   +-----------------------\r
+  //   | AuthKey\r
+  //   +-------------------------\r
+  //   | EncKey\r
+  //   +-------------------------\r
+  //   | SpdSelector\r
+  //\r
+  // Notes: To make sure the address alignment add padding after each data if needed.\r
+  //\r
+  DataSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA));\r
+  DataSize  = ALIGN_VARIABLE (DataSize + AuthKeyLength);\r
+  DataSize  = ALIGN_VARIABLE (DataSize + EncKeyLength);\r
+  DataSize  = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_SPD_SELECTOR));\r
+  DataSize  = ALIGN_VARIABLE (DataSize + sizeof (EFI_IP_ADDRESS_INFO));\r
+  DataSize += sizeof (EFI_IP_ADDRESS_INFO);\r
+\r
+\r
+\r
+  *Data = AllocateZeroPool (DataSize);\r
+  ASSERT (*Data != NULL);\r
+\r
+  (*Data)->ManualSet                    = TRUE;\r
+  (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER (((*Data) + 1), sizeof (UINTN));\r
+  (*Data)->AlgoInfo.EspAlgoInfo.EncKey  = (VOID *) ALIGN_POINTER (\r
+                                                     ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.AuthKey + AuthKeyLength),\r
+                                                     sizeof (UINTN)\r
+                                                     );\r
+  (*Data)->SpdSelector                  = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER (\r
+                                                                       ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.EncKey + EncKeyLength),\r
+                                                                       sizeof (UINTN)\r
+                                                                       );\r
+  (*Data)->SpdSelector->LocalAddress    = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (\r
+                                                                    ((UINT8 *) (*Data)->SpdSelector + sizeof (EFI_IPSEC_SPD_SELECTOR)),\r
+                                                                    sizeof (UINTN));\r
+  (*Data)->SpdSelector->RemoteAddress   = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (\r
+                                                                    (*Data)->SpdSelector->LocalAddress + 1,\r
+                                                                    sizeof (UINTN)\r
+                                                                    );\r
+\r
+  (*Data)->Mode = EfiIPsecTransport;\r
+  Status = GetNumber (\r
+             L"--mode",\r
+             0,\r
+             &(*Data)->Mode,\r
+             sizeof (EFI_IPSEC_MODE),\r
+             mMapIpSecMode,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= MODE;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // According to RFC 4303-3.3.3. The first packet sent using a given SA\r
+  // will contain a sequence number of 1.\r
+  //\r
+  (*Data)->SNCount = 1;\r
+  Status = GetNumber (\r
+             L"--sequence-number",\r
+             (UINT64) -1,\r
+             &(*Data)->SNCount,\r
+             sizeof (UINT64),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= SEQUENCE_NUMBER;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  (*Data)->AntiReplayWindows = 0;\r
+  Status = GetNumber (\r
+             L"--antireplay-window",\r
+             (UINT8) -1,\r
+             &(*Data)->AntiReplayWindows,\r
+             sizeof (UINT8),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= SEQUENCE_NUMBER;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--encrypt-algo",\r
+             0,\r
+             &(*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId,\r
+             sizeof (UINT8),\r
+             mMapEncAlgo,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= ENCRYPT_ALGO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");\r
+  if (ValueStr != NULL ) {\r
+    (*Data)->AlgoInfo.EspAlgoInfo.EncKeyLength = EncKeyLength;\r
+    CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.EncKey, ValueStr, EncKeyLength);\r
+    *Mask |= ENCRYPT_KEY;\r
+  } else {\r
+    (*Data)->AlgoInfo.EspAlgoInfo.EncKey = NULL;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--auth-algo",\r
+             0,\r
+             &(*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId,\r
+             sizeof (UINT8),\r
+             mMapAuthAlgo,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= AUTH_ALGO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");\r
+  if (ValueStr != NULL) {\r
+    (*Data)->AlgoInfo.EspAlgoInfo.AuthKeyLength = AuthKeyLength;\r
+    CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.AuthKey, ValueStr, AuthKeyLength);\r
+    *Mask |= AUTH_KEY;\r
+  } else {\r
+    (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = NULL;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--lifebyte",\r
+             (UINT64) -1,\r
+             &(*Data)->SaLifetime.ByteCount,\r
+             sizeof (UINT64),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= LIFEBYTE;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--lifetime",\r
+             (UINT64) -1,\r
+             &(*Data)->SaLifetime.HardLifetime,\r
+             sizeof (UINT64),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= LIFETIME;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--lifetime-soft",\r
+             (UINT64) -1,\r
+             &(*Data)->SaLifetime.SoftLifetime,\r
+             sizeof (UINT64),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= LIFETIME_SOFT;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--path-mtu",\r
+             (UINT32) -1,\r
+             &(*Data)->PathMTU,\r
+             sizeof (UINT32),\r
+             NULL,\r
+             ParamPackage,\r
+             FORMAT_NUMBER\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= PATH_MTU;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ReturnStatus = CreateSpdSelector ((*Data)->SpdSelector, ParamPackage, Mask);\r
+\r
+  if (CreateNew) {\r
+    if ((*Mask & (SPI | IPSEC_PROTO | DEST)) != (SPI | IPSEC_PROTO | DEST)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--spi --ipsec-proto --dest"\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      if ((*SaId)->Proto == EfiIPsecAH) {\r
+        if ((*Mask & AUTH_ALGO) == 0) {\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),\r
+            mHiiHandle,\r
+            mAppName,\r
+            L"--auth-algo"\r
+            );\r
+          ReturnStatus = EFI_INVALID_PARAMETER;\r
+        } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != EFI_IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) {\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),\r
+            mHiiHandle,\r
+            mAppName,\r
+            L"--auth-key"\r
+            );\r
+          ReturnStatus = EFI_INVALID_PARAMETER;\r
+        }\r
+      } else {\r
+        if ((*Mask & ENCRYPT_ALGO) == 0) {\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),\r
+            mHiiHandle,\r
+            mAppName,\r
+            L"--encrypt-algo"\r
+            );\r
+          ReturnStatus = EFI_INVALID_PARAMETER;\r
+        } else if ((*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId != EFI_IPSEC_EALG_NONE && (*Mask & ENCRYPT_KEY) == 0) {\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),\r
+            mHiiHandle,\r
+            mAppName,\r
+            L"--encrypt-key"\r
+            );\r
+          ReturnStatus = EFI_INVALID_PARAMETER;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+/**\r
+  Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA through ParamPackage list.\r
+\r
+  @param[out] PadId           The pointer to the EFI_IPSEC_PAD_ID structure.\r
+  @param[out] Data            The pointer to the EFI_IPSEC_PAD_DATA structure.\r
+  @param[in]  ParamPackage    The pointer to the ParamPackage list.\r
+  @param[out] Mask            The pointer to the Mask.\r
+  @param[in]  CreateNew       The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+EFI_STATUS\r
+CreatePadEntry (\r
+  OUT EFI_IPSEC_PAD_ID      **PadId,\r
+  OUT EFI_IPSEC_PAD_DATA    **Data,\r
+  IN  LIST_ENTRY            *ParamPackage,\r
+  OUT UINT32                *Mask,\r
+  IN  BOOLEAN               CreateNew\r
+  )\r
+{\r
+  EFI_STATUS         Status;\r
+  EFI_STATUS         ReturnStatus;\r
+  EFI_FILE_HANDLE    FileHandle;\r
+  UINT64             FileSize;\r
+  UINTN              AuthDataLength;\r
+  UINTN              RevocationDataLength;\r
+  UINTN              DataLength;\r
+  UINTN              Index;\r
+  CONST CHAR16       *ValueStr;\r
+  UINTN              DataSize;\r
+\r
+  Status               = EFI_SUCCESS;\r
+  ReturnStatus         = EFI_SUCCESS;\r
+  *Mask                = 0;\r
+  AuthDataLength       = 0;\r
+  RevocationDataLength = 0;\r
+\r
+  *PadId = AllocateZeroPool (sizeof (EFI_IPSEC_PAD_ID));\r
+  ASSERT (*PadId != NULL);\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_ID.\r
+  //\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-address");\r
+  if (ValueStr != NULL) {\r
+    (*PadId)->PeerIdValid = FALSE;\r
+    Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &(*PadId)->Id.IpAddress);\r
+    if (EFI_ERROR (Status)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--peer-address",\r
+        ValueStr\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else {\r
+      *Mask |= PEER_ADDRESS;\r
+    }\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-id");\r
+  if (ValueStr != NULL) {\r
+    (*PadId)->PeerIdValid = TRUE;\r
+    StrnCpy ((CHAR16 *) (*PadId)->Id.PeerId, ValueStr, ARRAY_SIZE ((*PadId)->Id.PeerId) - 1);\r
+    *Mask |= PEER_ID;\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");\r
+  if (ValueStr != NULL) {\r
+    if (ValueStr[0] == L'@') {\r
+      //\r
+      // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"\r
+      //\r
+      Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),\r
+          mHiiHandle,\r
+          mAppName,\r
+          &ValueStr[1]\r
+          );\r
+        ReturnStatus = EFI_INVALID_PARAMETER;\r
+      } else {\r
+        Status = ShellGetFileSize (FileHandle, &FileSize);\r
+        ShellCloseFile (&FileHandle);\r
+        if (EFI_ERROR (Status)) {\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),\r
+            mHiiHandle,\r
+            mAppName,\r
+            &ValueStr[1]\r
+            );\r
+          ReturnStatus = EFI_INVALID_PARAMETER;\r
+        } else {\r
+          AuthDataLength = (UINTN) FileSize;\r
+        }\r
+      }\r
+    } else {\r
+      AuthDataLength = StrLen (ValueStr);\r
+    }\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");\r
+  if (ValueStr != NULL) {\r
+    RevocationDataLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);\r
+  }\r
+\r
+  //\r
+  // Allocate Buffer for Data. Add padding after each struct to make sure the alignment\r
+  // in different Arch.\r
+  //\r
+  DataSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_PAD_DATA));\r
+  DataSize  = ALIGN_VARIABLE (DataSize + AuthDataLength);\r
+  DataSize += RevocationDataLength;\r
+\r
+  *Data = AllocateZeroPool (DataSize);\r
+  ASSERT (*Data != NULL);\r
+\r
+  (*Data)->AuthData       = (VOID *) ALIGN_POINTER ((*Data + 1), sizeof (UINTN));\r
+  (*Data)->RevocationData = (VOID *) ALIGN_POINTER (((UINT8 *) (*Data + 1) + AuthDataLength), sizeof (UINTN));\r
+  (*Data)->AuthProtocol   = EfiIPsecAuthProtocolIKEv1;\r
+\r
+  //\r
+  // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_DATA.\r
+  //\r
+  Status = GetNumber (\r
+             L"--auth-proto",\r
+             0,\r
+             &(*Data)->AuthProtocol,\r
+             sizeof (EFI_IPSEC_AUTH_PROTOCOL_TYPE),\r
+             mMapAuthProto,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= AUTH_PROTO;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = GetNumber (\r
+             L"--auth-method",\r
+             0,\r
+             &(*Data)->AuthMethod,\r
+             sizeof (EFI_IPSEC_AUTH_METHOD),\r
+             mMapAuthMethod,\r
+             ParamPackage,\r
+             FORMAT_STRING\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    *Mask |= AUTH_METHOD;\r
+  }\r
+\r
+  if (Status == EFI_INVALID_PARAMETER) {\r
+    ReturnStatus = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id")) {\r
+    (*Data)->IkeIdFlag = TRUE;\r
+    *Mask |= IKE_ID;\r
+  }\r
+\r
+  if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id-")) {\r
+    (*Data)->IkeIdFlag = FALSE;\r
+    *Mask |= IKE_ID;\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");\r
+  if (ValueStr != NULL) {\r
+    if (ValueStr[0] == L'@') {\r
+      //\r
+      // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"\r
+      //\r
+\r
+      Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);\r
+      if (EFI_ERROR (Status)) {\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),\r
+          mHiiHandle,\r
+          mAppName,\r
+          &ValueStr[1]\r
+          );\r
+        ReturnStatus = EFI_INVALID_PARAMETER;\r
+        (*Data)->AuthData = NULL;\r
+      } else {\r
+        DataLength = AuthDataLength;\r
+        Status = ShellReadFile (FileHandle, &DataLength, (*Data)->AuthData);\r
+        ShellCloseFile (&FileHandle);\r
+        if (EFI_ERROR (Status)) {\r
+          ShellPrintHiiEx (\r
+            -1,\r
+            -1,\r
+            NULL,\r
+            STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),\r
+            mHiiHandle,\r
+            mAppName,\r
+            &ValueStr[1]\r
+            );\r
+          ReturnStatus = EFI_INVALID_PARAMETER;\r
+          (*Data)->AuthData = NULL;\r
+        } else {\r
+          ASSERT (DataLength == AuthDataLength);\r
+          *Mask |= AUTH_DATA;\r
+        }\r
+      }\r
+    } else {\r
+      for (Index = 0; Index < AuthDataLength; Index++) {\r
+        ((CHAR8 *) (*Data)->AuthData)[Index] = (CHAR8) ValueStr[Index];\r
+      }\r
+      (*Data)->AuthDataSize = AuthDataLength;\r
+      *Mask |= AUTH_DATA;\r
+    }\r
+  }\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");\r
+  if (ValueStr != NULL) {\r
+    CopyMem ((*Data)->RevocationData, ValueStr, RevocationDataLength);\r
+    (*Data)->RevocationDataSize = RevocationDataLength;\r
+    *Mask |= REVOCATION_DATA;\r
+  } else {\r
+    (*Data)->RevocationData = NULL;\r
+  }\r
+\r
+  if (CreateNew) {\r
+    if ((*Mask & (PEER_ID | PEER_ADDRESS)) == 0) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--peer-id --peer-address"\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    } else if ((*Mask & (AUTH_METHOD | AUTH_DATA)) != (AUTH_METHOD | AUTH_DATA)) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--auth-method --auth-data"\r
+        );\r
+      ReturnStatus = EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+CREATE_POLICY_ENTRY mCreatePolicyEntry[] = {\r
+  (CREATE_POLICY_ENTRY) CreateSpdEntry,\r
+  (CREATE_POLICY_ENTRY) CreateSadEntry,\r
+  (CREATE_POLICY_ENTRY) CreatePadEntry\r
+};\r
+\r
+/**\r
+  Combine old SPD entry with new SPD entry.\r
+\r
+  @param[in, out] OldSelector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.\r
+  @param[in, out] OldData        The pointer to the EFI_IPSEC_SPD_DATA structure.\r
+  @param[in]      NewSelector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.\r
+  @param[in]      NewData        The pointer to the EFI_IPSEC_SPD_DATA structure.\r
+  @param[in]      Mask           The pointer to the Mask.\r
+  @param[out]     CreateNew      The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Combined successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+EFI_STATUS\r
+CombineSpdEntry (\r
+  IN OUT EFI_IPSEC_SPD_SELECTOR    *OldSelector,\r
+  IN OUT EFI_IPSEC_SPD_DATA        *OldData,\r
+  IN     EFI_IPSEC_SPD_SELECTOR    *NewSelector,\r
+  IN     EFI_IPSEC_SPD_DATA        *NewData,\r
+  IN     UINT32                    Mask,\r
+     OUT BOOLEAN                   *CreateNew\r
+  )\r
+{\r
+\r
+  //\r
+  // Process Selector\r
+  //\r
+  *CreateNew = FALSE;\r
+  if ((Mask & LOCAL) == 0) {\r
+    NewSelector->LocalAddressCount = OldSelector->LocalAddressCount;\r
+    NewSelector->LocalAddress      = OldSelector->LocalAddress;\r
+  } else if ((NewSelector->LocalAddressCount != OldSelector->LocalAddressCount) ||\r
+             (CompareMem (NewSelector->LocalAddress, OldSelector->LocalAddress, NewSelector->LocalAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {\r
+    *CreateNew = TRUE;\r
+  }\r
+\r
+  if ((Mask & REMOTE) == 0) {\r
+    NewSelector->RemoteAddressCount = OldSelector->RemoteAddressCount;\r
+    NewSelector->RemoteAddress      = OldSelector->RemoteAddress;\r
+  } else if ((NewSelector->RemoteAddressCount != OldSelector->RemoteAddressCount) ||\r
+             (CompareMem (NewSelector->RemoteAddress, OldSelector->RemoteAddress, NewSelector->RemoteAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {\r
+    *CreateNew = TRUE;\r
+  }\r
+\r
+  if ((Mask & PROTO) == 0) {\r
+    NewSelector->NextLayerProtocol = OldSelector->NextLayerProtocol;\r
+  } else if (NewSelector->NextLayerProtocol != OldSelector->NextLayerProtocol) {\r
+    *CreateNew = TRUE;\r
+  }\r
+\r
+  switch (NewSelector->NextLayerProtocol) {\r
+    case EFI_IP4_PROTO_TCP:\r
+    case EFI_IP4_PROTO_UDP:\r
+      if ((Mask & LOCAL_PORT) == 0) {\r
+        NewSelector->LocalPort      = OldSelector->LocalPort;\r
+        NewSelector->LocalPortRange = OldSelector->LocalPortRange;\r
+      } else if ((NewSelector->LocalPort != OldSelector->LocalPort) ||\r
+        (NewSelector->LocalPortRange != OldSelector->LocalPortRange)) {\r
+        *CreateNew = TRUE;\r
+      }\r
+\r
+      if ((Mask & REMOTE_PORT) == 0) {\r
+        NewSelector->RemotePort      = OldSelector->RemotePort;\r
+        NewSelector->RemotePortRange = OldSelector->RemotePortRange;\r
+      } else if ((NewSelector->RemotePort != OldSelector->RemotePort) ||\r
+        (NewSelector->RemotePortRange != OldSelector->RemotePortRange)) {\r
+        *CreateNew = TRUE;\r
+      }\r
+      break;\r
+\r
+    case EFI_IP4_PROTO_ICMP:\r
+      if ((Mask & ICMP_TYPE) == 0) {\r
+        NewSelector->LocalPort = OldSelector->LocalPort;\r
+      } else if (NewSelector->LocalPort != OldSelector->LocalPort) {\r
+        *CreateNew = TRUE;\r
+      }\r
+\r
+      if ((Mask & ICMP_CODE) == 0) {\r
+        NewSelector->RemotePort = OldSelector->RemotePort;\r
+      } else if (NewSelector->RemotePort != OldSelector->RemotePort) {\r
+        *CreateNew = TRUE;\r
+      }\r
+      break;\r
+  }\r
+  //\r
+  // Process Data\r
+  //\r
+  if ((Mask & NAME) != 0) {\r
+    AsciiStrCpy ((CHAR8 *) OldData->Name, (CHAR8 *) NewData->Name);\r
+  }\r
+\r
+  if ((Mask & PACKET_FLAG) != 0) {\r
+    OldData->PackageFlag = NewData->PackageFlag;\r
+  }\r
+\r
+  if ((Mask & ACTION) != 0) {\r
+    OldData->Action = NewData->Action;\r
+  }\r
+\r
+  if (OldData->Action != EfiIPsecActionProtect) {\r
+    OldData->ProcessingPolicy = NULL;\r
+  } else {\r
+    //\r
+    // Protect\r
+    //\r
+    if (OldData->ProcessingPolicy == NULL) {\r
+      //\r
+      // Just point to new data if originally NULL.\r
+      //\r
+      OldData->ProcessingPolicy = NewData->ProcessingPolicy;\r
+      if (OldData->ProcessingPolicy->Mode == EfiIPsecTunnel &&\r
+          (Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)\r
+        ) {\r
+        //\r
+        // Change to Protect action and Tunnel mode, but without providing local/remote tunnel address.\r
+        //\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+          mHiiHandle,\r
+          mAppName,\r
+          L"--tunnel-local --tunnel-remote"\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else {\r
+      //\r
+      // Modify some of the data.\r
+      //\r
+      if ((Mask & EXT_SEQUENCE) != 0) {\r
+        OldData->ProcessingPolicy->ExtSeqNum = NewData->ProcessingPolicy->ExtSeqNum;\r
+      }\r
+\r
+      if ((Mask & SEQUENCE_OVERFLOW) != 0) {\r
+        OldData->ProcessingPolicy->SeqOverflow = NewData->ProcessingPolicy->SeqOverflow;\r
+      }\r
+\r
+      if ((Mask & FRAGMENT_CHECK) != 0) {\r
+        OldData->ProcessingPolicy->FragCheck = NewData->ProcessingPolicy->FragCheck;\r
+      }\r
+\r
+      if ((Mask & LIFEBYTE) != 0) {\r
+        OldData->ProcessingPolicy->SaLifetime.ByteCount = NewData->ProcessingPolicy->SaLifetime.ByteCount;\r
+      }\r
+\r
+      if ((Mask & LIFETIME_SOFT) != 0) {\r
+        OldData->ProcessingPolicy->SaLifetime.SoftLifetime = NewData->ProcessingPolicy->SaLifetime.SoftLifetime;\r
+      }\r
+\r
+      if ((Mask & LIFETIME) != 0) {\r
+        OldData->ProcessingPolicy->SaLifetime.HardLifetime = NewData->ProcessingPolicy->SaLifetime.HardLifetime;\r
+      }\r
+\r
+      if ((Mask & MODE) != 0) {\r
+        OldData->ProcessingPolicy->Mode = NewData->ProcessingPolicy->Mode;\r
+      }\r
+\r
+      if ((Mask & IPSEC_PROTO) != 0) {\r
+        OldData->ProcessingPolicy->Proto = NewData->ProcessingPolicy->Proto;\r
+      }\r
+\r
+      if ((Mask & AUTH_ALGO) != 0) {\r
+        OldData->ProcessingPolicy->AuthAlgoId = NewData->ProcessingPolicy->AuthAlgoId;\r
+      }\r
+\r
+      if ((Mask & ENCRYPT_ALGO) != 0) {\r
+        OldData->ProcessingPolicy->EncAlgoId = NewData->ProcessingPolicy->EncAlgoId;\r
+      }\r
+\r
+      if (OldData->ProcessingPolicy->Mode != EfiIPsecTunnel) {\r
+        OldData->ProcessingPolicy->TunnelOption = NULL;\r
+      } else {\r
+        if (OldData->ProcessingPolicy->TunnelOption == NULL) {\r
+          //\r
+          // Set from Transport mode to Tunnel mode, should ensure TUNNEL_LOCAL & TUNNEL_REMOTE both exists.\r
+          //\r
+          if ((Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)) {\r
+            ShellPrintHiiEx (\r
+              -1,\r
+              -1,\r
+              NULL,\r
+              STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+              mHiiHandle,\r
+              mAppName,\r
+              L"--tunnel-local --tunnel-remote"\r
+              );\r
+            return EFI_INVALID_PARAMETER;\r
+          }\r
+\r
+          OldData->ProcessingPolicy->TunnelOption = NewData->ProcessingPolicy->TunnelOption;\r
+        } else {\r
+          if ((Mask & TUNNEL_LOCAL) != 0) {\r
+            CopyMem (\r
+              &OldData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,\r
+              &NewData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,\r
+              sizeof (EFI_IP_ADDRESS)\r
+              );\r
+          }\r
+\r
+          if ((Mask & TUNNEL_REMOTE) != 0) {\r
+            CopyMem (\r
+              &OldData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,\r
+              &NewData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,\r
+              sizeof (EFI_IP_ADDRESS)\r
+              );\r
+          }\r
+\r
+          if ((Mask & DONT_FRAGMENT) != 0) {\r
+            OldData->ProcessingPolicy->TunnelOption->DF = NewData->ProcessingPolicy->TunnelOption->DF;\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Combine old SAD entry with new SAD entry.\r
+\r
+  @param[in, out] OldSaId      The pointer to the EFI_IPSEC_SA_ID structure.\r
+  @param[in, out] OldData      The pointer to the EFI_IPSEC_SA_DATA structure.\r
+  @param[in]      NewSaId      The pointer to the EFI_IPSEC_SA_ID structure.\r
+  @param[in]      NewData      The pointer to the EFI_IPSEC_SA_DATA structure.\r
+  @param[in]      Mask         The pointer to the Mask.\r
+  @param[out]     CreateNew    The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Combined successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+EFI_STATUS\r
+CombineSadEntry (\r
+  IN OUT EFI_IPSEC_SA_ID      *OldSaId,\r
+  IN OUT EFI_IPSEC_SA_DATA    *OldData,\r
+  IN     EFI_IPSEC_SA_ID      *NewSaId,\r
+  IN     EFI_IPSEC_SA_DATA    *NewData,\r
+  IN     UINT32               Mask,\r
+     OUT BOOLEAN              *CreateNew\r
+  )\r
+{\r
+\r
+  *CreateNew = FALSE;\r
+\r
+  if ((Mask & SPI) == 0) {\r
+    NewSaId->Spi = OldSaId->Spi;\r
+  } else if (NewSaId->Spi != OldSaId->Spi) {\r
+    *CreateNew = TRUE;\r
+  }\r
+\r
+  if ((Mask & IPSEC_PROTO) == 0) {\r
+    NewSaId->Proto = OldSaId->Proto;\r
+  } else if (NewSaId->Proto != OldSaId->Proto) {\r
+    *CreateNew = TRUE;\r
+  }\r
+\r
+  if ((Mask & DEST) == 0) {\r
+    CopyMem (&NewSaId->DestAddress, &OldSaId->DestAddress, sizeof (EFI_IP_ADDRESS));\r
+  } else if (CompareMem (&NewSaId->DestAddress, &OldSaId->DestAddress, sizeof (EFI_IP_ADDRESS)) != 0) {\r
+    *CreateNew = TRUE;\r
+  }\r
+\r
+  //\r
+  // Process SA_DATA.\r
+  //\r
+  if ((Mask & MODE) != 0) {\r
+    OldData->Mode = NewData->Mode;\r
+  }\r
+\r
+  if ((Mask & SEQUENCE_NUMBER) != 0) {\r
+    OldData->SNCount = NewData->SNCount;\r
+  }\r
+\r
+  if ((Mask & ANTIREPLAY_WINDOW) != 0) {\r
+    OldData->AntiReplayWindows = NewData->AntiReplayWindows;\r
+  }\r
+\r
+  if ((Mask & AUTH_ALGO) != 0) {\r
+    OldData->AlgoInfo.EspAlgoInfo.AuthAlgoId    = NewData->AlgoInfo.EspAlgoInfo.AuthAlgoId;\r
+  }\r
+\r
+  if ((Mask & AUTH_KEY) != 0) {\r
+    OldData->AlgoInfo.EspAlgoInfo.AuthKey       = NewData->AlgoInfo.EspAlgoInfo.AuthKey;\r
+    OldData->AlgoInfo.EspAlgoInfo.AuthKeyLength = NewData->AlgoInfo.EspAlgoInfo.AuthKeyLength;\r
+  }\r
+\r
+  if ((Mask & ENCRYPT_ALGO) != 0) {\r
+    OldData->AlgoInfo.EspAlgoInfo.EncAlgoId     = NewData->AlgoInfo.EspAlgoInfo.EncAlgoId;\r
+  }\r
+\r
+  if ((Mask & ENCRYPT_KEY) != 0) {\r
+    OldData->AlgoInfo.EspAlgoInfo.EncKey        = NewData->AlgoInfo.EspAlgoInfo.EncKey;\r
+    OldData->AlgoInfo.EspAlgoInfo.EncKeyLength  = NewData->AlgoInfo.EspAlgoInfo.EncKeyLength;\r
+  }\r
+\r
+  if (NewSaId->Proto == EfiIPsecAH) {\r
+    if ((Mask & (ENCRYPT_ALGO | ENCRYPT_KEY)) != 0) {\r
+      //\r
+      // Should not provide encrypt_* if AH.\r
+      //\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_UNWANTED_PARAMETER),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--encrypt-algo --encrypt-key"\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  if (NewSaId->Proto == EfiIPsecESP && OldSaId->Proto == EfiIPsecAH) {\r
+    //\r
+    // AH -> ESP\r
+    // Should provide encrypt_algo at least.\r
+    //\r
+    if ((Mask & ENCRYPT_ALGO) == 0) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--encrypt-algo"\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    //\r
+    // Encrypt_key should be provided if algorithm is not NONE.\r
+    //\r
+    if (NewData->AlgoInfo.EspAlgoInfo.EncAlgoId != EFI_IPSEC_EALG_NONE && (Mask & ENCRYPT_KEY) == 0) {\r
+      ShellPrintHiiEx (\r
+        -1,\r
+        -1,\r
+        NULL,\r
+        STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),\r
+        mHiiHandle,\r
+        mAppName,\r
+        L"--encrypt-algo"\r
+        );\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  if ((Mask & LIFEBYTE) != 0) {\r
+    OldData->SaLifetime.ByteCount    = NewData->SaLifetime.ByteCount;\r
+  }\r
+\r
+  if ((Mask & LIFETIME_SOFT) != 0) {\r
+    OldData->SaLifetime.SoftLifetime = NewData->SaLifetime.SoftLifetime;\r
+  }\r
+\r
+  if ((Mask & LIFETIME) != 0) {\r
+    OldData->SaLifetime.HardLifetime = NewData->SaLifetime.HardLifetime;\r
+  }\r
+\r
+  if ((Mask & PATH_MTU) != 0) {\r
+    OldData->PathMTU                 = NewData->PathMTU;\r
+  }\r
+  //\r
+  // Process SpdSelector.\r
+  //\r
+  if (OldData->SpdSelector == NULL) {\r
+    if ((Mask & (LOCAL | REMOTE | PROTO | LOCAL_PORT | REMOTE_PORT | ICMP_TYPE | ICMP_CODE)) != 0) {\r
+      if ((Mask & (LOCAL | REMOTE | PROTO)) != (LOCAL | REMOTE | PROTO)) {\r
+        ShellPrintHiiEx (\r
+          -1,\r
+          -1,\r
+          NULL,\r
+          STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),\r
+          mHiiHandle,\r
+          mAppName,\r
+          L"--local --remote --proto"\r
+          );\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+\r
+      OldData->SpdSelector = NewData->SpdSelector;\r
+    }\r
+  } else {\r
+    if ((Mask & LOCAL) != 0) {\r
+      OldData->SpdSelector->LocalAddressCount  = NewData->SpdSelector->LocalAddressCount;\r
+      OldData->SpdSelector->LocalAddress       = NewData->SpdSelector->LocalAddress;\r
+    }\r
+\r
+    if ((Mask & REMOTE) != 0) {\r
+      OldData->SpdSelector->RemoteAddressCount = NewData->SpdSelector->RemoteAddressCount;\r
+      OldData->SpdSelector->RemoteAddress      = NewData->SpdSelector->RemoteAddress;\r
+    }\r
+\r
+    if ((Mask & PROTO) != 0) {\r
+      OldData->SpdSelector->NextLayerProtocol  = NewData->SpdSelector->NextLayerProtocol;\r
+    }\r
+\r
+    if (OldData->SpdSelector != NULL) {\r
+      switch (OldData->SpdSelector->NextLayerProtocol) {\r
+        case EFI_IP4_PROTO_TCP:\r
+        case EFI_IP4_PROTO_UDP:\r
+          if ((Mask & LOCAL_PORT) != 0) {\r
+            OldData->SpdSelector->LocalPort  = NewData->SpdSelector->LocalPort;\r
+          }\r
+\r
+          if ((Mask & REMOTE_PORT) != 0) {\r
+            OldData->SpdSelector->RemotePort = NewData->SpdSelector->RemotePort;\r
+          }\r
+          break;\r
+\r
+        case EFI_IP4_PROTO_ICMP:\r
+          if ((Mask & ICMP_TYPE) != 0) {\r
+            OldData->SpdSelector->LocalPort  = (UINT8) NewData->SpdSelector->LocalPort;\r
+          }\r
+\r
+          if ((Mask & ICMP_CODE) != 0) {\r
+            OldData->SpdSelector->RemotePort = (UINT8) NewData->SpdSelector->RemotePort;\r
+          }\r
+          break;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Combine old PAD entry with new PAD entry.\r
+\r
+  @param[in, out] OldPadId     The pointer to the EFI_IPSEC_PAD_ID structure.\r
+  @param[in, out] OldData      The pointer to the EFI_IPSEC_PAD_DATA structure.\r
+  @param[in]      NewPadId     The pointer to the EFI_IPSEC_PAD_ID structure.\r
+  @param[in]      NewData      The pointer to the EFI_IPSEC_PAD_DATA structure.\r
+  @param[in]      Mask         The pointer to the Mask.\r
+  @param[out]     CreateNew    The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Combined successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+EFI_STATUS\r
+CombinePadEntry (\r
+  IN OUT EFI_IPSEC_PAD_ID      *OldPadId,\r
+  IN OUT EFI_IPSEC_PAD_DATA    *OldData,\r
+  IN     EFI_IPSEC_PAD_ID      *NewPadId,\r
+  IN     EFI_IPSEC_PAD_DATA    *NewData,\r
+  IN     UINT32                Mask,\r
+     OUT BOOLEAN               *CreateNew\r
+  )\r
+{\r
+\r
+  *CreateNew = FALSE;\r
+\r
+  if ((Mask & (PEER_ID | PEER_ADDRESS)) == 0) {\r
+    CopyMem (NewPadId, OldPadId, sizeof (EFI_IPSEC_PAD_ID));\r
+  } else {\r
+    if ((Mask & PEER_ID) != 0) {\r
+      if (OldPadId->PeerIdValid) {\r
+        if (StrCmp ((CONST CHAR16 *) OldPadId->Id.PeerId, (CONST CHAR16 *) NewPadId->Id.PeerId) != 0) {\r
+          *CreateNew = TRUE;\r
+        }\r
+      } else {\r
+        *CreateNew = TRUE;\r
+      }\r
+    } else {\r
+      //\r
+      // MASK & PEER_ADDRESS\r
+      //\r
+      if (OldPadId->PeerIdValid) {\r
+        *CreateNew = TRUE;\r
+      } else {\r
+        if ((CompareMem (&OldPadId->Id.IpAddress.Address, &NewPadId->Id.IpAddress.Address, sizeof (EFI_IP_ADDRESS)) != 0) ||\r
+            (OldPadId->Id.IpAddress.PrefixLength != NewPadId->Id.IpAddress.PrefixLength)) {\r
+          *CreateNew = TRUE;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  if ((Mask & AUTH_PROTO) != 0) {\r
+    OldData->AuthProtocol = NewData->AuthProtocol;\r
+  }\r
+\r
+  if ((Mask & AUTH_METHOD) != 0) {\r
+    OldData->AuthMethod = NewData->AuthMethod;\r
+  }\r
+\r
+  if ((Mask & IKE_ID) != 0) {\r
+    OldData->IkeIdFlag = NewData->IkeIdFlag;\r
+  }\r
+\r
+  if ((Mask & AUTH_DATA) != 0) {\r
+    OldData->AuthDataSize = NewData->AuthDataSize;\r
+    OldData->AuthData     = NewData->AuthData;\r
+  }\r
+\r
+  if ((Mask & REVOCATION_DATA) != 0) {\r
+    OldData->RevocationDataSize = NewData->RevocationDataSize;\r
+    OldData->RevocationData     = NewData->RevocationData;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+COMBINE_POLICY_ENTRY mCombinePolicyEntry[] = {\r
+  (COMBINE_POLICY_ENTRY) CombineSpdEntry,\r
+  (COMBINE_POLICY_ENTRY) CombineSadEntry,\r
+  (COMBINE_POLICY_ENTRY) CombinePadEntry\r
+};\r
+\r
+/**\r
+  Edit entry information in the database.\r
+\r
+  @param[in] Selector    The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.\r
+  @param[in] Data        The pointer to the data.\r
+  @param[in] Context     The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.\r
+\r
+  @retval EFI_SUCCESS    Continue the iteration.\r
+  @retval EFI_ABORTED    Abort the iteration.\r
+**/\r
+EFI_STATUS\r
+EditOperatePolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_SELECTOR    *Selector,\r
+  IN VOID                         *Data,\r
+  IN EDIT_POLICY_ENTRY_CONTEXT    *Context\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  BOOLEAN       CreateNew;\r
+\r
+  if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {\r
+    ASSERT (Context->DataType < 3);\r
+\r
+    Status = mCombinePolicyEntry[Context->DataType] (\r
+               Selector,\r
+               Data,\r
+               Context->Selector,\r
+               Context->Data,\r
+               Context->Mask,\r
+               &CreateNew\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      if (CreateNew) {\r
+        //\r
+        // Insert new entry before old entry\r
+        //\r
+        Status = mIpSecConfig->SetData (\r
+                                 mIpSecConfig,\r
+                                 Context->DataType,\r
+                                 Context->Selector,\r
+                                 Data,\r
+                                 Selector\r
+                                 );\r
+        ASSERT_EFI_ERROR (Status);\r
+        //\r
+        // Delete old entry\r
+        //\r
+        Status = mIpSecConfig->SetData (\r
+                                 mIpSecConfig,\r
+                                 Context->DataType,\r
+                                 Selector,\r
+                                 NULL,\r
+                                 NULL\r
+                                 );\r
+        ASSERT_EFI_ERROR (Status);\r
+      } else {\r
+        Status = mIpSecConfig->SetData (\r
+                                 mIpSecConfig,\r
+                                 Context->DataType,\r
+                                 Context->Selector,\r
+                                 Data,\r
+                                 NULL\r
+                                 );\r
+      }\r
+    }\r
+\r
+    Context->Status = Status;\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Edit entry information in database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS             Edit entry information successfully.\r
+  @retval EFI_NOT_FOUND           Can't find the specified entry.\r
+  @retval Others                  Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+EditPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EDIT_POLICY_ENTRY_CONTEXT    Context;\r
+  CONST CHAR16                 *ValueStr;\r
+\r
+  ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");\r
+  if (ValueStr == NULL) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);\r
+  if (!EFI_ERROR (Status)) {\r
+    Context.DataType = DataType;\r
+    Context.Status   = EFI_NOT_FOUND;\r
+    Status = mCreatePolicyEntry[DataType] (&Context.Selector, &Context.Data, ParamPackage, &Context.Mask, FALSE);\r
+    if (!EFI_ERROR (Status)) {\r
+      ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) EditOperatePolicyEntry, &Context);\r
+      Status = Context.Status;\r
+    }\r
+\r
+    if (Context.Selector != NULL) {\r
+      gBS->FreePool (Context.Selector);\r
+    }\r
+\r
+    if (Context.Data != NULL) {\r
+      gBS->FreePool (Context.Data);\r
+    }\r
+  }\r
+\r
+  if (Status == EFI_NOT_FOUND) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);\r
+  } else if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_EDIT_FAILED), mHiiHandle, mAppName);\r
+  }\r
+\r
+  return Status;\r
+\r
+}\r
+\r
+/**\r
+  Insert entry information in database.\r
+\r
+  @param[in] Selector    The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.\r
+  @param[in] Data        The pointer to the data.\r
+  @param[in] Context     The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.\r
+\r
+  @retval EFI_SUCCESS    Continue the iteration.\r
+  @retval EFI_ABORTED    Abort the iteration.\r
+**/\r
+EFI_STATUS\r
+InsertPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_SELECTOR      *Selector,\r
+  IN VOID                           *Data,\r
+  IN INSERT_POLICY_ENTRY_CONTEXT    *Context\r
+  )\r
+{\r
+  //\r
+  // Found the entry which we want to insert before.\r
+  //\r
+  if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {\r
+\r
+    Context->Status = mIpSecConfig->SetData (\r
+                                      mIpSecConfig,\r
+                                      Context->DataType,\r
+                                      Context->Selector,\r
+                                      Context->Data,\r
+                                      Selector\r
+                                      );\r
+    //\r
+    // Abort the iteration after the insertion.\r
+    //\r
+    return EFI_ABORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Insert or add entry information in database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS             Insert or add entry information successfully.\r
+  @retval EFI_NOT_FOUND           Can't find the specified entry.\r
+  @retval EFI_BUFFER_TOO_SMALL    The entry already existed.\r
+  @retval EFI_UNSUPPORTED         The operation is not supported.\r
+  @retval Others                  Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+AddOrInsertPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_IPSEC_CONFIG_SELECTOR      *Selector;\r
+  VOID                           *Data;\r
+  INSERT_POLICY_ENTRY_CONTEXT    Context;\r
+  UINT32                         Mask;\r
+  UINTN                          DataSize;\r
+  CONST CHAR16                   *ValueStr;\r
+\r
+  Status = mCreatePolicyEntry[DataType] (&Selector, &Data, ParamPackage, &Mask, TRUE);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Find if the Selector to be inserted already exists.\r
+    //\r
+    DataSize = 0;\r
+    Status = mIpSecConfig->GetData (\r
+                             mIpSecConfig,\r
+                             DataType,\r
+                             Selector,\r
+                             &DataSize,\r
+                             NULL\r
+                             );\r
+    if (Status == EFI_BUFFER_TOO_SMALL) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_EXISTS), mHiiHandle, mAppName);\r
+    } else if (ShellCommandLineGetFlag (ParamPackage, L"-a")) {\r
+      Status = mIpSecConfig->SetData (\r
+                               mIpSecConfig,\r
+                               DataType,\r
+                               Selector,\r
+                               Data,\r
+                               NULL\r
+                               );\r
+    } else {\r
+      ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");\r
+      if (ValueStr == NULL) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);\r
+        return EFI_NOT_FOUND;\r
+      }\r
+\r
+      Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);\r
+      if (!EFI_ERROR (Status)) {\r
+        Context.DataType  = DataType;\r
+        Context.Status    = EFI_NOT_FOUND;\r
+        Context.Selector  = Selector;\r
+        Context.Data      = Data;\r
+\r
+        ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) InsertPolicyEntry, &Context);\r
+        Status = Context.Status;\r
+        if (Status == EFI_NOT_FOUND) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);\r
+        }\r
+      }\r
+    }\r
+\r
+    gBS->FreePool (Selector);\r
+    gBS->FreePool (Data);\r
+  }\r
+\r
+  if (Status == EFI_UNSUPPORTED) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_UNSUPPORT), mHiiHandle, mAppName);\r
+  } else if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_FAILED), mHiiHandle, mAppName);\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h b/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h
new file mode 100644 (file)
index 0000000..5161bac
--- /dev/null
@@ -0,0 +1,158 @@
+/** @file\r
+  The function declaration of policy entry operation in IpSecConfig application.\r
+\r
+  Copyright (c) 2009 - 2010, 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
+#ifndef _POLICY_ENTRY_OPERATION_H_\r
+#define _POLICY_ENTRY_OPERATION_H_\r
+\r
+#define LOCAL              BIT(0)\r
+#define REMOTE             BIT(1)\r
+#define PROTO              BIT(2)\r
+#define LOCAL_PORT         BIT(3)\r
+#define REMOTE_PORT        BIT(4)\r
+#define ICMP_TYPE          BIT(5)\r
+#define ICMP_CODE          BIT(6)\r
+#define NAME               BIT(7)\r
+#define PACKET_FLAG        BIT(8)\r
+#define ACTION             BIT(9)\r
+#define EXT_SEQUENCE       BIT(10)\r
+#define SEQUENCE_OVERFLOW  BIT(11)\r
+#define FRAGMENT_CHECK     BIT(12)\r
+#define LIFEBYTE           BIT(13)\r
+#define LIFETIME_SOFT      BIT(14)\r
+#define LIFETIME           BIT(15)\r
+#define MODE               BIT(16)\r
+#define TUNNEL_LOCAL       BIT(17)\r
+#define TUNNEL_REMOTE      BIT(18)\r
+#define DONT_FRAGMENT      BIT(19)\r
+#define IPSEC_PROTO        BIT(20)\r
+#define AUTH_ALGO          BIT(21)\r
+#define ENCRYPT_ALGO       BIT(22)\r
+#define SPI                BIT(23)\r
+#define DEST               BIT(24)\r
+#define SEQUENCE_NUMBER    BIT(25)\r
+#define ANTIREPLAY_WINDOW  BIT(26)\r
+#define AUTH_KEY           BIT(27)\r
+#define ENCRYPT_KEY        BIT(28)\r
+#define PATH_MTU           BIT(29)\r
+\r
+#define PEER_ID            BIT(0)\r
+#define PEER_ADDRESS       BIT(1)\r
+#define AUTH_PROTO         BIT(2)\r
+#define AUTH_METHOD        BIT(3)\r
+#define IKE_ID             BIT(4)\r
+#define AUTH_DATA          BIT(5)\r
+#define REVOCATION_DATA    BIT(6)\r
+\r
+typedef struct {\r
+  EFI_IPSEC_CONFIG_DATA_TYPE    DataType;\r
+  EFI_IPSEC_CONFIG_SELECTOR     *Selector;    // Data to be inserted.\r
+  VOID                          *Data;\r
+  UINT32                        Mask;\r
+  POLICY_ENTRY_INDEXER          Indexer;\r
+  EFI_STATUS                    Status;       // Indicate whether insertion succeeds.\r
+} EDIT_POLICY_ENTRY_CONTEXT;\r
+\r
+typedef struct {\r
+  EFI_IPSEC_CONFIG_DATA_TYPE    DataType;\r
+  EFI_IPSEC_CONFIG_SELECTOR     *Selector;    // Data to be inserted.\r
+  VOID                          *Data;\r
+  POLICY_ENTRY_INDEXER          Indexer;\r
+  EFI_STATUS                    Status;       // Indicate whether insertion succeeds.\r
+} INSERT_POLICY_ENTRY_CONTEXT;\r
+\r
+/**\r
+  The prototype for the CreateSpdEntry()/CreateSadEntry()/CreatePadEntry().\r
+  Fill in EFI_IPSEC_CONFIG_SELECTOR and corresponding data thru ParamPackage list.\r
+\r
+  @param[out] Selector        The pointer to the EFI_IPSEC_CONFIG_SELECTOR union.\r
+  @param[out] Data            The pointer to corresponding data.\r
+  @param[in]  ParamPackage    The pointer to the ParamPackage list.\r
+  @param[out] Mask            The pointer to the Mask.\r
+  @param[in]  CreateNew       The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Filled in EFI_IPSEC_CONFIG_SELECTOR and corresponding data successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(*CREATE_POLICY_ENTRY) (\r
+  OUT EFI_IPSEC_CONFIG_SELECTOR    **Selector,\r
+  OUT VOID                         **Data,\r
+  IN  LIST_ENTRY                   *ParamPackage,\r
+  OUT UINT32                       *Mask,\r
+  IN  BOOLEAN                      CreateNew\r
+  );\r
+\r
+/**\r
+  The prototype for the CombineSpdEntry()/CombineSadEntry()/CombinePadEntry().\r
+  Combine old SPD/SAD/PAD entry with new SPD/SAD/PAD entry.\r
+\r
+  @param[in, out] OldSelector    The pointer to the old EFI_IPSEC_CONFIG_SELECTOR union.\r
+  @param[in, out] OldData        The pointer to the corresponding old data.\r
+  @param[in]      NewSelector    The pointer to the new EFI_IPSEC_CONFIG_SELECTOR union.\r
+  @param[in]      NewData        The pointer to the corresponding new data.\r
+  @param[in]      Mask           The pointer to the Mask.\r
+  @param[out]     CreateNew      The switch to create new.\r
+\r
+  @retval EFI_SUCCESS              Combined successfully.\r
+  @retval EFI_INVALID_PARAMETER    Invalid user input parameter.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(* COMBINE_POLICY_ENTRY) (\r
+  EFI_IPSEC_CONFIG_SELECTOR    *OldSelector,\r
+  VOID                         *OldData,\r
+  EFI_IPSEC_CONFIG_SELECTOR    *NewSelector,\r
+  VOID                         *NewData,\r
+  UINT32                       Mask,\r
+  BOOLEAN                      *CreateNew\r
+  );\r
+\r
+/**\r
+  Insert or add entry information in database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS             Insert or add entry information successfully.\r
+  @retval EFI_NOT_FOUND           Can't find the specified entry.\r
+  @retval EFI_BUFFER_TOO_SMALL    The entry already existed.\r
+  @retval EFI_UNSUPPORTED         The operation is not supported./\r
+  @retval Others                  Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+AddOrInsertPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  );\r
+\r
+/**\r
+  Edit entry information in the database according to datatype.\r
+\r
+  @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.\r
+  @param[in] ParamPackage    The pointer to the ParamPackage list.\r
+\r
+  @retval EFI_SUCCESS             Edit entry information successfully.\r
+  @retval EFI_NOT_FOUND           Can't find the specified entry.\r
+  @retval Others                  Some mistaken case.\r
+**/\r
+EFI_STATUS\r
+EditPolicyEntry (\r
+  IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,\r
+  IN LIST_ENTRY                    *ParamPackage\r
+  );\r
+#endif\r
diff --git a/NetworkPkg/Application/Ping6/Ia32/Tsc.c b/NetworkPkg/Application/Ping6/Ia32/Tsc.c
new file mode 100644 (file)
index 0000000..e2eae99
--- /dev/null
@@ -0,0 +1,28 @@
+/** @file\r
+  The implement to read TSC in IA32 platform.\r
+\r
+  Copyright (c) 2009 - 2010, 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 <Library/BaseLib.h>\r
+\r
+/**\r
+  Reads and returns the current value of the Time Stamp Counter (TSC).\r
+\r
+  @return The current value of TSC.\r
+\r
+**/\r
+UINT64\r
+ReadTime ()\r
+{\r
+  return AsmReadTsc ();\r
+}\r
diff --git a/NetworkPkg/Application/Ping6/Ipf/Itc.c b/NetworkPkg/Application/Ping6/Ipf/Itc.c
new file mode 100644 (file)
index 0000000..131e5c0
--- /dev/null
@@ -0,0 +1,28 @@
+/** @file\r
+  The implement to read ITC in IA64 platform.\r
+\r
+  Copyright (c) 2009 - 2010, 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 <Library/BaseLib.h>\r
+\r
+/**\r
+  Reads and returns the current value of the Interval Timer Counter Register (ITC).\r
+\r
+  @return The current value of ITC.\r
+\r
+**/\r
+UINT64\r
+ReadTime ()\r
+{\r
+  return AsmReadItc ();\r
+}\r
diff --git a/NetworkPkg/Application/Ping6/Ping6.c b/NetworkPkg/Application/Ping6/Ping6.c
new file mode 100644 (file)
index 0000000..b783c5a
--- /dev/null
@@ -0,0 +1,1179 @@
+/** @file\r
+  The implementation for Ping6 application.\r
+\r
+  Copyright (c) 2009 - 2010, 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 <Library/ShellLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/BaseLib.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
+#include <Protocol/Cpu.h>\r
+#include <Protocol/ServiceBinding.h>\r
+#include <Protocol/Ip6.h>\r
+#include <Protocol/Ip6Config.h>\r
+\r
+#include "Ping6.h"\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
+EFI_HII_HANDLE    mHiiHandle;\r
+CONST CHAR16      *mIp6DstString;\r
+CONST CHAR16      *mIp6SrcString;\r
+EFI_GUID          mEfiPing6Guid = EFI_PING6_GUID;\r
+UINT32            mFrequency = 0;\r
+/**\r
+  Get and caculate the frequency in tick/ms.\r
+  The result is saved in the globle variable mFrequency\r
+\r
+  @retval EFI_SUCCESS    Caculated the frequency successfully.\r
+  @retval Others         Failed to caculate the frequency.\r
+\r
+**/\r
+EFI_STATUS\r
+Ping6GetFrequency (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS               Status;\r
+  EFI_CPU_ARCH_PROTOCOL    *Cpu;\r
+  UINT64                   CurrentTick;\r
+  UINT32                   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, (UINT64 *) &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 = 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 = (UINT32) DivU64x32 (1000000000000ULL, TimerPeriod);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Get and caculate 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
+UINT32\r
+Ping6CalculateTick (\r
+  IN UINT64    Begin,\r
+  IN UINT64    End\r
+  )\r
+{\r
+  ASSERT (End > Begin);\r
+  return (UINT32) DivU64x32 (End - Begin, mFrequency);\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
+Ping6MatchEchoReply (\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
+Ping6OnEchoRequestSent (\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
+Ping6OnEchoReplyReceived (\r