diff options
author | hhtian <hhtian@6f19259b-4bc3-4df7-8a09-765794883524> | 2010-11-01 06:13:54 +0000 |
---|---|---|
committer | hhtian <hhtian@6f19259b-4bc3-4df7-8a09-765794883524> | 2010-11-01 06:13:54 +0000 |
commit | a3bcde70e6dc69000f85cc5deee98101d2ae200a (patch) | |
tree | 693709a5293f80b320931693b34b2d6983cfcf4b /NetworkPkg/Application | |
parent | 12873d57666d0beff41959a1fb8f9062016f0983 (diff) | |
download | edk2-a3bcde70e6dc69000f85cc5deee98101d2ae200a.tar.gz edk2-a3bcde70e6dc69000f85cc5deee98101d2ae200a.tar.bz2 edk2-a3bcde70e6dc69000f85cc5deee98101d2ae200a.zip |
Add NetworkPkg (P.UDK2010.UP3.Network.P1)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10986 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'NetworkPkg/Application')
32 files changed, 9175 insertions, 0 deletions
diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6.c b/NetworkPkg/Application/IfConfig6/IfConfig6.c new file mode 100644 index 0000000000..b2eada639a --- /dev/null +++ b/NetworkPkg/Application/IfConfig6/IfConfig6.c @@ -0,0 +1,1781 @@ +/** @file
+ The implementation for Shell application IfConfig6.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/ShellLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HiiLib.h>
+#include <Library/NetLib.h>
+
+#include <Protocol/Ip6.h>
+#include <Protocol/Ip6Config.h>
+
+#include "IfConfig6.h"
+
+EFI_HII_HANDLE mHiiHandle;
+
+EFI_GUID mEfiIfConfig6Guid = EFI_IFCONFIG6_GUID;
+SHELL_PARAM_ITEM mIfConfig6CheckList[] = {
+ {
+ L"-b",
+ TypeFlag
+ },
+ {
+ L"-s",
+ TypeMaxValue
+ },
+ {
+ L"-l",
+ TypeValue
+ },
+ {
+ L"-r",
+ TypeValue
+ },
+ {
+ L"-?",
+ TypeFlag
+ },
+ {
+ NULL,
+ TypeMax
+ },
+};
+
+VAR_CHECK_ITEM mSetCheckList[] = {
+ {
+ L"auto",
+ 0x00000001,
+ 0x00000001,
+ FlagTypeSingle
+ },
+ {
+ L"man",
+ 0x00000002,
+ 0x00000001,
+ FlagTypeSingle
+ },
+ {
+ L"host",
+ 0x00000004,
+ 0x00000002,
+ FlagTypeSingle
+ },
+ {
+ L"dad",
+ 0x00000008,
+ 0x00000004,
+ FlagTypeSingle
+ },
+ {
+ L"gw",
+ 0x00000010,
+ 0x00000008,
+ FlagTypeSingle
+ },
+ {
+ L"dns",
+ 0x00000020,
+ 0x00000010,
+ FlagTypeSingle
+ },
+ {
+ L"id",
+ 0x00000040,
+ 0x00000020,
+ FlagTypeSingle
+ },
+ {
+ NULL,
+ 0x0,
+ 0x0,
+ FlagTypeSkipUnknown
+ },
+};
+
+/**
+ Split a string with specified separator and save the substring to a list.
+
+ @param[in] String The pointer of the input string.
+ @param[in] Separator The specified separator.
+
+ @return The pointer of headnode of ARG_LIST.
+
+**/
+ARG_LIST *
+SplitStrToList (
+ IN CONST CHAR16 *String,
+ IN CHAR16 Separator
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ArgStr;
+ ARG_LIST *ArgList;
+ ARG_LIST *ArgNode;
+
+ if (*String == L'\0') {
+ return NULL;
+ }
+
+ //
+ // Copy the CONST string to a local copy.
+ //
+ Str = (CHAR16 *) AllocateZeroPool (StrSize (String));
+ ASSERT (Str != NULL);
+ Str = StrCpy (Str, String);
+ ArgStr = Str;
+
+ //
+ // init a node for the list head.
+ //
+ ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
+ ASSERT (ArgNode != NULL);
+ ArgList = ArgNode;
+
+ //
+ // Split the local copy and save in the list node.
+ //
+ while (*Str != L'\0') {
+ if (*Str == Separator) {
+ *Str = L'\0';
+ ArgNode->Arg = ArgStr;
+ ArgStr = Str + 1;
+ ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
+ ASSERT (ArgNode->Next != NULL);
+ ArgNode = ArgNode->Next;
+ }
+
+ Str++;
+ }
+
+ ArgNode->Arg = ArgStr;
+ ArgNode->Next = NULL;
+
+ return ArgList;
+}
+
+/**
+ Check the correctness of input Args with '-s' option.
+
+ @param[in] CheckList The pointer of VAR_CHECK_ITEM array.
+ @param[in] Name The pointer of input arg.
+ @param[in] Init The switch to execute the check.
+
+ @return The value of VAR_CHECK_CODE.
+
+**/
+VAR_CHECK_CODE
+IfConfig6RetriveCheckListByName(
+ IN VAR_CHECK_ITEM *CheckList,
+ IN CHAR16 *Name,
+ IN BOOLEAN Init
+)
+{
+ STATIC UINT32 CheckDuplicate;
+ STATIC UINT32 CheckConflict;
+ VAR_CHECK_CODE RtCode;
+ UINT32 Index;
+ VAR_CHECK_ITEM Arg;
+
+ if (Init) {
+ CheckDuplicate = 0;
+ CheckConflict = 0;
+ return VarCheckOk;
+ }
+
+ RtCode = VarCheckOk;
+ Index = 0;
+ Arg = CheckList[Index];
+
+ //
+ // Check the Duplicated/Conflicted/Unknown input Args.
+ //
+ while (Arg.FlagStr != NULL) {
+ if (StrCmp (Arg.FlagStr, Name) == 0) {
+
+ if (CheckDuplicate & Arg.FlagID) {
+ RtCode = VarCheckDuplicate;
+ break;
+ }
+
+ if (CheckConflict & Arg.ConflictMask) {
+ RtCode = VarCheckConflict;
+ break;
+ }
+
+ CheckDuplicate |= Arg.FlagID;
+ CheckConflict |= Arg.ConflictMask;
+ break;
+ }
+
+ Arg = CheckList[++Index];
+ }
+
+ if (Arg.FlagStr == NULL) {
+ RtCode = VarCheckUnknown;
+ }
+
+ return RtCode;
+}
+
+/**
+ The notify function of create event when performing a manual config.
+
+ @param[in] CheckList The pointer of Event.
+ @param[in] Context The pointer of Context.
+
+**/
+VOID
+EFIAPI
+IfConfig6ManualAddressNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ *((BOOLEAN *) Context) = TRUE;
+}
+
+/**
+ Print MAC address.
+
+ @param[in] Node The pointer of MAC address buffer.
+ @param[in] Size The size of MAC address buffer.
+
+**/
+VOID
+IfConfig6PrintMacAddr (
+ IN UINT8 *Node,
+ IN UINT32 Size
+ )
+{
+ UINTN Index;
+
+ ASSERT (Size <= MACADDRMAXSIZE);
+
+ for (Index = 0; Index < Size; Index++) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_BODY), mHiiHandle, Node[Index]);
+ if (Index + 1 < Size) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
+ }
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
+}
+
+/**
+ Print IPv6 address.
+
+ @param[in] Ip The pointer of Ip bufffer in EFI_IPv6_ADDRESS format.
+ @param[in] PrefixLen The pointer of PrefixLen that describes the size Prefix.
+
+**/
+VOID
+IfConfig6PrintIpAddr (
+ IN EFI_IPv6_ADDRESS *Ip,
+ IN UINT8 *PrefixLen
+ )
+{
+ UINTN Index;
+ BOOLEAN Short;
+
+ Short = FALSE;
+
+ for (Index = 0; Index < PREFIXMAXLEN; Index = Index + 2) {
+
+ if (!Short && (Index + 1 < PREFIXMAXLEN) && (Index % 2 == 0) && (Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0)) {
+ //
+ // Deal with the case of ::.
+ //
+ if (Index == 0) {
+ //
+ // :: is at the beginning of the address.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
+ }
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
+
+ while ((Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0) && (Index < PREFIXMAXLEN)) {
+ Index = Index + 2;
+ if (Index > PREFIXMAXLEN - 2) {
+ break;
+ }
+ }
+
+ Short = TRUE;
+
+ if (Index == PREFIXMAXLEN) {
+ //
+ // :: is at the end of the address.
+ //
+ break;
+ }
+ }
+
+ if (Index < PREFIXMAXLEN - 1) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), mHiiHandle, Ip->Addr[Index]);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), mHiiHandle, Ip->Addr[Index + 1]);
+ }
+
+ if (Index + 2 < PREFIXMAXLEN) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
+ }
+ }
+
+ if (PrefixLen != NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), mHiiHandle, *PrefixLen);
+ }
+}
+
+/**
+ Pick up host IPv6 address in string format from Args with "-s" option and convert it to EFI_IP6_CONFIG_MANUAL_ADDRESS format.
+
+ @param[in, out] Arg The pointer of the address of ARG_LIST which save Args with the "-s" option.
+ @param[out] Buf The pointer of the address of EFI_IP6_CONFIG_MANUAL_ADDRESS.
+ @param[out] Address The pointer of BufSize that describes the size of Buf in bytes.
+
+ @retval EFI_SUCCESS The convertion is successful.
+ @retval Others Does't find the host address, or it is an invalid IPv6 address in string format.
+
+**/
+EFI_STATUS
+IfConfig6ParseManualAddressList (
+ IN OUT ARG_LIST **Arg,
+ OUT EFI_IP6_CONFIG_MANUAL_ADDRESS **Buf,
+ OUT UINTN *BufSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_IP6_CONFIG_MANUAL_ADDRESS *AddrBuf;
+ ARG_LIST *VarArg;
+ EFI_IPv6_ADDRESS Address;
+ UINT8 Prefix;
+ UINT8 AddrCnt;
+
+ AddrCnt = 0;
+ *BufSize = 0;
+ *Buf = NULL;
+ VarArg = *Arg;
+ Status = EFI_SUCCESS;
+
+ //
+ // Go through the list to check the correctness of input host ip6 address.
+ //
+ while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
+
+ Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
+
+ if (EFI_ERROR (Status)) {
+ //
+ // host ip ip ... gw
+ //
+ break;
+ }
+
+ VarArg = VarArg->Next;
+ AddrCnt++;
+ }
+
+ if (AddrCnt == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));
+ ASSERT (AddrBuf != NULL);
+
+ AddrCnt = 0;
+ VarArg = *Arg;
+ Status = EFI_SUCCESS;
+
+ //
+ // Go through the list to fill in the EFI_IP6_CONFIG_MANUAL_ADDRESS structure.
+ //
+ while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
+
+ Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // If prefix length is not set, set it as Zero here. In the IfConfigSetInterfaceInfo()
+ // Zero prefix, length will be transfered to default prefix length.
+ //
+ if (Prefix == 0xFF) {
+ Prefix = 0;
+ }
+ AddrBuf[AddrCnt].IsAnycast = FALSE;
+ AddrBuf[AddrCnt].PrefixLength = Prefix;
+ IP6_COPY_ADDRESS (&AddrBuf[AddrCnt].Address, &Address);
+ VarArg = VarArg->Next;
+ AddrCnt++;
+ }
+
+ *Arg = VarArg;
+
+ if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {
+ goto ON_ERROR;
+ }
+
+ *Buf = AddrBuf;
+ *BufSize = AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+
+ FreePool (AddrBuf);
+ return Status;
+}
+
+/**
+ Pick up gw/dns IPv6 address in string format from Args with "-s" option and convert it to EFI_IPv6_ADDRESS format.
+
+ @param[in, out] Arg The pointer of the address of ARG_LIST that save Args with the "-s" option.
+ @param[out] Buf The pointer of the address of EFI_IPv6_ADDRESS.
+ @param[out] Address The pointer of BufSize that describes the size of Buf in bytes.
+
+ @retval EFI_SUCCESS The conversion is successful.
+ @retval Others Doesn't find the host address, or it is an invalid IPv6 address in string format.
+
+**/
+EFI_STATUS
+IfConfig6ParseGwDnsAddressList (
+ IN OUT ARG_LIST **Arg,
+ OUT EFI_IPv6_ADDRESS **Buf,
+ OUT UINTN *BufSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_IPv6_ADDRESS *AddrBuf;
+ ARG_LIST *VarArg;
+ EFI_IPv6_ADDRESS Address;
+ UINT8 Prefix;
+ UINT8 AddrCnt;
+
+ AddrCnt = 0;
+ *BufSize = 0;
+ *Buf = NULL;
+ VarArg = *Arg;
+ Status = EFI_SUCCESS;
+
+ //
+ // Go through the list to check the correctness of input gw/dns address.
+ //
+ while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
+
+ Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
+
+ if (EFI_ERROR (Status)) {
+ //
+ // gw ip ip ... host
+ //
+ break;
+ }
+
+ VarArg = VarArg->Next;
+ AddrCnt++;
+ }
+
+ if (AddrCnt == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IPv6_ADDRESS));
+ ASSERT (AddrBuf != NULL);
+
+ AddrCnt = 0;
+ VarArg = *Arg;
+ Status = EFI_SUCCESS;
+
+ //
+ // Go through the list to fill in the EFI_IPv6_ADDRESS structure.
+ //
+ while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
+
+ Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ IP6_COPY_ADDRESS (&AddrBuf[AddrCnt], &Address);
+
+ VarArg = VarArg->Next;
+ AddrCnt++;
+ }
+
+ *Arg = VarArg;
+
+ if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {
+ goto ON_ERROR;
+ }
+
+ *Buf = AddrBuf;
+ *BufSize = AddrCnt * sizeof (EFI_IPv6_ADDRESS);
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+
+ FreePool (AddrBuf);
+ return Status;
+}
+
+/**
+ Parse InterfaceId in string format from Args with the "-s" option and convert it to EFI_IP6_CONFIG_INTERFACE_ID format.
+
+ @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
+ @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
+
+ @retval EFI_SUCCESS The get status processed successfullly.
+ @retval EFI_INVALID_PARAMETER The get status process failed.
+
+**/
+EFI_STATUS
+IfConfig6ParseInterfaceId (
+ IN OUT ARG_LIST **Arg,
+ OUT EFI_IP6_CONFIG_INTERFACE_ID **IfId
+ )
+{
+ UINT8 Index;
+ UINT8 NodeVal;
+ CHAR16 *IdStr;
+
+ if (*Arg == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Index = 0;
+ IdStr = (*Arg)->Arg;
+ ASSERT (IfId != NULL);
+ *IfId = AllocateZeroPool (sizeof (EFI_IP6_CONFIG_INTERFACE_ID));
+ ASSERT (*IfId != NULL);
+
+ while ((*IdStr != L'\0') && (Index < 8)) {
+
+ NodeVal = 0;
+ while ((*IdStr != L':') && (*IdStr != L'\0')) {
+
+ if ((*IdStr <= L'F') && (*IdStr >= L'A')) {
+ NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'A' + 10);
+ } else if ((*IdStr <= L'f') && (*IdStr >= L'a')) {
+ NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'a' + 10);
+ } else if ((*IdStr <= L'9') && (*IdStr >= L'0')) {
+ NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'0');
+ } else {
+ FreePool (*IfId);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IdStr++;
+ }
+
+ (*IfId)->Id[Index++] = NodeVal;
+
+ if (*IdStr == L':') {
+ IdStr++;
+ }
+ }
+
+ *Arg = (*Arg)->Next;
+ return EFI_SUCCESS;
+}
+
+/**
+ Parse dad in string format from Args with the "-s" option and convert it to UINT32 format.
+
+ @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
+ @param[out] Xmits The pointer of Xmits.
+
+ @retval EFI_SUCCESS The get status processed successfully.
+ @retval others The get status process failed.
+
+**/
+EFI_STATUS
+IfConfig6ParseDadXmits (
+ IN OUT ARG_LIST **Arg,
+ OUT UINT32 *Xmits
+ )
+{
+ CHAR16 *ValStr;
+
+ if (*Arg == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ValStr = (*Arg)->Arg;
+ *Xmits = 0;
+
+ while (*ValStr != L'\0') {
+
+ if ((*ValStr <= L'9') && (*ValStr >= L'0')) {
+
+ *Xmits = (*Xmits * 10) + (*ValStr - L'0');
+
+ } else {
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ValStr++;
+ }
+
+ *Arg = (*Arg)->Next;
+ return EFI_SUCCESS;
+}
+
+/**
+ The get current status of all handles.
+
+ @param[in] ImageHandle The handle of ImageHandle.
+ @param[in] IfName The pointer of IfName(interface name).
+ @param[in] IfList The pointer of IfList(interface list).
+
+ @retval EFI_SUCCESS The get status processed successfully.
+ @retval others The get status process failed.
+
+**/
+EFI_STATUS
+IfConfig6GetInterfaceInfo (
+ IN EFI_HANDLE ImageHandle,
+ IN CHAR16 *IfName,
+ IN LIST_ENTRY *IfList
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleIndex;
+ UINTN HandleNum;
+ EFI_HANDLE *HandleBuffer;
+ EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
+ EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
+ IFCONFIG6_INTERFACE_CB *IfCb;
+ UINTN DataSize;
+
+ HandleBuffer = NULL;
+ HandleNum = 0;
+
+ IfInfo = NULL;
+ IfCb = NULL;
+
+ //
+ // Locate all the handles with ip6 service binding protocol.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiIp6ServiceBindingProtocolGuid,
+ NULL,
+ &HandleNum,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status) || (HandleNum == 0)) {
+ return EFI_ABORTED;
+ }
+
+ //
+ // Enumerate all handles that installed with ip6 service binding protocol.
+ //
+ for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {
+ IfCb = NULL;
+ IfInfo = NULL;
+ DataSize = 0;
+
+ //
+ // Ip6config protocol and ip6 service binding protocol are installed
+ // on the same handle.
+ //
+ ASSERT (HandleBuffer != NULL);
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gEfiIp6ConfigProtocolGuid,
+ (VOID **) &Ip6Cfg
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+ //
+ // Get the interface information size.
+ //
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ NULL
+ );
+
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+
+ IfInfo = AllocateZeroPool (DataSize);
+
+ if (IfInfo == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+ //
+ // Get the interface info.
+ //
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ IfInfo
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+ //
+ // Check the interface name if required.
+ //
+ if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) {
+ FreePool (IfInfo);
+ continue;
+ }
+
+ DataSize = 0;
+ //
+ // Get the size of dns server list.
+ //
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeDnsServer,
+ &DataSize,
+ NULL
+ );
+
+ if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+
+ IfCb = AllocateZeroPool (sizeof (IFCONFIG6_INTERFACE_CB) + DataSize);
+
+ if (IfCb == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+
+ IfCb->NicHandle = HandleBuffer[HandleIndex];
+ IfCb->IfInfo = IfInfo;
+ IfCb->IfCfg = Ip6Cfg;
+ IfCb->DnsCnt = (UINT32) (DataSize / sizeof (EFI_IPv6_ADDRESS));
+
+ //
+ // Get the dns server list if has.
+ //
+ if (DataSize > 0) {
+
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeDnsServer,
+ &DataSize,
+ IfCb->DnsAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+ }
+ //
+ // Get the interface id if has.
+ //
+ DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
+ IfCb->IfId = AllocateZeroPool (DataSize);
+
+ if (IfCb->IfId == NULL) {
+ goto ON_ERROR;
+ }
+
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeAltInterfaceId,
+ &DataSize,
+ IfCb->IfId
+ );
+
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+
+ if (Status == EFI_NOT_FOUND) {
+ FreePool (IfCb->IfId);
+ IfCb->IfId = NULL;
+ }
+ //
+ // Get the config policy.
+ //
+ DataSize = sizeof (EFI_IP6_CONFIG_POLICY);
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypePolicy,
+ &DataSize,
+ &IfCb->Policy
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+ //
+ // Get the dad transmits.
+ //
+ DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeDupAddrDetectTransmits,
+ &DataSize,
+ &IfCb->Xmits
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+
+ InsertTailList (IfList, &IfCb->Link);
+
+ if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) {
+ //
+ // Only need the appointed interface, keep the allocated buffer.
+ //
+ IfCb = NULL;
+ IfInfo = NULL;
+ break;
+ }
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+
+ if (IfInfo != NULL) {
+ FreePool (IfInfo);
+ }
+
+ if (IfCb != NULL) {
+ if (IfCb->IfId != NULL) {
+ FreePool (IfCb->IfId);
+ }
+
+ FreePool (IfCb);
+ }
+
+ return Status;
+}
+
+/**
+ The list process of the IfConfig6 application.
+
+ @param[in] IfList The pointer of IfList(interface list).
+
+ @retval EFI_SUCCESS The IfConfig6 list processed successfully.
+ @retval others The IfConfig6 list process failed.
+
+**/
+EFI_STATUS
+IfConfig6ShowInterfaceInfo (
+ IN LIST_ENTRY *IfList
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Entry;
+ IFCONFIG6_INTERFACE_CB *IfCb;
+ UINTN Index;
+
+ Entry = IfList->ForwardLink;
+ Status = EFI_SUCCESS;
+
+ if (IsListEmpty (IfList)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);
+ }
+
+ //
+ // Go through the interface list.
+ //
+ while (Entry != IfList) {
+
+ IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), mHiiHandle);
+
+ //
+ // Print interface name.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME), mHiiHandle, IfCb->IfInfo->Name);
+
+ //
+ // Print interface config policy.
+ //
+ if (IfCb->Policy == Ip6ConfigPolicyAutomatic) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO), mHiiHandle);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN), mHiiHandle);
+ }
+
+ //
+ // Print dad transmit.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS), mHiiHandle, IfCb->Xmits);
+
+ //
+ // Print interface id if has.
+ //
+ if (IfCb->IfId != NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD), mHiiHandle);
+
+ IfConfig6PrintMacAddr (
+ IfCb->IfId->Id,
+ 8
+ );
+ }
+ //
+ // Print mac address of the interface.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD), mHiiHandle);
+
+ IfConfig6PrintMacAddr (
+ IfCb->IfInfo->HwAddress.Addr,
+ IfCb->IfInfo->HwAddressSize
+ );
+
+ //
+ // Print ip addresses list of the interface.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_HEAD), mHiiHandle);
+
+ for (Index = 0; Index < IfCb->IfInfo->AddressInfoCount; Index++) {
+ IfConfig6PrintIpAddr (
+ &IfCb->IfInfo->AddressInfo[Index].Address,
+ &IfCb->IfInfo->AddressInfo[Index].PrefixLength
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
+ }
+
+ //
+ // Print dns server addresses list of the interface if has.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD), mHiiHandle);
+
+ for (Index = 0; Index < IfCb->DnsCnt; Index++) {
+ IfConfig6PrintIpAddr (
+ &IfCb->DnsAddr[Index],
+ NULL
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
+ }
+
+ //
+ // Print route table of the interface if has.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD), mHiiHandle);
+
+ for (Index = 0; Index < IfCb->IfInfo->RouteCount; Index++) {
+ IfConfig6PrintIpAddr (
+ &IfCb->IfInfo->RouteTable[Index].Destination,
+ &IfCb->IfInfo->RouteTable[Index].PrefixLength
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_JOINT), mHiiHandle);
+
+ IfConfig6PrintIpAddr (
+ &IfCb->IfInfo->RouteTable[Index].Gateway,
+ NULL
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
+ }
+
+ Entry = Entry->ForwardLink;
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), mHiiHandle);
+
+ return Status;
+}
+
+/**
+ The clean process of the IfConfig6 application.
+
+ @param[in] IfList The pointer of IfList(interface list).
+
+ @retval EFI_SUCCESS The IfConfig6 clean processed successfully.
+ @retval others The IfConfig6 clean process failed.
+
+**/
+EFI_STATUS
+IfConfig6ClearInterfaceInfo (
+ IN LIST_ENTRY *IfList
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Entry;
+ IFCONFIG6_INTERFACE_CB *IfCb;
+ EFI_IP6_CONFIG_POLICY Policy;
+
+ Policy = Ip6ConfigPolicyAutomatic;
+ Entry = IfList->ForwardLink;
+ Status = EFI_SUCCESS;
+
+ if (IsListEmpty (IfList)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);
+ }
+
+ //
+ // Go through the interface list.
+ //
+ while (Entry != IfList) {
+
+ IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
+
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypePolicy,
+ sizeof (EFI_IP6_CONFIG_POLICY),
+ &Policy
+ );
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ Entry = Entry->ForwardLink;
+ }
+
+ return Status;
+}
+
+/**
+ The set process of the IfConfig6 application.
+
+ @param[in] IfList The pointer of IfList(interface list).
+ @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option).
+
+ @retval EFI_SUCCESS The IfConfig6 set processed successfully.
+ @retval others The IfConfig6 set process failed.
+
+**/
+EFI_STATUS
+IfConfig6SetInterfaceInfo (
+ IN LIST_ENTRY *IfList,
+ IN ARG_LIST *VarArg
+ )
+{
+ EFI_STATUS Status;
+ IFCONFIG6_INTERFACE_CB *IfCb;
+ EFI_IP6_CONFIG_MANUAL_ADDRESS *CfgManAddr;
+ EFI_IPv6_ADDRESS *CfgAddr;
+ UINTN AddrSize;
+ EFI_IP6_CONFIG_INTERFACE_ID *InterfaceId;
+ UINT32 DadXmits;
+ UINT32 CurDadXmits;
+ UINTN CurDadXmitsLen;
+ EFI_IP6_CONFIG_POLICY Policy;
+
+ VAR_CHECK_CODE CheckCode;
+ EFI_EVENT TimeOutEvt;
+ EFI_EVENT MappedEvt;
+ BOOLEAN IsAddressOk;
+
+ UINTN DataSize;
+ UINT32 Index;
+ UINT32 Index2;
+ BOOLEAN IsAddressSet;
+ EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
+
+ CfgManAddr = NULL;
+ CfgAddr = NULL;
+ TimeOutEvt = NULL;
+ MappedEvt = NULL;
+ IfInfo = NULL;
+ InterfaceId = NULL;
+ CurDadXmits = 0;
+
+ if (IsListEmpty (IfList)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle);
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Make sure to set only one interface each time.
+ //
+ IfCb = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link);
+ Status = EFI_SUCCESS;
+
+ //
+ // Initialize check list mechanism.
+ //
+ CheckCode = IfConfig6RetriveCheckListByName(
+ NULL,
+ NULL,
+ TRUE
+ );
+
+ //
+ // Create events & timers for asynchronous settings.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &TimeOutEvt
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IfConfig6ManualAddressNotify,
+ &IsAddressOk,
+ &MappedEvt
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Parse the setting variables.
+ //
+ while (VarArg != NULL) {
+ //
+ // Check invalid parameters (duplication & unknown & conflict).
+ //
+ CheckCode = IfConfig6RetriveCheckListByName(
+ mSetCheckList,
+ VarArg->Arg,
+ FALSE
+ );
+
+ if (VarCheckOk != CheckCode) {
+ switch (CheckCode) {
+ case VarCheckDuplicate:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), mHiiHandle, VarArg->Arg);
+ break;
+
+ case VarCheckConflict:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), mHiiHandle, VarArg->Arg);
+ break;
+
+ case VarCheckUnknown:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), mHiiHandle, VarArg->Arg);
+ break;
+
+ default:
+ break;
+ }
+
+ VarArg = VarArg->Next;
+ continue;
+ }
+ //
+ // Process valid variables.
+ //
+ if (StrCmp(VarArg->Arg, L"auto") == 0) {
+ //
+ // Set automaic config policy
+ //
+ Policy = Ip6ConfigPolicyAutomatic;
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypePolicy,
+ sizeof (EFI_IP6_CONFIG_POLICY),
+ &Policy
+ );
+
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+
+ VarArg= VarArg->Next;
+
+ } else if (StrCmp (VarArg->Arg, L"man") == 0) {
+ //
+ // Set manual config policy.
+ //
+ Policy = Ip6ConfigPolicyManual;
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypePolicy,
+ sizeof (EFI_IP6_CONFIG_POLICY),
+ &Policy
+ );
+
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+
+ VarArg= VarArg->Next;
+
+ } else if (StrCmp (VarArg->Arg, L"host") == 0) {
+ //
+ // Parse till the next tag or the end of command line.
+ //
+ VarArg = VarArg->Next;
+ Status = IfConfig6ParseManualAddressList (
+ &VarArg,
+ &CfgManAddr,
+ &AddrSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_INVALID_PARAMETER) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"host");
+ continue;
+ } else {
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Set static host ip6 address list.
+ // This is a asynchronous process.
+ //
+ IsAddressOk = FALSE;
+
+ Status = IfCb->IfCfg->RegisterDataNotify (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeManualAddress,
+ MappedEvt
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeManualAddress,
+ AddrSize,
+ CfgManAddr
+ );
+
+ if (Status == EFI_NOT_READY) {
+ //
+ // Get current dad transmits count.
+ //
+ CurDadXmitsLen = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
+ IfCb->IfCfg->GetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeDupAddrDetectTransmits,
+ &CurDadXmitsLen,
+ &CurDadXmits
+ );
+
+ gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000 + 10000000 * CurDadXmits);
+
+ while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {
+ if (IsAddressOk) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ IfCb->IfCfg->UnregisterDataNotify (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeManualAddress,
+ MappedEvt
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST), mHiiHandle, Status);
+ goto ON_EXIT;
+ }
+
+ //
+ // Check whether the address is set successfully.
+ //
+ DataSize = 0;
+
+ Status = IfCb->IfCfg->GetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ NULL
+ );
+
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_EXIT;
+ }
+
+ IfInfo = AllocateZeroPool (DataSize);
+
+ if (IfInfo == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = IfCb->IfCfg->GetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ IfInfo
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_EXIT;
+ }
+
+ for ( Index = 0; Index < (UINTN) (AddrSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); Index++) {
+ IsAddressSet = FALSE;
+ //
+ // By default, the prefix length 0 is regarded as 64.
+ //
+ if (CfgManAddr[Index].PrefixLength == 0) {
+ CfgManAddr[Index].PrefixLength = 64;
+ }
+
+ for (Index2 = 0; Index2 < IfInfo->AddressInfoCount; Index2++) {
+ if (EFI_IP6_EQUAL (&IfInfo->AddressInfo[Index2].Address, &CfgManAddr[Index].Address) &&
+ (IfInfo->AddressInfo[Index2].PrefixLength == CfgManAddr[Index].PrefixLength)) {
+ IsAddressSet = TRUE;
+ break;
+ }
+ }
+
+ if (!IsAddressSet) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED), mHiiHandle);
+ IfConfig6PrintIpAddr (
+ &CfgManAddr[Index].Address,
+ &CfgManAddr[Index].PrefixLength
+ );
+ }
+ }
+
+ } else if (StrCmp (VarArg->Arg, L"gw") == 0) {
+ //
+ // Parse till the next tag or the end of command line.
+ //
+ VarArg = VarArg->Next;
+ Status = IfConfig6ParseGwDnsAddressList (
+ &VarArg,
+ &CfgAddr,
+ &AddrSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_INVALID_PARAMETER) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"gw");
+ continue;
+ } else {
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Set static gateway ip6 address list.
+ //
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeGateway,
+ AddrSize,
+ CfgAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ } else if (StrCmp (VarArg->Arg, L"dns") == 0) {
+ //
+ // Parse till the next tag or the end of command line.
+ //
+ VarArg = VarArg->Next;
+ Status = IfConfig6ParseGwDnsAddressList (
+ &VarArg,
+ &CfgAddr,
+ &AddrSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_INVALID_PARAMETER) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"dns");
+ continue;
+ } else {
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Set static dhs server ip6 address list.
+ //
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeDnsServer,
+ AddrSize,
+ CfgAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ } else if (StrCmp (VarArg->Arg, L"id") == 0) {
+ //
+ // Parse till the next tag or the end of command line.
+ //
+ VarArg = VarArg->Next;
+ Status = IfConfig6ParseInterfaceId (&VarArg, &InterfaceId);
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Set alternative interface id.
+ //
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeAltInterfaceId,
+ sizeof (EFI_IP6_CONFIG_INTERFACE_ID),
+ InterfaceId
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ } else if (StrCmp (VarArg->Arg, L"dad") == 0) {
+ //
+ // Parse till the next tag or the end of command line.
+ //
+ VarArg = VarArg->Next;
+ Status = IfConfig6ParseDadXmits (&VarArg, &DadXmits);
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Set dad transmits count.
+ //
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeDupAddrDetectTransmits,
+ sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),
+ &DadXmits
+ );
+
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+ }
+ }
+
+ON_EXIT:
+
+ if (CfgManAddr != NULL) {
+ FreePool (CfgManAddr);
+ }
+
+ if (CfgAddr != NULL) {
+ FreePool (CfgAddr);
+ }
+
+ if (MappedEvt != NULL) {
+ gBS->CloseEvent (MappedEvt);
+ }
+
+ if (TimeOutEvt != NULL) {
+ gBS->CloseEvent (TimeOutEvt);
+ }
+
+ if (IfInfo != NULL) {
+ FreePool (IfInfo);
+ }
+
+ return Status;
+
+}
+
+/**
+ The IfConfig6 main process.
+
+ @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS IfConfig6 processed successfully.
+ @retval others The IfConfig6 process failed.
+
+**/
+EFI_STATUS
+IfConfig6 (
+ IN IFCONFIG6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Get configure information of all interfaces.
+ //
+ Status = IfConfig6GetInterfaceInfo (
+ Private->ImageHandle,
+ Private->IfName,
+ &Private->IfList
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ switch (Private->OpCode) {
+ case IfConfig6OpList:
+ Status = IfConfig6ShowInterfaceInfo (&Private->IfList);
+ break;
+
+ case IfConfig6OpClear:
+ Status = IfConfig6ClearInterfaceInfo (&Private->IfList);
+ break;
+
+ case IfConfig6OpSet:
+ Status = IfConfig6SetInterfaceInfo (&Private->IfList, Private->VarArg);
+ break;
+
+ default:
+ Status = EFI_ABORTED;
+ }
+
+ON_EXIT:
+
+ return Status;
+}
+
+/**
+ The IfConfig6 cleanup process, free the allocated memory.
+
+ @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
+
+**/
+VOID
+IfConfig6Cleanup (
+ IN IFCONFIG6_PRIVATE_DATA *Private
+ )
+{
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *NextEntry;
+ IFCONFIG6_INTERFACE_CB *IfCb;
+ ARG_LIST *ArgNode;
+ ARG_LIST *ArgHead;
+
+ ASSERT (Private != NULL);
+
+ //
+ // Clean the list which save the set config Args.
+ //
+ if (Private->VarArg != NULL) {
+ ArgHead = Private->VarArg;
+
+ while (ArgHead->Next != NULL) {
+ ArgNode = ArgHead->Next;
+ FreePool (ArgHead);
+ ArgHead = ArgNode;
+ }
+
+ FreePool (ArgHead);
+ }
+
+ if (Private->IfName != NULL)
+ FreePool (Private->IfName);
+
+
+ //
+ // Clean the IFCONFIG6_INTERFACE_CB list.
+ //
+ Entry = Private->IfList.ForwardLink;
+ NextEntry = Entry->ForwardLink;
+
+ while (Entry != &Private->IfList) {
+
+ IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
+
+ RemoveEntryList (&IfCb->Link);
+
+ if (IfCb->IfId != NULL) {
+
+ FreePool (IfCb->IfId);
+ }
+
+ if (IfCb->IfInfo != NULL) {
+
+ FreePool (IfCb->IfInfo);
+ }
+
+ FreePool (IfCb);
+
+ Entry = NextEntry;
+ NextEntry = Entry->ForwardLink;
+ }
+
+ FreePool (Private);
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
+ both device drivers and bus drivers.
+
+ The entry point for the IfConfig6 application which parses the command line input and calls the IfConfig6 process.
+
+ @param[in] ImageHandle The image handle of this application.
+ @param[in] SystemTable The pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others Some errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+IfConfig6Initialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ IFCONFIG6_PRIVATE_DATA *Private;
+ LIST_ENTRY *ParamPackage;
+ CONST CHAR16 *ValueStr;
+ ARG_LIST *ArgList;
+ CHAR16 *ProblemParam;
+ CHAR16 *Str;
+
+ Private = NULL;
+
+ //
+ // Register our string package with HII and return the handle to it.
+ //
+ mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, IfConfig6Strings, NULL);
+ ASSERT (mHiiHandle != NULL);
+
+ Status = ShellCommandLineParseEx (mIfConfig6CheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND), mHiiHandle, ProblemParam);
+ goto ON_EXIT;
+ }
+
+ //
+ // To handle no option.
+ //
+ if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") &&
+ !ShellCommandLineGetFlag (ParamPackage, L"-?") && !ShellCommandLineGetFlag (ParamPackage, L"-l")) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_LACK_OPTION), mHiiHandle);
+ goto ON_EXIT;
+ }
+ //
+ // To handle conflict options.
+ //
+ if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) ||
+ ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||
+ ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||
+ ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||
+ ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||
+ ((ShellCommandLineGetFlag (ParamPackage, L"-l")) && (ShellCommandLineGetFlag (ParamPackage, L"-?")))) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_CONFLICT_OPTIONS), mHiiHandle);
+ goto ON_EXIT;
+ }
+ //
+ // To show the help information of ifconfig6 command.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-?")) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_HELP), mHiiHandle);
+ goto ON_EXIT;
+ }
+
+ Status = EFI_INVALID_PARAMETER;
+
+ Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));
+
+ if (Private == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ InitializeListHead (&Private->IfList);
+
+ //
+ // To get interface name for the list option.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {
+ Private->OpCode = IfConfig6OpList;
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");
+ if (ValueStr != NULL) {
+ Str = (CHAR16 *) AllocateZeroPool (StrSize (ValueStr));
+ ASSERT (Str != NULL);
+
+ Str = StrCpy (Str, ValueStr);
+ Private->IfName = Str;
+ }
+ }
+ //
+ // To get interface name for the clear option.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-r")) {
+ Private->OpCode = IfConfig6OpClear;
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r");
+ if (ValueStr != NULL) {
+ Str = (CHAR16 *) AllocateZeroPool (StrSize (ValueStr));
+ ASSERT (Str != NULL);
+
+ Str = StrCpy (Str, ValueStr);
+ Private->IfName = Str;
+ }
+ }
+ //
+ // To get interface name and corresponding Args for the set option.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-s")) {
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");
+ if (ValueStr == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_INTERFACE), mHiiHandle);
+ goto ON_EXIT;
+ }
+ //
+ // To split the configuration into multi-section.
+ //
+ ArgList = SplitStrToList (ValueStr, L' ');
+ ASSERT (ArgList != NULL);
+
+ Private->OpCode = IfConfig6OpSet;
+ Private->IfName = ArgList->Arg;
+
+ Private->VarArg = ArgList->Next;
+
+ if (Private->IfName == NULL || Private->VarArg == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_COMMAND), mHiiHandle);
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Main process of ifconfig6.
+ //
+ Status = IfConfig6 (Private);
+
+ON_EXIT:
+
+ ShellCommandLineFreeVarList (ParamPackage);
+ HiiRemovePackages (mHiiHandle);
+ if (Private != NULL)
+ IfConfig6Cleanup (Private);
+
+ return Status;
+}
+
diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6.h b/NetworkPkg/Application/IfConfig6/IfConfig6.h new file mode 100644 index 0000000000..eea7df55d1 --- /dev/null +++ b/NetworkPkg/Application/IfConfig6/IfConfig6.h @@ -0,0 +1,84 @@ +/** @file
+ The interface function declaration of shell application IfConfig6.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _IFCONFIG6_H_
+#define _IFCONFIG6_H_
+
+#define EFI_IFCONFIG6_GUID \
+ { \
+ 0xbab7296b, 0x222c, 0x4408, {0x9e, 0x6c, 0xc2, 0x5c, 0x18, 0x7e, 0xff, 0x33} \
+ }
+
+enum {
+ IfConfig6OpList = 1,
+ IfConfig6OpSet = 2,
+ IfConfig6OpClear = 3
+};
+
+typedef enum {
+ VarCheckReserved = -1,
+ VarCheckOk = 0,
+ VarCheckDuplicate,
+ VarCheckConflict,
+ VarCheckUnknown,
+ VarCheckLackValue,
+ VarCheckOutOfMem
+} VAR_CHECK_CODE;
+
+typedef enum {
+ FlagTypeSingle = 0,
+ FlagTypeNeedVar,
+ FlagTypeNeedSet,
+ FlagTypeSkipUnknown
+} VAR_CHECK_FLAG_TYPE;
+
+#define MACADDRMAXSIZE 32
+#define PREFIXMAXLEN 16
+
+typedef struct _IFCONFIG6_INTERFACE_CB {
+ EFI_HANDLE NicHandle;
+ LIST_ENTRY Link;
+ EFI_IP6_CONFIG_PROTOCOL *IfCfg;
+ EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
+ EFI_IP6_CONFIG_INTERFACE_ID *IfId;
+ EFI_IP6_CONFIG_POLICY Policy;
+ EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS Xmits;
+ UINT32 DnsCnt;
+ EFI_IPv6_ADDRESS DnsAddr[1];
+} IFCONFIG6_INTERFACE_CB;
+
+typedef struct _ARG_LIST ARG_LIST;
+
+struct _ARG_LIST {
+ ARG_LIST *Next;
+ CHAR16 *Arg;
+};
+
+typedef struct _IFCONFIG6_PRIVATE_DATA {
+ EFI_HANDLE ImageHandle;
+ LIST_ENTRY IfList;
+
+ UINT32 OpCode;
+ CHAR16 *IfName;
+ ARG_LIST *VarArg;
+} IFCONFIG6_PRIVATE_DATA;
+
+typedef struct _VAR_CHECK_ITEM{
+ CHAR16 *FlagStr;
+ UINT32 FlagID;
+ UINT32 ConflictMask;
+ VAR_CHECK_FLAG_TYPE FlagType;
+} VAR_CHECK_ITEM;
+#endif
diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6.inf b/NetworkPkg/Application/IfConfig6/IfConfig6.inf new file mode 100644 index 0000000000..dd3ab64493 --- /dev/null +++ b/NetworkPkg/Application/IfConfig6/IfConfig6.inf @@ -0,0 +1,52 @@ +## @file
+# Component description file for Shell application IfConfig6.
+#
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = IfConfig6
+ FILE_GUID = 6F71926E-60CE-428d-AA58-A3D9FB879429
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = IfConfig6Initialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+[Sources]
+ IfConfig6Strings.uni
+ IfConfig6.c
+ IfConfig6.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
+ UefiApplicationEntryPoint
+ BaseMemoryLib
+ ShellLib
+ MemoryAllocationLib
+ DebugLib
+ HiiLib
+ NetLib
+
+[Protocols]
+ gEfiIp6ServiceBindingProtocolGuid ## CONSUMS
+ gEfiIp6ConfigProtocolGuid ## CONSUMS
diff --git a/NetworkPkg/Application/IfConfig6/IfConfig6Strings.uni b/NetworkPkg/Application/IfConfig6/IfConfig6Strings.uni Binary files differnew file mode 100644 index 0000000000..a5e7fd04cf --- /dev/null +++ b/NetworkPkg/Application/IfConfig6/IfConfig6Strings.uni diff --git a/NetworkPkg/Application/IpsecConfig/Delete.c b/NetworkPkg/Application/IpsecConfig/Delete.c new file mode 100644 index 0000000000..caeb1c8350 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Delete.c @@ -0,0 +1,110 @@ +/** @file
+ The implementation of delete policy entry function in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IpSecConfig.h"
+#include "Indexer.h"
+#include "Delete.h"
+#include "Match.h"
+#include "ForEach.h"
+
+/**
+ Private function to delete entry information in database.
+
+ @param[in] Selector The pointer to EFI_IPSEC_CONFIG_SELECTOR structure.
+ @param[in] Data The pointer to Data.
+ @param[in] Context The pointer to DELETE_POLICY_ENTRY_CONTEXT.
+
+ @retval EFI_ABORTED Abort the iteration.
+ @retval EFI_SUCCESS Continue the iteration.
+**/
+EFI_STATUS
+DeletePolicyEntry (
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
+ IN VOID *Data,
+ IN DELETE_POLICY_ENTRY_CONTEXT *Context
+ )
+{
+ if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {
+ Context->Status = mIpSecConfig->SetData (
+ mIpSecConfig,
+ Context->DataType,
+ Selector,
+ NULL,
+ NULL
+ );
+ //
+ // Abort the iteration after the insertion.
+ //
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Flush or delete entry information in the database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Delete entry information successfully.
+ @retval EFI_NOT_FOUND Can't find the specified entry.
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+FlushOrDeletePolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ )
+{
+ EFI_STATUS Status;
+ DELETE_POLICY_ENTRY_CONTEXT Context;
+ CONST CHAR16 *ValueStr;
+
+ //
+ // If user wants to remove all.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-f")) {
+ Status = mIpSecConfig->SetData (
+ mIpSecConfig,
+ DataType,
+ NULL,
+ NULL,
+ NULL
+ );
+ } else {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");
+ if (ValueStr == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);
+ return EFI_NOT_FOUND;
+ }
+
+ Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);
+ if (!EFI_ERROR (Status)) {
+ Context.DataType = DataType;
+ Context.Status = EFI_NOT_FOUND;
+ ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) DeletePolicyEntry, &Context);
+ Status = Context.Status;
+
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);
+ } else if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DELETE_FAILED), mHiiHandle, mAppName);
+ }
+ }
+ }
+
+ return Status;
+}
diff --git a/NetworkPkg/Application/IpsecConfig/Delete.h b/NetworkPkg/Application/IpsecConfig/Delete.h new file mode 100644 index 0000000000..49f3b0d5fa --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Delete.h @@ -0,0 +1,42 @@ +/** @file
+ The internal structure and function declaration of delete policy entry function
+ in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __DELETE_H_
+#define __DELETE_H_
+
+typedef struct {
+ EFI_IPSEC_CONFIG_DATA_TYPE DataType;
+ POLICY_ENTRY_INDEXER Indexer;
+ EFI_STATUS Status; //Indicate whether deletion succeeds.
+} DELETE_POLICY_ENTRY_CONTEXT;
+
+/**
+ Flush or delete entry information in the database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Delete entry information successfully.
+ @retval EFI_NOT_FOUND Can't find the specified entry.
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+FlushOrDeletePolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ );
+
+#endif
diff --git a/NetworkPkg/Application/IpsecConfig/Dump.c b/NetworkPkg/Application/IpsecConfig/Dump.c new file mode 100644 index 0000000000..004ab1089c --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Dump.c @@ -0,0 +1,530 @@ +/** @file
+ The implementation of dump policy entry function in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IpSecConfig.h"
+#include "Dump.h"
+#include "ForEach.h"
+#include "Helper.h"
+
+/**
+ Private function called to get the version infomation from an EFI_IP_ADDRESS_INFO structure.
+
+ @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure.
+
+ @return the value of version.
+**/
+UINTN
+GetVerFromAddrInfo (
+ IN EFI_IP_ADDRESS_INFO *AddressInfo
+)
+{
+ if((AddressInfo->PrefixLength <= 32) && (AddressInfo->Address.Addr[1] == 0) &&
+ (AddressInfo->Address.Addr[2] == 0) && (AddressInfo->Address.Addr[3] == 0)) {
+ return IP_VERSION_4;
+ } else {
+ return IP_VERSION_6;
+ }
+}
+
+/**
+ Private function called to get the version information from a EFI_IP_ADDRESS structure.
+
+ @param[in] Address The pointer to the EFI_IP_ADDRESS structure.
+
+ @return The value of the version.
+**/
+UINTN
+GetVerFromIpAddr (
+ IN EFI_IP_ADDRESS *Address
+)
+{
+ if ((Address->Addr[1] == 0) && (Address->Addr[2] == 0) && (Address->Addr[3] == 0)) {
+ return IP_VERSION_4;
+ } else {
+ return IP_VERSION_6;
+ }
+}
+
+/**
+ Private function called to print an ASCII string in unicode char format.
+
+ @param[in] Str The pointer to the ASCII string.
+ @param[in] Length The value of the ASCII string length.
+**/
+VOID
+DumpAsciiString (
+ IN CHAR8 *Str,
+ IN UINTN Length
+ )
+{
+ UINTN Index;
+ for (Index = 0; Index < Length; Index++) {
+ Print (L"%c", (CHAR16) Str[Index]);
+ }
+}
+
+/**
+ Private function called to print EFI_IP_ADDRESS_INFO content.
+
+ @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure.
+**/
+VOID
+DumpAddressInfo (
+ IN EFI_IP_ADDRESS_INFO *AddressInfo
+ )
+{
+ if (IP_VERSION_4 == GetVerFromAddrInfo (AddressInfo)) {
+ Print (
+ L"%d.%d.%d.%d",
+ (UINTN) AddressInfo->Address.v4.Addr[0],
+ (UINTN) AddressInfo->Address.v4.Addr[1],
+ (UINTN) AddressInfo->Address.v4.Addr[2],
+ (UINTN) AddressInfo->Address.v4.Addr[3]
+ );
+ if (AddressInfo->PrefixLength != 32) {
+ Print (L"/%d", (UINTN) AddressInfo->PrefixLength);
+ }
+ }
+
+ if (IP_VERSION_6 == GetVerFromAddrInfo (AddressInfo)) {
+ Print (
+ L"%x:%x:%x:%x:%x:%x:%x:%x",
+ (((UINT16) AddressInfo->Address.v6.Addr[0]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[1]),
+ (((UINT16) AddressInfo->Address.v6.Addr[2]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[3]),
+ (((UINT16) AddressInfo->Address.v6.Addr[4]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[5]),
+ (((UINT16) AddressInfo->Address.v6.Addr[6]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[7]),
+ (((UINT16) AddressInfo->Address.v6.Addr[8]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[9]),
+ (((UINT16) AddressInfo->Address.v6.Addr[10]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[11]),
+ (((UINT16) AddressInfo->Address.v6.Addr[12]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[13]),
+ (((UINT16) AddressInfo->Address.v6.Addr[14]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[15])
+ );
+ if (AddressInfo->PrefixLength != 128) {
+ Print (L"/%d", AddressInfo->PrefixLength);
+ }
+ }
+}
+
+/**
+ Private function called to print EFI_IP_ADDRESS content.
+
+ @param[in] IpAddress The pointer to the EFI_IP_ADDRESS structure.
+**/
+VOID
+DumpIpAddress (
+ IN EFI_IP_ADDRESS *IpAddress
+ )
+{
+ if (IP_VERSION_4 == GetVerFromIpAddr (IpAddress)) {
+ Print (
+ L"%d.%d.%d.%d",
+ (UINTN) IpAddress->v4.Addr[0],
+ (UINTN) IpAddress->v4.Addr[1],
+ (UINTN) IpAddress->v4.Addr[2],
+ (UINTN) IpAddress->v4.Addr[3]
+ );
+ }
+
+ if (IP_VERSION_6 == GetVerFromIpAddr (IpAddress)) {
+ Print (
+ L"%x:%x:%x:%x:%x:%x:%x:%x",
+ (((UINT16) IpAddress->v6.Addr[0]) << 8) | ((UINT16) IpAddress->v6.Addr[1]),
+ (((UINT16) IpAddress->v6.Addr[2]) << 8) | ((UINT16) IpAddress->v6.Addr[3]),
+ (((UINT16) IpAddress->v6.Addr[4]) << 8) | ((UINT16) IpAddress->v6.Addr[5]),
+ (((UINT16) IpAddress->v6.Addr[6]) << 8) | ((UINT16) IpAddress->v6.Addr[7]),
+ (((UINT16) IpAddress->v6.Addr[8]) << 8) | ((UINT16) IpAddress->v6.Addr[9]),
+ (((UINT16) IpAddress->v6.Addr[10]) << 8) | ((UINT16) IpAddress->v6.Addr[11]),
+ (((UINT16) IpAddress->v6.Addr[12]) << 8) | ((UINT16) IpAddress->v6.Addr[13]),
+ (((UINT16) IpAddress->v6.Addr[14]) << 8) | ((UINT16) IpAddress->v6.Addr[15])
+ );
+ }
+
+}
+
+/**
+ Private function called to print EFI_IPSEC_SPD_SELECTOR content.
+
+ @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
+**/
+VOID
+DumpSpdSelector (
+ IN EFI_IPSEC_SPD_SELECTOR *Selector
+ )
+{
+ UINT32 Index;
+ CHAR16 *Str;
+
+ for (Index = 0; Index < Selector->LocalAddressCount; Index++) {
+ if (Index > 0) {
+ Print (L",");
+ }
+
+ DumpAddressInfo (&Selector->LocalAddress[Index]);
+ }
+
+ if (Index == 0) {
+ Print (L"localhost");
+ }
+
+ Print (L" -> ");
+
+ for (Index = 0; Index < Selector->RemoteAddressCount; Index++) {
+ if (Index > 0) {
+ Print (L",");
+ }
+
+ DumpAddressInfo (&Selector->RemoteAddress[Index]);
+ }
+
+ Str = MapIntegerToString (Selector->NextLayerProtocol, mMapIpProtocol);
+ if (Str != NULL) {
+ Print (L" %s", Str);
+ } else {
+ Print (L" proto:%d", (UINTN) Selector->NextLayerProtocol);
+ }
+
+ if ((Selector->NextLayerProtocol == EFI_IP4_PROTO_TCP) || (Selector->NextLayerProtocol == EFI_IP4_PROTO_UDP)) {
+ Print (L" port:");
+ if (Selector->LocalPort != EFI_IPSEC_ANY_PORT) {
+ Print (L"%d", Selector->LocalPort);
+ if (Selector->LocalPortRange != 0) {
+ Print (L"~%d", (UINTN) Selector->LocalPort + Selector->LocalPortRange);
+ }
+ } else {
+ Print (L"any");
+ }
+
+ Print (L" -> ");
+ if (Selector->RemotePort != EFI_IPSEC_ANY_PORT) {
+ Print (L"%d", Selector->RemotePort);
+ if (Selector->RemotePortRange != 0) {
+ Print (L"~%d", (UINTN) Selector->RemotePort + Selector->RemotePortRange);
+ }
+ } else {
+ Print (L"any");
+ }
+ } else if (Selector->NextLayerProtocol == EFI_IP4_PROTO_ICMP) {
+ Print (L" class/code:");
+ if (Selector->LocalPort != 0) {
+ Print (L"%d", (UINTN) (UINT8) Selector->LocalPort);
+ } else {
+ Print (L"any");
+ }
+
+ Print (L"/");
+ if (Selector->RemotePort != 0) {
+ Print (L"%d", (UINTN) (UINT8) Selector->RemotePort);
+ } else {
+ Print (L"any");
+ }
+ }
+}
+
+/**
+ Print EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA content.
+
+ @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
+ @param[in] Data The pointer to the EFI_IPSEC_SPD_DATA structure.
+ @param[in] EntryIndex The pointer to the Index in SPD Database.
+
+ @retval EFI_SUCCESS Dump SPD information successfully.
+**/
+EFI_STATUS
+DumpSpdEntry (
+ IN EFI_IPSEC_SPD_SELECTOR *Selector,
+ IN EFI_IPSEC_SPD_DATA *Data,
+ IN UINTN *EntryIndex
+ )
+{
+ BOOLEAN HasPre;
+ CHAR16 DataName[128];
+ CHAR16 *String1;
+ CHAR16 *String2;
+ CHAR16 *String3;
+ UINT8 Index;
+
+ Print (L"%d.", (*EntryIndex)++);
+
+ //
+ // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400
+ // Protect PF:0x34323423 Name:First Entry
+ // ext-sequence sequence-overflow fragcheck life:[B0,S1024,H3600]
+ // ESP algo1 algo2 Tunnel [xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx set]
+ //
+
+ DumpSpdSelector (Selector);
+ Print (L"\n ");
+
+ Print (L"%s ", MapIntegerToString (Data->Action, mMapIpSecAction));
+ Print (L"PF:%08x ", Data->PackageFlag);
+
+ Index = 0;
+ while (Data->Name[Index] != 0) {
+ DataName[Index] = (CHAR16) Data->Name[Index];
+ Index++;
+ ASSERT (Index < 128);
+ }
+ DataName[Index] = L'\0';
+
+ Print (L"Name:%s", DataName);
+
+ if (Data->Action == EfiIPsecActionProtect) {
+ Print (L"\n ");
+ if (Data->ProcessingPolicy->ExtSeqNum) {
+ Print (L"ext-sequence ");
+ }
+
+ if (Data->ProcessingPolicy->SeqOverflow) {
+ Print (L"sequence-overflow ");
+ }
+
+ if (Data->ProcessingPolicy->FragCheck) {
+ Print (L"fragment-check ");
+ }
+
+ HasPre = FALSE;
+ if (Data->ProcessingPolicy->SaLifetime.ByteCount != 0) {
+ Print (HasPre ? L"," : L"life:[");
+ Print (L"%lxB", Data->ProcessingPolicy->SaLifetime.ByteCount);
+ HasPre = TRUE;
+ }
+
+ if (Data->ProcessingPolicy->SaLifetime.SoftLifetime != 0) {
+ Print (HasPre ? L"," : L"life:[");
+ Print (L"%lxs", Data->ProcessingPolicy->SaLifetime.SoftLifetime);
+ HasPre = TRUE;
+ }
+
+ if (Data->ProcessingPolicy->SaLifetime.HardLifetime != 0) {
+ Print (HasPre ? L"," : L"life:[");
+ Print (L"%lxS", Data->ProcessingPolicy->SaLifetime.HardLifetime);
+ HasPre = TRUE;
+ }
+
+ if (HasPre) {
+ Print (L"]");
+ }
+
+ if (HasPre || Data->ProcessingPolicy->ExtSeqNum ||
+ Data->ProcessingPolicy->SeqOverflow || Data->ProcessingPolicy->FragCheck) {
+ Print (L"\n ");
+ }
+
+ String1 = MapIntegerToString (Data->ProcessingPolicy->Proto, mMapIpSecProtocol);
+ String2 = MapIntegerToString (Data->ProcessingPolicy->AuthAlgoId, mMapAuthAlgo);
+ String3 = MapIntegerToString (Data->ProcessingPolicy->EncAlgoId, mMapEncAlgo);
+ Print (
+ L"%s Auth:%s Encrypt:%s ",
+ String1,
+ String2,
+ String3
+ );
+
+ Print (L"%s ", MapIntegerToString (Data->ProcessingPolicy->Mode, mMapIpSecMode));
+ if (Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {
+ Print (L"[");
+ DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress);
+ Print (L" -> ");
+ DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress);
+ Print (L" %s]", MapIntegerToString (Data->ProcessingPolicy->TunnelOption->DF, mMapDfOption));
+ }
+ }
+
+ Print (L"\n");
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Print EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA content.
+
+ @param[in] SaId The pointer to the EFI_IPSEC_SA_ID structure.
+ @param[in] Data The pointer to the EFI_IPSEC_SA_DATA structure.
+ @param[in] EntryIndex The pointer to the Index in the SAD Database.
+
+ @retval EFI_SUCCESS Dump SAD information successfully.
+**/
+EFI_STATUS
+DumpSadEntry (
+ IN EFI_IPSEC_SA_ID *SaId,
+ IN EFI_IPSEC_SA_DATA *Data,
+ IN UINTN *EntryIndex
+ )
+{
+ BOOLEAN HasPre;
+ CHAR16 *String1;
+ CHAR16 *String2;
+
+ //
+ // SPI:1234 ESP Destination:xxx.xxx.xxx.xxx
+ // Mode:Transport SeqNum:134 AntiReplayWin:64 life:[0B,1023s,3400S] PathMTU:34
+ // Auth:xxxx/password Encrypt:yyyy/password
+ // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400
+ //
+
+ Print (L"%d.", (*EntryIndex)++);
+ Print (L"0x%x %s ", (UINTN) SaId->Spi, MapIntegerToString (SaId->Proto, mMapIpSecProtocol));
+ Print (L"Destination:");
+ DumpIpAddress (&SaId->DestAddress);
+ Print (L"\n");
+
+ Print (
+ L" Mode:%s SeqNum:%lx AntiReplayWin:%d ",
+ MapIntegerToString (Data->Mode, mMapIpSecMode),
+ Data->SNCount,
+ (UINTN) Data->AntiReplayWindows
+ );
+
+ HasPre = FALSE;
+ if (Data->SaLifetime.ByteCount != 0) {
+ Print (HasPre ? L"," : L"life:[");
+ Print (L"%lxB", Data->SaLifetime.ByteCount);
+ HasPre = TRUE;
+ }
+
+ if (Data->SaLifetime.SoftLifetime != 0) {
+ Print (HasPre ? L"," : L"life:[");
+ Print (L"%lxs", Data->SaLifetime.SoftLifetime);
+ HasPre = TRUE;
+ }
+
+ if (Data->SaLifetime.HardLifetime != 0) {
+ Print (HasPre ? L"," : L"life:[");
+ Print (L"%lxS", Data->SaLifetime.HardLifetime);
+ HasPre = TRUE;
+ }
+
+ if (HasPre) {
+ Print (L"] ");
+ }
+
+ Print (L"PathMTU:%d\n", (UINTN) Data->PathMTU);
+
+ if (SaId->Proto == EfiIPsecAH) {
+ Print (
+ L" Auth:%s/%s\n",
+ MapIntegerToString (Data->AlgoInfo.AhAlgoInfo.AuthAlgoId, mMapAuthAlgo),
+ Data->AlgoInfo.AhAlgoInfo.AuthKey
+ );
+ } else {
+ String1 = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.AuthAlgoId, mMapAuthAlgo);
+ String2 = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.EncAlgoId, mMapEncAlgo);
+ Print (
+ L" Auth:%s/%s Encrypt:%s/%s\n",
+ String1,
+ Data->AlgoInfo.EspAlgoInfo.AuthKey,
+ String2,
+ Data->AlgoInfo.EspAlgoInfo.EncKey
+ );
+ }
+
+ if (Data->SpdSelector != NULL) {
+ Print (L" ");
+ DumpSpdSelector (Data->SpdSelector);
+ Print (L"\n");
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Print EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA content.
+
+ @param[in] PadId The pointer to the EFI_IPSEC_PAD_ID structure.
+ @param[in] Data The pointer to the EFI_IPSEC_PAD_DATA structure.
+ @param[in] EntryIndex The pointer to the Index in the PAD Database.
+
+ @retval EFI_SUCCESS Dump PAD information successfully.
+**/
+EFI_STATUS
+DumpPadEntry (
+ IN EFI_IPSEC_PAD_ID *PadId,
+ IN EFI_IPSEC_PAD_DATA *Data,
+ IN UINTN *EntryIndex
+ )
+{
+ CHAR16 *String1;
+ CHAR16 *String2;
+
+ //
+ // ADDR:10.23.17.34/15
+ // IDEv1 PreSharedSecret IKE-ID
+ // password
+ //
+
+ Print (L"%d.", (*EntryIndex)++);
+
+ if (PadId->PeerIdValid) {
+ Print (L"ID:%s", PadId->Id.PeerId);
+ } else {
+ Print (L"ADDR:");
+ DumpAddressInfo (&PadId->Id.IpAddress);
+ }
+
+ Print (L"\n");
+
+ String1 = MapIntegerToString (Data->AuthProtocol, mMapAuthProto);
+ String2 = MapIntegerToString (Data->AuthMethod, mMapAuthMethod);
+ Print (
+ L" %s %s",
+ String1,
+ String2
+ );
+
+ if (Data->IkeIdFlag) {
+ Print (L"IKE-ID");
+ }
+
+ Print (L"\n");
+
+ if (Data->AuthData != NULL) {
+ DumpAsciiString (Data->AuthData, Data->AuthDataSize);
+ Print (L"\n");
+ }
+
+ if (Data->RevocationData != NULL) {
+ Print (L" %s\n", Data->RevocationData);
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+VISIT_POLICY_ENTRY mDumpPolicyEntry[] = {
+ (VISIT_POLICY_ENTRY) DumpSpdEntry,
+ (VISIT_POLICY_ENTRY) DumpSadEntry,
+ (VISIT_POLICY_ENTRY) DumpPadEntry
+};
+
+/**
+ Print all entry information in the database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Dump all information successfully.
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+ListPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ )
+{
+ UINTN EntryIndex;
+
+ EntryIndex = 0;
+ return ForeachPolicyEntry (DataType, mDumpPolicyEntry[DataType], &EntryIndex);
+}
+
diff --git a/NetworkPkg/Application/IpsecConfig/Dump.h b/NetworkPkg/Application/IpsecConfig/Dump.h new file mode 100644 index 0000000000..3c475dd304 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Dump.h @@ -0,0 +1,34 @@ +/** @file
+ The function declaration of dump policy entry function in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _DUMP_H_
+#define _DUMP_H_
+
+/**
+ Print all entry information in the database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Dump all information successfully.
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+ListPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ );
+
+#endif
diff --git a/NetworkPkg/Application/IpsecConfig/ForEach.c b/NetworkPkg/Application/IpsecConfig/ForEach.c new file mode 100644 index 0000000000..7b3b9b17a8 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/ForEach.c @@ -0,0 +1,115 @@ +/** @file
+ The implementation to go through each entry in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IpSecConfig.h"
+#include "ForEach.h"
+
+
+/**
+ Enumerate all entries in the database to execute specified operations according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] Routine The pointer to the function of a specified operation.
+ @param[in] Context The pointer to the context of a function.
+
+ @retval EFI_SUCCESS Execute specified operation successfully.
+**/
+EFI_STATUS
+ForeachPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN VISIT_POLICY_ENTRY Routine,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS GetNextStatus;
+ EFI_STATUS GetDataStatus;
+ EFI_IPSEC_CONFIG_SELECTOR *Selector;
+ VOID *Data;
+ UINTN SelectorSize;
+ UINTN DataSize;
+ BOOLEAN FirstGetNext;
+
+ FirstGetNext = TRUE;
+ SelectorSize = sizeof (EFI_IPSEC_CONFIG_SELECTOR);
+ Selector = AllocateZeroPool (SelectorSize);
+
+ DataSize = 0;
+ Data = NULL;
+
+ while (TRUE) {
+ GetNextStatus = mIpSecConfig->GetNextSelector (
+ mIpSecConfig,
+ DataType,
+ &SelectorSize,
+ Selector
+ );
+ if (GetNextStatus == EFI_BUFFER_TOO_SMALL) {
+ gBS->FreePool (Selector);
+ Selector = FirstGetNext ? AllocateZeroPool (SelectorSize) : AllocatePool (SelectorSize);
+
+ GetNextStatus = mIpSecConfig->GetNextSelector (
+ mIpSecConfig,
+ DataType,
+ &SelectorSize,
+ Selector
+ );
+ }
+
+ if (EFI_ERROR (GetNextStatus)) {
+ break;
+ }
+
+ FirstGetNext = FALSE;
+
+ GetDataStatus = mIpSecConfig->GetData (
+ mIpSecConfig,
+ DataType,
+ Selector,
+ &DataSize,
+ Data
+ );
+ if (GetDataStatus == EFI_BUFFER_TOO_SMALL) {
+ if (Data != NULL) {
+ gBS->FreePool (Data);
+ }
+
+ Data = AllocateZeroPool (DataSize);
+ GetDataStatus = mIpSecConfig->GetData (
+ mIpSecConfig,
+ DataType,
+ Selector,
+ &DataSize,
+ Data
+ );
+ }
+
+ ASSERT_EFI_ERROR (GetDataStatus);
+
+ if (EFI_ERROR (Routine (Selector, Data, Context))) {
+ break;
+ }
+ }
+
+ if (Data != NULL) {
+ gBS->FreePool (Data);
+ }
+
+ if (Selector != NULL) {
+ gBS->FreePool (Selector);
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/NetworkPkg/Application/IpsecConfig/ForEach.h b/NetworkPkg/Application/IpsecConfig/ForEach.h new file mode 100644 index 0000000000..fc309300c0 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/ForEach.h @@ -0,0 +1,54 @@ +/** @file
+ The internal structure and function declaration of the implementation
+ to go through each entry in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _FOREACH_H_
+#define _FOREACH_H_
+
+/**
+ The prototype for the DumpSpdEntry()/DumpSadEntry()/DumpPadEntry().
+ Print EFI_IPSEC_CONFIG_SELECTOR and corresponding content.
+
+ @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR union.
+ @param[in] Data The pointer to the corresponding data.
+ @param[in] Context The pointer to the Index in SPD/SAD/PAD Database.
+
+ @retval EFI_SUCCESS Dump SPD/SAD/PAD information successfully.
+**/
+typedef
+EFI_STATUS
+(*VISIT_POLICY_ENTRY) (
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
+ IN VOID *Data,
+ IN VOID *Context
+ );
+
+/**
+ Enumerate all entry in the database to execute a specified operation according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] Routine The pointer to function of a specified operation.
+ @param[in] Context The pointer to the context of a function.
+
+ @retval EFI_SUCCESS Execute specified operation successfully.
+**/
+EFI_STATUS
+ForeachPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN VISIT_POLICY_ENTRY Routine,
+ IN VOID *Context
+ );
+
+#endif
diff --git a/NetworkPkg/Application/IpsecConfig/Helper.c b/NetworkPkg/Application/IpsecConfig/Helper.c new file mode 100644 index 0000000000..5013ad9b76 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Helper.c @@ -0,0 +1,419 @@ +/** @file
+ The assistant function implementation for IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IpSecConfig.h"
+#include "Helper.h"
+
+/**
+ Helper function called to change an input parameter in the string format to a number.
+
+ @param[in] FlagStr The pointer to the flag string.
+ @param[in] Maximum Greatest value number.
+ @param[in, out] ValuePtr The pointer to the input parameter in string format.
+ @param[in] ByteCount The valid byte count
+ @param[in] Map The pointer to the STR2INT table.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+ @param[in] FormatMask The bit mask.
+ BIT 0 set indicates the value of a flag might be a number.
+ BIT 1 set indicates the value of a flag might be a string that needs to be looked up.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_NOT_FOUND The input parameter can't be found.
+ @retval EFI_INVALID_PARAMETER The input parameter is an invalid input.
+**/
+EFI_STATUS
+GetNumber (
+ IN CHAR16 *FlagStr,
+ IN UINT64 Maximum,
+ IN OUT VOID *ValuePtr,
+ IN UINTN ByteCount,
+ IN STR2INT *Map,
+ IN LIST_ENTRY *ParamPackage,
+ IN UINT32 FormatMask
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Value64;
+ BOOLEAN Converted;
+ UINTN Index;
+ CONST CHAR16 *ValueStr;
+
+ ASSERT (FormatMask & (FORMAT_NUMBER | FORMAT_STRING));
+
+ Converted = FALSE;
+ Value64 = 0;
+ ValueStr = ShellCommandLineGetValue (ParamPackage, FlagStr);
+
+ if (ValueStr == NULL) {
+ return EFI_NOT_FOUND;
+ } else {
+ //
+ // Try to convert to integer directly if MaybeNumber is TRUE.
+ //
+ if ((FormatMask & FORMAT_NUMBER) != 0) {
+ Value64 = StrToUInteger (ValueStr, &Status);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Convert successfully.
+ //
+ if (Value64 > Maximum) {
+ //
+ // But the result is invalid
+ //
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ FlagStr,
+ ValueStr
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Converted = TRUE;
+ }
+ }
+
+ if (!Converted && ((FormatMask & FORMAT_STRING) != 0)) {
+ //
+ // Convert falied, so use String->Integer map.
+ //
+ Value64 = MapStringToInteger (ValueStr, Map);
+ if (Value64 == (UINT32) -1) {
+ //
+ // Cannot find the string in the map.
+ //
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ FlagStr,
+ ValueStr
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ACCEPT_PARAMETERS), mHiiHandle);
+ for (Index = 0; Map[Index].String != NULL; Index++) {
+ Print (L" %s", Map[Index].String);
+ }
+
+ Print (L"\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ CopyMem (ValuePtr, &Value64, ByteCount);
+ return EFI_SUCCESS;
+ }
+}
+
+/**
+ Helper function called to convert a string containing an Ipv4 or Ipv6 Internet Protocol address
+ into a proper address for the EFI_IP_ADDRESS structure.
+
+ @param[in] Ptr The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
+ @param[out] Ip The pointer to the EFI_IP_ADDRESS structure to contain the result.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EfiInetAddr2 (
+ IN CHAR16 *Ptr,
+ OUT EFI_IP_ADDRESS *Ip
+ )
+{
+ EFI_STATUS Status;
+
+ if ((Ptr == NULL) || (Ip == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Parse the input address as Ipv4 Address first.
+ //
+ Status = NetLibStrToIp4 (Ptr, &Ip->v4);
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = NetLibStrToIp6 (Ptr, &Ip->v6);
+ return Status;
+}
+
+/**
+ Helper function called to calculate the prefix length associated with the string
+ containing an Ipv4 or Ipv6 Internet Protocol address.
+
+ @param[in] Ptr The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
+ @param[out] Addr The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval Others Other mistake case.
+**/
+EFI_STATUS
+EfiInetAddrRange (
+ IN CHAR16 *Ptr,
+ OUT EFI_IP_ADDRESS_INFO *Addr
+ )
+{
+ EFI_STATUS Status;
+
+ if ((Ptr == NULL) || (Addr == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = NetLibStrToIp4 (Ptr, &Addr->Address.v4);
+ if (!EFI_ERROR (Status)) {
+ if ((UINT32)(*Addr->Address.v4.Addr) == 0) {
+ Addr->PrefixLength = 0;
+ } else {
+ Addr->PrefixLength = 32;
+ }
+ return Status;
+ }
+
+ Status = NetLibStrToIp6andPrefix (Ptr, &Addr->Address.v6, &Addr->PrefixLength);
+ if (!EFI_ERROR (Status) && (Addr->PrefixLength == 0xFF)) {
+ Addr->PrefixLength = 128;
+ }
+
+ return Status;
+}
+
+/**
+ Helper function called to calculate the port range associated with the string.
+
+ @param[in] Ptr The pointer to the string containing a port and range.
+ @param[out] Port The pointer to the Port to contain the result.
+ @param[out] PortRange The pointer to the PortRange to contain the result.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval Others Other mistake case.
+**/
+EFI_STATUS
+EfiInetPortRange (
+ IN CHAR16 *Ptr,
+ OUT UINT16 *Port,
+ OUT UINT16 *PortRange
+ )
+{
+ CHAR16 *BreakPtr;
+ CHAR16 Ch;
+ EFI_STATUS Status;
+
+ for (BreakPtr = Ptr; (*BreakPtr != L'\0') && (*BreakPtr != L':'); BreakPtr++) {
+ ;
+ }
+
+ Ch = *BreakPtr;
+ *BreakPtr = L'\0';
+ *Port = (UINT16) StrToUInteger (Ptr, &Status);
+ *BreakPtr = Ch;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *PortRange = 0;
+ if (*BreakPtr == L':') {
+ BreakPtr++;
+ *PortRange = (UINT16) StrToUInteger (BreakPtr, &Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (*PortRange < *Port) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *PortRange = (UINT16) (*PortRange - *Port);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Helper function called to transfer a string to an unsigned integer.
+
+ @param[in] Str The pointer to the string.
+ @param[out] Status The operation status.
+
+ @return The integer value of converted Str.
+**/
+UINT64
+StrToUInteger (
+ IN CONST CHAR16 *Str,
+ OUT EFI_STATUS *Status
+ )
+{
+ UINT64 Value;
+ UINT64 NewValue;
+ CHAR16 *StrTail;
+ CHAR16 Char;
+ UINTN Base;
+ UINTN Len;
+
+ Base = 10;
+ Value = 0;
+ *Status = EFI_ABORTED;
+
+ //
+ // Skip leading white space.
+ //
+ while ((*Str != 0) && (*Str == ' ')) {
+ Str++;
+ }
+ //
+ // For NULL Str, just return.
+ //
+ if (*Str == 0) {
+ return 0;
+ }
+ //
+ // Skip white space in tail.
+ //
+ Len = StrLen (Str);
+ StrTail = (CHAR16 *) (Str + Len - 1);
+ while (*StrTail == ' ') {
+ *StrTail = 0;
+ StrTail--;
+ }
+
+ Len = StrTail - Str + 1;
+
+ //
+ // Check hex prefix '0x'.
+ //
+ if ((Len >= 2) && (*Str == '0') && ((*(Str + 1) == 'x') || (*(Str + 1) == 'X'))) {
+ Str += 2;
+ Len -= 2;
+ Base = 16;
+ }
+
+ if (Len == 0) {
+ return 0;
+ }
+ //
+ // Convert the string to value.
+ //
+ for (; Str <= StrTail; Str++) {
+
+ Char = *Str;
+
+ if (Base == 16) {
+ if (RShiftU64 (Value, 60) != 0) {
+ //
+ // Overflow here x16.
+ //
+ return 0;
+ }
+
+ NewValue = LShiftU64 (Value, 4);
+ } else {
+ if (RShiftU64 (Value, 61) != 0) {
+ //
+ // Overflow here x8.
+ //
+ return 0;
+ }
+
+ NewValue = LShiftU64 (Value, 3);
+ Value = LShiftU64 (Value, 1);
+ NewValue += Value;
+ if (NewValue < Value) {
+ //
+ // Overflow here.
+ //
+ return 0;
+ }
+ }
+
+ Value = NewValue;
+
+ if ((Base == 16) && (Char >= 'a') && (Char <= 'f')) {
+ Char = (CHAR16) (Char - 'a' + 'A');
+ }
+
+ if ((Base == 16) && (Char >= 'A') && (Char <= 'F')) {
+ Value += (Char - 'A') + 10;
+ } else if ((Char >= '0') && (Char <= '9')) {
+ Value += (Char - '0');
+ } else {
+ //
+ // Unexpected Char encountered.
+ //
+ return 0;
+ }
+ }
+
+ *Status = EFI_SUCCESS;
+ return Value;
+}
+
+/**
+ Helper function called to transfer a string to an unsigned integer according to the map table.
+
+ @param[in] Str The pointer to the string.
+ @param[in] Map The pointer to the map table.
+
+ @return The integer value of converted Str. If not found, then return -1.
+**/
+UINT32
+MapStringToInteger (
+ IN CONST CHAR16 *Str,
+ IN STR2INT *Map
+ )
+{
+ STR2INT *Item;
+
+ for (Item = Map; Item->String != NULL; Item++) {
+ if (StrCmp (Item->String, Str) == 0) {
+ return Item->Integer;
+ }
+ }
+
+ return (UINT32) -1;
+}
+
+/**
+ Helper function called to transfer an unsigned integer to a string according to the map table.
+
+ @param[in] Integer The pointer to the string.
+ @param[in] Map The pointer to the map table.
+
+ @return The converted Str. If not found, then return NULL.
+**/
+CHAR16 *
+MapIntegerToString (
+ IN UINT32 Integer,
+ IN STR2INT *Map
+ )
+{
+ STR2INT *Item;
+
+ for (Item = Map; Item->String != NULL; Item++) {
+ if (Integer == Item->Integer) {
+ return Item->String;
+ }
+ }
+
+ return NULL;
+}
diff --git a/NetworkPkg/Application/IpsecConfig/Helper.h b/NetworkPkg/Application/IpsecConfig/Helper.h new file mode 100644 index 0000000000..d893145a76 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Helper.h @@ -0,0 +1,143 @@ +/** @file
+ The assistant function declaration for IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _HELPER_H_
+#define _HELPER_H_
+
+#define FORMAT_NUMBER 0x1
+#define FORMAT_STRING 0x2
+
+/**
+ Helper function called to change input parameter in string format to number.
+
+ @param[in] FlagStr The pointer to the flag string.
+ @param[in] Maximum most value number.
+ @param[in, out] ValuePtr The pointer to the input parameter in string format.
+ @param[in] ByteCount The valid byte count
+ @param[in] Map The pointer to the STR2INT table.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+ @param[in] FormatMask The bit mask.
+ BIT 0 set indicates the value of flag might be number.
+ BIT 1 set indicates the value of flag might be a string that needs to be looked up.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_NOT_FOUND The input parameter can't be found.
+ @retval EFI_INVALID_PARAMETER The input parameter is an invalid input.
+**/
+EFI_STATUS
+GetNumber (
+ IN CHAR16 *FlagStr,
+ IN UINT64 Maximum,
+ IN OUT VOID *ValuePtr,
+ IN UINTN ByteCount,
+ IN STR2INT *Map,
+ IN LIST_ENTRY *ParamPackage,
+ IN UINT32 FormatMask
+ );
+
+/**
+ Helper function called to convert a string containing an (Ipv4) Internet Protocol dotted address
+ into a proper address for the EFI_IP_ADDRESS structure.
+
+ @param[in] Ptr The pointer to the string containing an (Ipv4) Internet Protocol dotted address.
+ @param[out] Ip The pointer to the Ip address structure to contain the result.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EfiInetAddr2 (
+ IN CHAR16 *Ptr,
+ OUT EFI_IP_ADDRESS *Ip
+ );
+
+/**
+ Helper function called to calculate the prefix length associated with the string
+ containing an Ipv4 or Ipv6 Internet Protocol address.
+
+ @param[in] Ptr The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
+ @param[out] Addr The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval Others Other mistake case.
+**/
+EFI_STATUS
+EfiInetAddrRange (
+ IN CHAR16 *Ptr,
+ OUT EFI_IP_ADDRESS_INFO *Addr
+ );
+
+/**
+ Helper function called to calculate the port range associated with the string.
+
+ @param[in] Ptr The pointer to the string containing a port and range.
+ @param[out] Port The pointer to the Port to contain the result.
+ @param[out] PortRange The pointer to the PortRange to contain the result.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval Others Other mistake case.
+**/
+EFI_STATUS
+EfiInetPortRange (
+ IN CHAR16 *Ptr,
+ OUT UINT16 *Port,
+ OUT UINT16 *PortRange
+ );
+
+/**
+ Helper function called to transfer a string to an unsigned integer.
+
+ @param[in] Str The pointer to the string.
+ @param[out] Status The operation status.
+
+ @return The integer value of a converted str.
+**/
+UINT64
+StrToUInteger (
+ IN CONST CHAR16 *Str,
+ OUT EFI_STATUS *Status
+ );
+
+/**
+ Helper function called to transfer a string to an unsigned integer according to the map table.
+
+ @param[in] Str The pointer to the string.
+ @param[in] Map The pointer to the map table.
+
+ @return The integer value of converted str. If not found, then return -1.
+**/
+UINT32
+MapStringToInteger (
+ IN CONST CHAR16 *Str,
+ IN STR2INT *Map
+ );
+
+/**
+ Helper function called to transfer an unsigned integer to a string according to the map table.
+
+ @param[in] Integer The pointer to the string.
+ @param[in] Map The pointer to the map table.
+
+ @return The converted str. If not found, then return NULL.
+**/
+CHAR16 *
+MapIntegerToString (
+ IN UINT32 Integer,
+ IN STR2INT *Map
+ );
+
+#endif
diff --git a/NetworkPkg/Application/IpsecConfig/Indexer.c b/NetworkPkg/Application/IpsecConfig/Indexer.c new file mode 100644 index 0000000000..1762bbeb58 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Indexer.c @@ -0,0 +1,248 @@ +/** @file
+ The implementation of construct ENTRY_INDEXER in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IpSecConfig.h"
+#include "Indexer.h"
+#include "Helper.h"
+
+/**
+ Fill in SPD_ENTRY_INDEXER through ParamPackage list.
+
+ @param[in, out] Indexer The pointer to the SPD_ENTRY_INDEXER structure.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Filled in SPD_ENTRY_INDEXER successfully.
+**/
+EFI_STATUS
+ConstructSpdIndexer (
+ IN OUT SPD_ENTRY_INDEXER *Indexer,
+ IN LIST_ENTRY *ParamPackage
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Value64;
+ CONST CHAR16 *ValueStr;
+
+ ValueStr = NULL;
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");
+ } else {
+ ASSERT (FALSE);
+ }
+
+ ASSERT (ValueStr != NULL);
+
+ Value64 = StrToUInteger (ValueStr, &Status);
+ if (!EFI_ERROR (Status)) {
+ Indexer->Index = (UINTN) Value64;
+ Indexer->Name = NULL;
+ } else {
+ UnicodeStrToAsciiStr (ValueStr, (CHAR8 *) Indexer->Name);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Fill in SAD_ENTRY_INDEXER through ParamPackage list.
+
+ @param[in, out] Indexer The pointer to the SAD_ENTRY_INDEXER structure.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Filled in SPD_ENTRY_INDEXER successfully.
+ @retval EFI_INVALID_PARAMETER The mistaken user input in ParamPackage list.
+**/
+EFI_STATUS
+ConstructSadIndexer (
+ IN OUT SAD_ENTRY_INDEXER *Indexer,
+ IN LIST_ENTRY *ParamPackage
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ UINT64 Value64;
+ CONST CHAR16 *ValueStr;
+
+ ValueStr = NULL;
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");
+ } else {
+ ASSERT (FALSE);
+ }
+
+ ASSERT (ValueStr != NULL);
+
+ Value64 = StrToUInteger (ValueStr, &Status);
+ if (!EFI_ERROR (Status)) {
+ Indexer->Index = (UINTN) Value64;
+ ZeroMem (&Indexer->SaId, sizeof (EFI_IPSEC_SA_ID));
+ } else {
+ if ((!ShellCommandLineGetFlag (ParamPackage, L"--lookup-spi")) ||
+ (!ShellCommandLineGetFlag (ParamPackage, L"--lookup-ipsec-proto")) ||
+ (!ShellCommandLineGetFlag (ParamPackage, L"--lookup-dest"))) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--lookup-spi --lookup-ipsec-proto --lookup-dest"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--lookup-spi",
+ (UINT32) -1,
+ &Indexer->SaId.Spi,
+ sizeof (UINT32),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ Status1 = GetNumber (
+ L"--lookup-ipsec-proto",
+ 0,
+ &Indexer->SaId.Proto,
+ sizeof (EFI_IPSEC_PROTOCOL_TYPE),
+ mMapIpSecProtocol,
+ ParamPackage,
+ FORMAT_STRING
+ );
+
+ if (EFI_ERROR (Status) || EFI_ERROR (Status1)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-dest");
+ ASSERT (ValueStr != NULL);
+
+ Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &Indexer->SaId.DestAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--lookup-dest",
+ ValueStr
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Fill in PAD_ENTRY_INDEXER through ParamPackage list.
+
+ @param[in, out] Indexer The pointer to the PAD_ENTRY_INDEXER structure.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Filled in PAD_ENTRY_INDEXER successfully.
+ @retval EFI_INVALID_PARAMETER The mistaken user input in ParamPackage list.
+**/
+EFI_STATUS
+ConstructPadIndexer (
+ IN OUT PAD_ENTRY_INDEXER *Indexer,
+ IN LIST_ENTRY *ParamPackage
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Value64;
+ CONST CHAR16 *ValueStr;
+
+ ValueStr = NULL;
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d");
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");
+ } else {
+ ASSERT (FALSE);
+ }
+
+ ASSERT (ValueStr != NULL);
+
+ Value64 = StrToUInteger (ValueStr, &Status);
+
+ if (!EFI_ERROR (Status)) {
+ Indexer->Index = (UINTN) Value64;
+ ZeroMem (&Indexer->PadId, sizeof (EFI_IPSEC_PAD_ID));
+ } else {
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"--lookup-peer-address")) {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-peer-address");
+ ASSERT (ValueStr != NULL);
+
+ Indexer->PadId.PeerIdValid = FALSE;
+ Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &Indexer->PadId.Id.IpAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--lookup-peer-address",
+ ValueStr
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-peer-id");
+ if (ValueStr == NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--lookup-peer-address --lookup-peer-id"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Indexer->PadId.PeerIdValid = TRUE;
+ StrnCpy ((CHAR16 *) Indexer->PadId.Id.PeerId, ValueStr, ARRAY_SIZE (Indexer->PadId.Id.PeerId) - 1);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+CONSTRUCT_POLICY_ENTRY_INDEXER mConstructPolicyEntryIndexer[] = {
+ (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructSpdIndexer,
+ (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructSadIndexer,
+ (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructPadIndexer
+};
diff --git a/NetworkPkg/Application/IpsecConfig/Indexer.h b/NetworkPkg/Application/IpsecConfig/Indexer.h new file mode 100644 index 0000000000..078f38a312 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Indexer.h @@ -0,0 +1,58 @@ +/** @file
+ The internal structure and function declaration to construct ENTRY_INDEXER in
+ IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _INDEXER_H_
+#define _INDEXER_H_
+
+typedef struct {
+ UINT8 *Name;
+ UINTN Index; // Used only if Name is NULL.
+} SPD_ENTRY_INDEXER;
+
+typedef struct {
+ EFI_IPSEC_SA_ID SaId;
+ UINTN Index;
+} SAD_ENTRY_INDEXER;
+
+typedef struct {
+ EFI_IPSEC_PAD_ID PadId;
+ UINTN Index;
+} PAD_ENTRY_INDEXER;
+
+typedef union {
+ SPD_ENTRY_INDEXER Spd;
+ SAD_ENTRY_INDEXER Sad;
+ PAD_ENTRY_INDEXER Pad;
+} POLICY_ENTRY_INDEXER;
+
+/**
+ The prototype for the ConstructSpdIndexer()/ConstructSadIndexer()/ConstructPadIndexer().
+ Fill in SPD_ENTRY_INDEXER/SAD_ENTRY_INDEXER/PAD_ENTRY_INDEXER through ParamPackage list.
+
+ @param[in, out] Indexer The pointer to the POLICY_ENTRY_INDEXER union.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Filled in POLICY_ENTRY_INDEXER successfully.
+**/
+typedef
+EFI_STATUS
+(* CONSTRUCT_POLICY_ENTRY_INDEXER) (
+ IN POLICY_ENTRY_INDEXER *Indexer,
+ IN LIST_ENTRY *ParamPackage
+);
+
+extern CONSTRUCT_POLICY_ENTRY_INDEXER mConstructPolicyEntryIndexer[];
+#endif
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfig.c b/NetworkPkg/Application/IpsecConfig/IpSecConfig.c new file mode 100644 index 0000000000..8006d84860 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/IpSecConfig.c @@ -0,0 +1,809 @@ +/** @file
+ The main process for IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/HiiLib.h>
+
+#include <Protocol/IpSec.h>
+
+#include "IpSecConfig.h"
+#include "Dump.h"
+#include "Indexer.h"
+#include "PolicyEntryOperation.h"
+#include "Delete.h"
+#include "Helper.h"
+
+//
+// Used for ShellCommandLineParseEx only
+// and to ensure user inputs are in valid format
+//
+SHELL_PARAM_ITEM mIpSecConfigParamList[] = {
+ { L"-p", TypeValue },
+ { L"-a", TypeValue },
+ { L"-i", TypeValue },
+ { L"-e", TypeValue },
+ { L"-d", TypeValue },
+ { L"-f", TypeFlag },
+ { L"-l", TypeFlag },
+ { L"-enable", TypeFlag },
+ { L"-disable", TypeFlag },
+ { L"-status", TypeFlag },
+ { L"-?", TypeFlag },
+
+ //
+ // SPD Selector
+ //
+ { L"--local", TypeValue },
+ { L"--remote", TypeValue },
+ { L"--proto", TypeValue },
+ { L"--local-port", TypeValue },
+ { L"--remote-port", TypeValue },
+ { L"--icmp-type", TypeValue },
+ { L"--icmp-code", TypeValue },
+
+ //
+ // SPD Data
+ //
+ { L"--name", TypeValue },
+ { L"--packet-flag", TypeValue },
+ { L"--action", TypeValue },
+ { L"--lifebyte", TypeValue },
+ { L"--lifetime-soft", TypeValue },
+ { L"--lifetime", TypeValue },
+ { L"--mode", TypeValue },
+ { L"--tunnel-local", TypeValue },
+ { L"--tunnel-remote", TypeValue },
+ { L"--dont-fragment", TypeValue },
+ { L"--ipsec-proto", TypeValue },
+ { L"--auth-algo", TypeValue },
+ { L"--encrypt-algo", TypeValue },
+
+ { L"--ext-sequence", TypeFlag },
+ { L"--sequence-overflow", TypeFlag },
+ { L"--fragment-check", TypeFlag },
+ { L"--ext-sequence-", TypeFlag },
+ { L"--sequence-overflow-", TypeFlag },
+ { L"--fragment-check-", TypeFlag },
+
+ //
+ // SA ID
+ // --ipsec-proto
+ //
+ { L"--spi", TypeValue },
+ { L"--dest", TypeValue },
+ { L"--lookup-spi", TypeValue },
+ { L"--lookup-ipsec-proto", TypeValue },
+ { L"--lookup-dest", TypeValue },
+
+ //
+ // SA DATA
+ // --mode
+ // --auth-algo
+ // --encrypt-algo
+ //
+ { L"--sequence-number", TypeValue },
+ { L"--antireplay-window", TypeValue },
+ { L"--auth-key", TypeValue },
+ { L"--encrypt-key", TypeValue },
+ { L"--path-mtu", TypeValue },
+
+ //
+ // PAD ID
+ //
+ { L"--peer-id", TypeValue },
+ { L"--peer-address", TypeValue },
+ { L"--auth-proto", TypeValue },
+ { L"--auth-method", TypeValue },
+ { L"--ike-id", TypeValue },
+ { L"--ike-id-", TypeValue },
+ { L"--auth-data", TypeValue },
+ { L"--revocation-data", TypeValue },
+ { L"--lookup-peer-id", TypeValue },
+ { L"--lookup-peer-address", TypeValue },
+
+ { NULL, TypeMax },
+};
+
+//
+// -P
+//
+STR2INT mMapPolicy[] = {
+ { L"SPD", IPsecConfigDataTypeSpd },
+ { L"SAD", IPsecConfigDataTypeSad },
+ { L"PAD", IPsecConfigDataTypePad },
+ { NULL, 0 },
+};
+
+//
+// --proto
+//
+STR2INT mMapIpProtocol[] = {
+ { L"TCP", EFI_IP4_PROTO_TCP },
+ { L"UDP", EFI_IP4_PROTO_UDP },
+ { L"ICMP", EFI_IP4_PROTO_ICMP },
+ { NULL, 0 },
+};
+
+//
+// --action
+//
+STR2INT mMapIpSecAction[] = {
+ { L"Bypass", EfiIPsecActionBypass },
+ { L"Discard", EfiIPsecActionDiscard },
+ { L"Protect", EfiIPsecActionProtect },
+ { NULL, 0 },
+};
+
+//
+// --mode
+//
+STR2INT mMapIpSecMode[] = {
+ { L"Transport", EfiIPsecTransport },
+ { L"Tunnel", EfiIPsecTunnel },
+ { NULL, 0 },
+};
+
+//
+// --dont-fragment
+//
+STR2INT mMapDfOption[] = {
+ { L"clear", EfiIPsecTunnelClearDf },
+ { L"set", EfiIPsecTunnelSetDf },
+ { L"copy", EfiIPsecTunnelCopyDf },
+ { NULL, 0 },
+};
+
+//
+// --ipsec-proto
+//
+STR2INT mMapIpSecProtocol[] = {
+ { L"AH", EfiIPsecAH },
+ { L"ESP", EfiIPsecESP },
+ { NULL, 0 },
+};
+
+//
+// --auth-algo
+//
+STR2INT mMapAuthAlgo[] = {
+ { L"NONE", EFI_IPSEC_AALG_NONE },
+ { L"MD5HMAC", EFI_IPSEC_AALG_MD5HMAC },
+ { L"SHA1HMAC", EFI_IPSEC_AALG_SHA1HMAC },
+ { L"SHA2-256HMAC", EFI_IPSEC_AALG_SHA2_256HMAC },
+ { L"SHA2-384HMAC", EFI_IPSEC_AALG_SHA2_384HMAC },
+ { L"SHA2-512HMAC", EFI_IPSEC_AALG_SHA2_512HMAC },
+ { L"AES-XCBC-MAC", EFI_IPSEC_AALG_AES_XCBC_MAC },
+ { L"NULL", EFI_IPSEC_AALG_NULL },
+ { NULL, 0 },
+};
+
+//
+// --encrypt-algo
+//
+STR2INT mMapEncAlgo[] = {
+ { L"NONE", EFI_IPSEC_EALG_NONE },
+ { L"DESCBC", EFI_IPSEC_EALG_DESCBC },
+ { L"3DESCBC", EFI_IPSEC_EALG_3DESCBC },
+ { L"CASTCBC", EFI_IPSEC_EALG_CASTCBC },
+ { L"BLOWFISHCBC", EFI_IPSEC_EALG_BLOWFISHCBC },
+ { L"NULL", EFI_IPSEC_EALG_NULL },
+ { L"AESCBC", EFI_IPSEC_EALG_AESCBC },
+ { L"AESCTR", EFI_IPSEC_EALG_AESCTR },
+ { L"AES-CCM-ICV8", EFI_IPSEC_EALG_AES_CCM_ICV8 },
+ { L"AES-CCM-ICV12",EFI_IPSEC_EALG_AES_CCM_ICV12 },
+ { L"AES-CCM-ICV16",EFI_IPSEC_EALG_AES_CCM_ICV16 },
+ { L"AES-GCM-ICV8", EFI_IPSEC_EALG_AES_GCM_ICV8 },
+ { L"AES-GCM-ICV12",EFI_IPSEC_EALG_AES_GCM_ICV12 },
+ { L"AES-GCM-ICV16",EFI_IPSEC_EALG_AES_GCM_ICV16 },
+ { NULL, 0 },
+};
+
+//
+// --auth-proto
+//
+STR2INT mMapAuthProto[] = {
+ { L"IKEv1", EfiIPsecAuthProtocolIKEv1 },
+ { L"IKEv2", EfiIPsecAuthProtocolIKEv2 },
+ { NULL, 0 },
+};
+
+//
+// --auth-method
+//
+STR2INT mMapAuthMethod[] = {
+ { L"PreSharedSecret", EfiIPsecAuthMethodPreSharedSecret },
+ { L"Certificates", EfiIPsecAuthMethodCertificates },
+ { NULL, 0 },
+};
+
+EFI_IPSEC_PROTOCOL *mIpSec;
+EFI_IPSEC_CONFIG_PROTOCOL *mIpSecConfig;
+EFI_HII_HANDLE mHiiHandle;
+EFI_GUID mEfiIpSecConfigGuid = EFI_IPSEC_CONFIG_GUID;
+CHAR16 mAppName[] = L"IpSecConfig";
+
+//
+// Used for IpSecConfigRetriveCheckListByName only to check the validation of user input
+//
+VAR_CHECK_ITEM mIpSecConfigVarCheckList[] = {
+ { L"-enable", BIT(1)|BIT(0), BIT(1), BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-disable", BIT(1)|BIT(0), BIT(1), BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-status", BIT(1)|BIT(0), BIT(1), BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-p", BIT(1), 0, BIT(2)|BIT(1)|BIT(0), 0 },
+
+ { L"-a", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-i", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-d", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-e", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-l", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 },
+ { L"-f", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 },
+
+ { L"-?", BIT(0), BIT(0), BIT(2)|BIT(1)|BIT(0), 0 },
+
+ //
+ // SPD Selector
+ //
+ { L"--local", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--remote", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--proto", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--local-port", 0, 0, BIT(2)|BIT(1), BIT(0) },
+ { L"--remote-port", 0, 0, BIT(2)|BIT(1), BIT(0) },
+ { L"--icmp-type", 0, 0, BIT(2)|BIT(1), BIT(1) },
+ { L"--icmp-code", 0, 0, BIT(2)|BIT(1), BIT(1) },
+
+ //
+ // SPD Data
+ //
+ { L"--name", 0, 0, BIT(2), 0 },
+ { L"--packet-flag", 0, 0, BIT(2), 0 },
+ { L"--action", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--lifebyte", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--lifetime-soft", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--lifetime", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--mode", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--tunnel-local", 0, 0, BIT(2), 0 },
+ { L"--tunnel-remote", 0, 0, BIT(2), 0 },
+ { L"--dont-fragment", 0, 0, BIT(2), 0 },
+ { L"--ipsec-proto", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--auth-algo", 0, 0, BIT(2)|BIT(1), 0 },
+ { L"--encrypt-algo", 0, 0, BIT(2)|BIT(1), 0 },
+
+ { L"--ext-sequence", 0, 0, BIT(2), BIT(2) },
+ { L"--sequence-overflow", 0, 0, BIT(2), BIT(2) },
+ { L"--fragment-check", 0, 0, BIT(2), BIT(2) },
+ { L"--ext-sequence-", 0, 0, BIT(2), BIT(3) },
+ { L"--sequence-overflow-", 0, 0, BIT(2), BIT(3) },
+ { L"--fragment-check-", 0, 0, BIT(2), BIT(3) },
+
+ //
+ // SA ID
+ // --ipsec-proto
+ //
+ { L"--spi", 0, 0, BIT(1), 0 },
+ { L"--dest", 0, 0, BIT(1), 0 },
+ { L"--lookup-spi", 0, 0, BIT(1), 0 },
+ { L"--lookup-ipsec-proto", 0, 0, BIT(1), 0 },
+ { L"--lookup-dest", 0, 0, BIT(1), 0 },
+
+ //
+ // SA DATA
+ // --mode
+ // --auth-algo
+ // --encrypt-algo
+ //
+ { L"--sequence-number", 0, 0, BIT(1), 0 },
+ { L"--antireplay-window", 0, 0, BIT(1), 0 },
+ { L"--auth-key", 0, 0, BIT(1), 0 },
+ { L"--encrypt-key", 0, 0, BIT(1), 0 },
+ { L"--path-mtu", 0, 0, BIT(1), 0 },
+
+ //
+ // The example to add a PAD:
+ // "-A --peer-id Mike [--peer-address 10.23.2.2] --auth-proto IKE1/IKE2
+ // --auth-method PreSharedSeceret/Certificate --ike-id
+ // --auth-data 343343 --revocation-data 2342432"
+ // The example to delete a PAD:
+ // "-D * --lookup-peer-id Mike [--lookup-peer-address 10.23.2.2]"
+ // "-D 1"
+ // The example to edit a PAD:
+ // "-E * --lookup-peer-id Mike --auth-method Certificate"
+
+ //
+ // PAD ID
+ //
+ { L"--peer-id", 0, 0, BIT(0), BIT(4) },
+ { L"--peer-address", 0, 0, BIT(0), BIT(5) },
+ { L"--auth-proto", 0, 0, BIT(0), 0 },
+ { L"--auth-method", 0, 0, BIT(0), 0 },
+ { L"--IKE-ID", 0, 0, BIT(0), BIT(6) },
+ { L"--IKE-ID-", 0, 0, BIT(0), BIT(7) },
+ { L"--auth-data", 0, 0, BIT(0), 0 },
+ { L"--revocation-data", 0, 0, BIT(0), 0 },
+ { L"--lookup-peer-id", 0, 0, BIT(0), BIT(4) },
+ { L"--lookup-peer-address",0, 0, BIT(0), BIT(5) },
+
+ { NULL, 0, 0, 0, 0 },
+};
+
+/**
+ The function to allocate the proper sized buffer for various
+ EFI interfaces.
+
+ @param[in, out] Status Current status.
+ @param[in, out] Buffer Current allocated buffer, or NULL.
+ @param[in] BufferSize Current buffer size needed
+
+ @retval TRUE If the buffer was reallocated and the caller should try the API again.
+ @retval FALSE If the buffer was not reallocated successfully.
+**/
+BOOLEAN
+GrowBuffer (
+ IN OUT EFI_STATUS *Status,
+ IN OUT VOID **Buffer,
+ IN UINTN BufferSize
+ )
+{
+ BOOLEAN TryAgain;
+
+ ASSERT (Status != NULL);
+ ASSERT (Buffer != NULL);
+
+ //
+ // If this is an initial request, buffer will be null with a new buffer size.
+ //
+ if ((NULL == *Buffer) && (BufferSize != 0)) {
+ *Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // If the status code is "buffer too small", resize the buffer.
+ //
+ TryAgain = FALSE;
+ if (*Status == EFI_BUFFER_TOO_SMALL) {
+
+ if (*Buffer != NULL) {
+ FreePool (*Buffer);
+ }
+
+ *Buffer = AllocateZeroPool (BufferSize);
+
+ if (*Buffer != NULL) {
+ TryAgain = TRUE;
+ } else {
+ *Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ //
+ // If there's an error, free the buffer.
+ //
+ if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) {
+ FreePool (*Buffer);
+ *Buffer = NULL;
+ }
+
+ return TryAgain;
+}
+
+/**
+ Function returns an array of handles that support the requested protocol
+ in a buffer allocated from a pool.
+
+ @param[in] SearchType Specifies which handle(s) are to be returned.
+ @param[in] Protocol Provides the protocol to search by.
+ This parameter is only valid for SearchType ByProtocol.
+
+ @param[in] SearchKey Supplies the search key depending on the SearchType.
+ @param[in, out] NoHandles The number of handles returned in Buffer.
+ @param[out] Buffer A pointer to the buffer to return the requested array of
+ handles that support Protocol.
+
+ @retval EFI_SUCCESS The resulting array of handles was returned.
+ @retval Others Other mistake case.
+**/
+EFI_STATUS
+LocateHandle (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NoHandles,
+ OUT EFI_HANDLE **Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+
+ ASSERT (NoHandles != NULL);
+ ASSERT (Buffer != NULL);
+
+ //
+ // Initialize for GrowBuffer loop.
+ //
+ Status = EFI_SUCCESS;
+ *Buffer = NULL;
+ BufferSize = 50 * sizeof (EFI_HANDLE);
+
+ //
+ // Call the real function.
+ //
+ while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) {
+ Status = gBS->LocateHandle (
+ SearchType,
+ Protocol,
+ SearchKey,
+ &BufferSize,
+ *Buffer
+ );
+ }
+
+ *NoHandles = BufferSize / sizeof (EFI_HANDLE);
+ if (EFI_ERROR (Status)) {
+ *NoHandles = 0;
+ }
+
+ return Status;
+}
+
+/**
+ Find the first instance of this protocol in the system and return its interface.
+
+ @param[in] ProtocolGuid The guid of the protocol.
+ @param[out] Interface The pointer to the first instance of the protocol.
+
+ @retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found.
+ @retval Others A protocol instance matching ProtocolGuid was not found.
+**/
+EFI_STATUS
+LocateProtocol (
+ IN EFI_GUID *ProtocolGuid,
+ OUT VOID **Interface
+ )
+
+{
+ EFI_STATUS Status;
+ UINTN NumberHandles;
+ UINTN Index;
+ EFI_HANDLE *Handles;
+
+ *Interface = NULL;
+ Handles = NULL;
+ NumberHandles = 0;
+
+ Status = LocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "LibLocateProtocol: Handle not found\n"));
+ return Status;
+ }
+
+ for (Index = 0; Index < NumberHandles; Index++) {
+ ASSERT (Handles != NULL);
+ Status = gBS->HandleProtocol (
+ Handles[Index],
+ ProtocolGuid,
+ Interface
+ );
+
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ if (Handles != NULL) {
+ FreePool (Handles);
+ }
+
+ return Status;
+}
+
+/**
+ Helper function called to check the conflicted flags.
+
+ @param[in] CheckList The pointer to the VAR_CHECK_ITEM table.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS No conflicted flags.
+ @retval EFI_INVALID_PARAMETER The input parameter is erroroneous or there are some conflicted flags.
+**/
+EFI_STATUS
+IpSecConfigRetriveCheckListByName (
+ IN VAR_CHECK_ITEM *CheckList,
+ IN LIST_ENTRY *ParamPackage
+)
+{
+
+ LIST_ENTRY *Node;
+ VAR_CHECK_ITEM *Item;
+ UINT32 Attribute1;
+ UINT32 Attribute2;
+ UINT32 Attribute3;
+ UINT32 Attribute4;
+ UINT32 Index;
+
+ Attribute1 = 0;
+ Attribute2 = 0;
+ Attribute3 = 0;
+ Attribute4 = 0;
+ Index = 0;
+ Item = mIpSecConfigVarCheckList;
+
+ if ((ParamPackage == NULL) || (CheckList == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Enumerate through the list of parameters that are input by user.
+ //
+ for (Node = GetFirstNode (ParamPackage); !IsNull (ParamPackage, Node); Node = GetNextNode (ParamPackage, Node)) {
+ if (((SHELL_PARAM_PACKAGE *) Node)->Name != NULL) {
+ //
+ // Enumerate the check list that defines the conflicted attributes of each flag.
+ //
+ for (; Item->VarName != NULL; Item++) {
+ if (StrCmp (((SHELL_PARAM_PACKAGE *) Node)->Name, Item->VarName) == 0) {
+ Index++;
+ if (Index == 1) {
+ Attribute1 = Item->Attribute1;
+ Attribute2 = Item->Attribute2;
+ Attribute3 = Item->Attribute3;
+ Attribute4 = Item->Attribute4;
+ } else {
+ Attribute1 &= Item->Attribute1;
+ Attribute2 |= Item->Attribute2;
+ Attribute3 &= Item->Attribute3;
+ Attribute4 |= Item->Attribute4;
+ if (Attribute1 != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Attribute2 != 0) {
+ if ((Index == 2) && (StrCmp (Item->VarName, L"-p") == 0)) {
+ continue;
+ }
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Attribute3 == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (((Attribute4 & 0xFF) == 0x03) || ((Attribute4 & 0xFF) == 0x0C) ||
+ ((Attribute4 & 0xFF) == 0x30) || ((Attribute4 & 0xFF) == 0xC0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ break;
+ }
+ }
+
+ Item = mIpSecConfigVarCheckList;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
+ both device drivers and bus drivers.
+
+ The entry point for IpSecConfig application that parse the command line input and call an IpSecConfig process.
+
+ @param[in] ImageHandle The image handle of this application.
+ @param[in] SystemTable The pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeIpSecConfig (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_IPSEC_CONFIG_DATA_TYPE DataType;
+ UINT8 Value;
+ LIST_ENTRY *ParamPackage;
+ CONST CHAR16 *ValueStr;
+ CHAR16 *ProblemParam;
+ UINTN NonOptionCount;
+
+ //
+ // Register our string package with HII and return the handle to it.
+ //
+ mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, IpSecConfigStrings, NULL);
+ ASSERT (mHiiHandle != NULL);
+
+ Status = ShellCommandLineParseEx (mIpSecConfigParamList, &ParamPackage, &ProblemParam, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, ProblemParam);
+ goto Done;
+ }
+
+ Status = IpSecConfigRetriveCheckListByName (mIpSecConfigVarCheckList, ParamPackage);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_MISTAKEN_OPTIONS), mHiiHandle);
+ goto Done;
+ }
+
+ Status = LocateProtocol (&gEfiIpSecConfigProtocolGuid, (VOID **) &mIpSecConfig);
+ if (EFI_ERROR (Status) || mIpSecConfig == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);
+ goto Done;
+ }
+
+ Status = LocateProtocol (&gEfiIpSecProtocolGuid, (VOID **) &mIpSec);
+ if (EFI_ERROR (Status) || mIpSec == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName);
+ goto Done;
+ }
+
+ //
+ // Enable IPsec.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-enable")) {
+ if (!(mIpSec->DisabledFlag)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_ENABLE), mHiiHandle, mAppName);
+ } else {
+ //
+ // Set enable flag.
+ //
+ Value = IPSEC_STATUS_ENABLED;
+ Status = gRT->SetVariable (
+ IPSECCONFIG_STATUS_NAME,
+ &gEfiIpSecConfigProtocolGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof (Value),
+ &Value
+ );
+ if (!EFI_ERROR (Status)) {
+ mIpSec->DisabledFlag = FALSE;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_SUCCESS), mHiiHandle, mAppName);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_FAILED), mHiiHandle, mAppName);
+ }
+ }
+
+ goto Done;
+ }
+
+ //
+ // Disable IPsec.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-disable")) {
+ if (mIpSec->DisabledFlag) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_DISABLE), mHiiHandle, mAppName);
+ } else {
+ //
+ // Set disable flag; however, leave it to be disabled in the callback function of DisabledEvent.
+ //
+ gBS->SignalEvent (mIpSec->DisabledEvent);
+ if (mIpSec->DisabledFlag) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_SUCCESS), mHiiHandle, mAppName);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_FAILED), mHiiHandle, mAppName);
+ }
+ }
+
+ goto Done;
+ }
+
+ //
+ //IPsec Status.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-status")) {
+ if (mIpSec->DisabledFlag) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_DISABLE), mHiiHandle, mAppName);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_ENABLE), mHiiHandle, mAppName);
+ }
+
+ goto Done;
+ }
+
+ //
+ // Try to get policy database type.
+ //
+ DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) -1;
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-p");
+ if (ValueStr != NULL) {
+ DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) MapStringToInteger (ValueStr, mMapPolicy);
+ if (DataType == -1) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_DB), mHiiHandle, mAppName, ValueStr);
+ goto Done;
+ }
+ }
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-?")) {
+ switch (DataType) {
+ case (EFI_IPSEC_CONFIG_DATA_TYPE) -1:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_HELP), mHiiHandle);
+ break;
+
+ case IPsecConfigDataTypeSpd:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_SPD_HELP), mHiiHandle);
+ break;
+
+ case IPsecConfigDataTypeSad:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_SAD_HELP), mHiiHandle);
+ break;
+
+ case IPsecConfigDataTypePad:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PAD_HELP), mHiiHandle);
+ break;
+
+ default:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_DB), mHiiHandle);
+ break;
+ }
+
+ goto Done;
+ }
+
+ NonOptionCount = ShellCommandLineGetCount ();
+ if ((NonOptionCount - 1) > 0) {
+ ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32) (NonOptionCount - 1));
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_REDUNDANCY_MANY), mHiiHandle, mAppName, ValueStr);
+ goto Done;
+ }
+
+ if (DataType == -1) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_DB), mHiiHandle, mAppName);
+ goto Done;
+ }
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-a")) {
+ Status = AddOrInsertPolicyEntry (DataType, ParamPackage);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ Status = AddOrInsertPolicyEntry (DataType, ParamPackage);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) {
+ Status = EditPolicyEntry (DataType, ParamPackage);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) {
+ Status = FlushOrDeletePolicyEntry (DataType, ParamPackage);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-f")) {
+ Status = FlushOrDeletePolicyEntry (DataType, ParamPackage);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {
+ Status = ListPolicyEntry (DataType, ParamPackage);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, mAppName);
+ goto Done;
+ }
+
+Done:
+ ShellCommandLineFreeVarList (ParamPackage);
+ HiiRemovePackages (mHiiHandle);
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfig.h b/NetworkPkg/Application/IpsecConfig/IpSecConfig.h new file mode 100644 index 0000000000..d1a7681012 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/IpSecConfig.h @@ -0,0 +1,123 @@ +/** @file
+ The internal structure and function declaration in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _IPSEC_CONFIG_H_
+#define _IPSEC_CONFIG_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/NetLib.h>
+
+#include <Protocol/IpSecConfig.h>
+
+#define EFI_IPSEC_CONFIG_GUID \
+ { \
+ 0x9db0c3ac, 0xd9d2, 0x4f96, {0x9e, 0xd7, 0x6d, 0xa6, 0x12, 0xa4, 0xf3, 0x27} \
+ }
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+#define IPSECCONFIG_STATUS_NAME L"IpSecStatus"
+
+#define BIT(x) (UINT32) (1 << (x))
+
+#define IPSEC_STATUS_DISABLED 0x0
+#define IPSEC_STATUS_ENABLED 0x1
+
+#define EFI_IP4_PROTO_ICMP 0x1
+#define EFI_IP4_PROTO_TCP 0x6
+#define EFI_IP4_PROTO_UDP 0x11
+
+#define EFI_IPSEC_ANY_PROTOCOL 0xFFFF
+#define EFI_IPSEC_ANY_PORT 0
+
+typedef struct _VAR_CHECK_ITEM {
+ CHAR16 *VarName;
+ UINT32 Attribute1;
+ UINT32 Attribute2;
+ UINT32 Attribute3;
+ UINT32 Attribute4;
+} VAR_CHECK_ITEM;
+
+typedef struct _SHELL_PARAM_PACKAGE{
+ LIST_ENTRY Link;
+ CHAR16 *Name;
+ ParamType Type;
+ CHAR16 *Value;
+ UINTN OriginalPosition;
+} SHELL_PARAM_PACKAGE;
+
+typedef struct _STR2INT {
+ CHAR16 *String;
+ UINT32 Integer;
+} STR2INT;
+
+extern EFI_IPSEC_CONFIG_PROTOCOL *mIpSecConfig;
+extern EFI_HII_HANDLE mHiiHandle;
+extern CHAR16 mAppName[];
+
+//
+// -P
+//
+extern STR2INT mMapPolicy[];
+
+//
+// --proto
+//
+extern STR2INT mMapIpProtocol[];
+
+//
+// --action
+//
+extern STR2INT mMapIpSecAction[];
+
+//
+// --mode
+//
+extern STR2INT mMapIpSecMode[];
+
+//
+// --dont-fragment
+//
+extern STR2INT mMapDfOption[];
+
+//
+// --ipsec-proto
+//
+extern STR2INT mMapIpSecProtocol[];
+//
+// --auth-algo
+//
+extern STR2INT mMapAuthAlgo[];
+
+//
+// --encrypt-algo
+//
+extern STR2INT mMapEncAlgo[];
+//
+// --auth-proto
+//
+extern STR2INT mMapAuthProto[];
+
+//
+// --auth-method
+//
+extern STR2INT mMapAuthMethod[];
+
+#endif
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf b/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf new file mode 100644 index 0000000000..1e0d4f44db --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf @@ -0,0 +1,61 @@ +## @file
+# Component description file for IpSecConfig6 application.
+#
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = IpSecConfig
+ FILE_GUID = 0922E604-F5EC-42ef-980D-A35E9A2B1844
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeIpSecConfig
+
+[Sources]
+ IpSecConfigStrings.uni
+ IpSecConfig.c
+ IpSecConfig.h
+ Dump.c
+ Dump.h
+ Indexer.c
+ Indexer.h
+ Match.c
+ Match.h
+ Delete.h
+ Delete.c
+ Helper.c
+ Helper.h
+ ForEach.c
+ ForEach.h
+ PolicyEntryOperation.c
+ PolicyEntryOperation.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiApplicationEntryPoint
+ BaseMemoryLib
+ ShellLib
+ MemoryAllocationLib
+ DebugLib
+ HiiLib
+ NetLib
+ UefiLib
+
+[Protocols]
+ gEfiIpSecProtocolGuid ##CONSUMS
+ gEfiIpSecConfigProtocolGuid ##CONSUMS
diff --git a/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni b/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni Binary files differnew file mode 100644 index 0000000000..fb0e27d802 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni diff --git a/NetworkPkg/Application/IpsecConfig/Match.c b/NetworkPkg/Application/IpsecConfig/Match.c new file mode 100644 index 0000000000..d6595ee8b8 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Match.c @@ -0,0 +1,163 @@ +/** @file
+ The implementation of match policy entry function in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IpSecConfig.h"
+#include "Indexer.h"
+#include "Match.h"
+
+/**
+ Private function to validate a buffer that should be filled with zero.
+
+ @param[in] Memory The pointer to the buffer.
+ @param[in] Size The size of the buffer.
+
+ @retval TRUE The memory is filled with zero.
+ @retval FALSE The memory isn't filled with zero.
+**/
+BOOLEAN
+IsMemoryZero (
+ IN VOID *Memory,
+ IN UINTN Size
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < Size; Index++) {
+ if (*((UINT8 *) Memory + Index) != 0) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ Find the matching SPD with Indexer.
+
+ @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
+ @param[in] Data The pointer to the EFI_IPSEC_SPD_DATA structure.
+ @param[in] Indexer The pointer to the SPD_ENTRY_INDEXER structure.
+
+ @retval TRUE The matched SPD is found.
+ @retval FALSE The matched SPD is not found.
+**/
+BOOLEAN
+MatchSpdEntry (
+ IN EFI_IPSEC_SPD_SELECTOR *Selector,
+ IN EFI_IPSEC_SPD_DATA *Data,
+ IN SPD_ENTRY_INDEXER *Indexer
+ )
+{
+ BOOLEAN Match;
+
+ Match = FALSE;
+ if (Indexer->Name != NULL) {
+ if ((Data->Name != NULL) && (AsciiStrCmp ((CHAR8 *) Indexer->Name, (CHAR8 *) Data->Name) == 0)) {
+ Match = TRUE;
+ }
+ } else {
+ if (Indexer->Index == 0) {
+ Match = TRUE;
+ }
+
+ Indexer->Index--;
+ }
+
+ return Match;
+}
+
+/**
+ Find the matching SAD with Indexer.
+
+ @param[in] SaId The pointer to the EFI_IPSEC_SA_ID structure.
+ @param[in] Data The pointer to the EFI_IPSEC_SA_DATA structure.
+ @param[in] Indexer The pointer to the SPD_ENTRY_INDEXER structure.
+
+ @retval TRUE The matched SAD is found.
+ @retval FALSE The matched SAD is not found.
+**/
+BOOLEAN
+MatchSadEntry (
+ IN EFI_IPSEC_SA_ID *SaId,
+ IN EFI_IPSEC_SA_DATA *Data,
+ IN SAD_ENTRY_INDEXER *Indexer
+ )
+{
+ BOOLEAN Match;
+
+ Match = FALSE;
+ if (!IsMemoryZero (&Indexer->SaId, sizeof (EFI_IPSEC_SA_ID))) {
+ Match = (BOOLEAN) (CompareMem (&Indexer->SaId, SaId, sizeof (EFI_IPSEC_SA_ID)) == 0);
+ } else {
+ if (Indexer->Index == 0) {
+ Match = TRUE;
+ }
+ Indexer->Index--;
+ }
+
+ return Match;
+}
+
+/**
+ Find the matching PAD with Indexer.
+
+ @param[in] PadId The pointer to the EFI_IPSEC_PAD_ID structure.
+ @param[in] Data The pointer to the EFI_IPSEC_PAD_DATA structure.
+ @param[in] Indexer The pointer to the SPD_ENTRY_INDEXER structure.
+
+ @retval TRUE The matched PAD is found.
+ @retval FALSE The matched PAD is not found.
+**/
+BOOLEAN
+MatchPadEntry (
+ IN EFI_IPSEC_PAD_ID *PadId,
+ IN EFI_IPSEC_PAD_DATA *Data,
+ IN PAD_ENTRY_INDEXER *Indexer
+ )
+{
+ BOOLEAN Match;
+
+ Match = FALSE;
+ if (!IsMemoryZero (&Indexer->PadId, sizeof (EFI_IPSEC_PAD_ID))) {
+ Match = (BOOLEAN) ((Indexer->PadId.PeerIdValid == PadId->PeerIdValid) &&
+ ((PadId->PeerIdValid &&
+ (StrCmp (
+ (CONST CHAR16 *) Indexer->PadId.Id.PeerId,
+ (CONST CHAR16 *) PadId->Id.PeerId
+ ) == 0)) ||
+ ((!PadId->PeerIdValid) &&
+ (Indexer->PadId.Id.IpAddress.PrefixLength == PadId->Id.IpAddress.PrefixLength) &&
+ (CompareMem (
+ &Indexer->PadId.Id.IpAddress.Address,
+ &PadId->Id.IpAddress.Address,
+ sizeof (EFI_IP_ADDRESS)
+ ) == 0))));
+ } else {
+ if (Indexer->Index == 0) {
+ Match = TRUE;
+ }
+
+ Indexer->Index--;
+ }
+
+ return Match;
+}
+
+MATCH_POLICY_ENTRY mMatchPolicyEntry[] = {
+ (MATCH_POLICY_ENTRY) MatchSpdEntry,
+ (MATCH_POLICY_ENTRY) MatchSadEntry,
+ (MATCH_POLICY_ENTRY) MatchPadEntry
+};
+
diff --git a/NetworkPkg/Application/IpsecConfig/Match.h b/NetworkPkg/Application/IpsecConfig/Match.h new file mode 100644 index 0000000000..1d73c5cfbc --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/Match.h @@ -0,0 +1,41 @@ +/** @file
+ The internal structure and function declaration of
+ match policy entry function in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MATCH_H_
+#define _MATCH_H_
+
+/**
+ The prototype for the MatchSpdEntry()/MatchSadEntry()/MatchPadEntry().
+ The functionality is to find the matching SPD/SAD/PAD with Indexer.
+
+ @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR union.
+ @param[in] Data The pointer to corresponding Data.
+ @param[in] Indexer The pointer to the POLICY_ENTRY_INDEXER union.
+
+ @retval TRUE The matched SPD/SAD/PAD is found.
+ @retval FALSE The matched SPD/SAD/PAD is not found.
+**/
+typedef
+BOOLEAN
+(* MATCH_POLICY_ENTRY) (
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
+ IN VOID *Data,
+ IN POLICY_ENTRY_INDEXER *Indexer
+ );
+
+extern MATCH_POLICY_ENTRY mMatchPolicyEntry[];
+
+#endif
diff --git a/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c b/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c new file mode 100644 index 0000000000..ddfbb4c504 --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c @@ -0,0 +1,2016 @@ +/** @file
+ The implementation of policy entry operation function in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "IpSecConfig.h"
+#include "Indexer.h"
+#include "Match.h"
+#include "Helper.h"
+#include "ForEach.h"
+#include "PolicyEntryOperation.h"
+
+/**
+ Fill in EFI_IPSEC_SPD_SELECTOR through ParamPackage list.
+
+ @param[out] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+ @param[in, out] ParamPackage The pointer to the Mask.
+
+ @retval EFI_SUCCESS Fill in EFI_IPSEC_SPD_SELECTOR successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+EFI_STATUS
+CreateSpdSelector (
+ OUT EFI_IPSEC_SPD_SELECTOR *Selector,
+ IN LIST_ENTRY *ParamPackage,
+ IN OUT UINT32 *Mask
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ CONST CHAR16 *ValueStr;
+
+ Status = EFI_SUCCESS;
+ ReturnStatus = EFI_SUCCESS;
+
+ //
+ // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local");
+ if (ValueStr != NULL) {
+ Selector->LocalAddressCount = 1;
+ Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->LocalAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--local",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= LOCAL;
+ }
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote");
+ if (ValueStr != NULL) {
+ Selector->RemoteAddressCount = 1;
+ Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->RemoteAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--remote",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= REMOTE;
+ }
+ }
+
+ Selector->NextLayerProtocol = EFI_IPSEC_ANY_PROTOCOL;
+
+ //
+ // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
+ //
+ Status = GetNumber (
+ L"--proto",
+ (UINT16) -1,
+ &Selector->NextLayerProtocol,
+ sizeof (UINT16),
+ mMapIpProtocol,
+ ParamPackage,
+ FORMAT_NUMBER | FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= PROTO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Selector->LocalPort = EFI_IPSEC_ANY_PORT;
+ Selector->RemotePort = EFI_IPSEC_ANY_PORT;
+
+ //
+ // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local-port");
+ if (ValueStr != NULL) {
+ Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->LocalPort, &Selector->LocalPortRange);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--local-port",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= LOCAL_PORT;
+ }
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote-port");
+ if (ValueStr != NULL) {
+ Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->RemotePort, &Selector->RemotePortRange);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--remote-port",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= REMOTE_PORT;
+ }
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
+ //
+ Status = GetNumber (
+ L"--icmp-type",
+ (UINT8) -1,
+ &Selector->LocalPort,
+ sizeof (UINT16),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= ICMP_TYPE;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
+ //
+ Status = GetNumber (
+ L"--icmp-code",
+ (UINT8) -1,
+ &Selector->RemotePort,
+ sizeof (UINT16),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= ICMP_CODE;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ return ReturnStatus;
+}
+
+/**
+ Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA through ParamPackage list.
+
+ @param[out] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
+ @param[out] Data The pointer to the EFI_IPSEC_SPD_DATA structure.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+ @param[out] Mask The pointer to the Mask.
+ @param[in] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+EFI_STATUS
+CreateSpdEntry (
+ OUT EFI_IPSEC_SPD_SELECTOR **Selector,
+ OUT EFI_IPSEC_SPD_DATA **Data,
+ IN LIST_ENTRY *ParamPackage,
+ OUT UINT32 *Mask,
+ IN BOOLEAN CreateNew
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ CONST CHAR16 *ValueStr;
+ UINTN DataSize;
+
+ Status = EFI_SUCCESS;
+ *Mask = 0;
+
+ *Selector = AllocateZeroPool (sizeof (EFI_IPSEC_SPD_SELECTOR) + 2 * sizeof (EFI_IP_ADDRESS_INFO));
+ ASSERT (*Selector != NULL);
+
+ (*Selector)->LocalAddress = (EFI_IP_ADDRESS_INFO *) (*Selector + 1);
+ (*Selector)->RemoteAddress = (*Selector)->LocalAddress + 1;
+
+ ReturnStatus = CreateSpdSelector (*Selector, ParamPackage, Mask);
+
+ //
+ // SPD DATA
+ // NOTE: Allocate enough memory and add padding for different arch.
+ //
+ DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SPD_DATA));
+ DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_PROCESS_POLICY));
+ DataSize += sizeof (EFI_IPSEC_TUNNEL_OPTION);
+
+ *Data = AllocateZeroPool (DataSize);
+ ASSERT (*Data != NULL);
+
+ (*Data)->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER (
+ (*Data + 1),
+ sizeof (UINTN)
+ );
+ (*Data)->ProcessingPolicy->TunnelOption = (EFI_IPSEC_TUNNEL_OPTION *) ALIGN_POINTER (
+ ((*Data)->ProcessingPolicy + 1),
+ sizeof (UINTN)
+ );
+
+
+ //
+ // Convert user imput from string to integer, and fill in the Name in EFI_IPSEC_SPD_DATA.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--name");
+ if (ValueStr != NULL) {
+ UnicodeStrToAsciiStr (ValueStr, (CHAR8 *) (*Data)->Name);
+ *Mask |= NAME;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the PackageFlag in EFI_IPSEC_SPD_DATA.
+ //
+ Status = GetNumber (
+ L"--packet-flag",
+ (UINT8) -1,
+ &(*Data)->PackageFlag,
+ sizeof (UINT32),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= PACKET_FLAG;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the Action in EFI_IPSEC_SPD_DATA.
+ //
+ Status = GetNumber (
+ L"--action",
+ (UINT8) -1,
+ &(*Data)->Action,
+ sizeof (UINT32),
+ mMapIpSecAction,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= ACTION;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the ExtSeqNum in EFI_IPSEC_SPD_DATA.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence")) {
+ (*Data)->ProcessingPolicy->ExtSeqNum = TRUE;
+ *Mask |= EXT_SEQUENCE;
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence-")) {
+ (*Data)->ProcessingPolicy->ExtSeqNum = FALSE;
+ *Mask |= EXT_SEQUENCE;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the SeqOverflow in EFI_IPSEC_SPD_DATA.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow")) {
+ (*Data)->ProcessingPolicy->SeqOverflow = TRUE;
+ *Mask |= SEQUENCE_OVERFLOW;
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow-")) {
+ (*Data)->ProcessingPolicy->SeqOverflow = FALSE;
+ *Mask |= SEQUENCE_OVERFLOW;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the FragCheck in EFI_IPSEC_SPD_DATA.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check")) {
+ (*Data)->ProcessingPolicy->FragCheck = TRUE;
+ *Mask |= FRAGMENT_CHECK;
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check-")) {
+ (*Data)->ProcessingPolicy->FragCheck = FALSE;
+ *Mask |= FRAGMENT_CHECK;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the ProcessingPolicy in EFI_IPSEC_SPD_DATA.
+ //
+ Status = GetNumber (
+ L"--lifebyte",
+ (UINT64) -1,
+ &(*Data)->ProcessingPolicy->SaLifetime.ByteCount,
+ sizeof (UINT64),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= LIFEBYTE;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--lifetime",
+ (UINT64) -1,
+ &(*Data)->ProcessingPolicy->SaLifetime.HardLifetime,
+ sizeof (UINT64),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= LIFETIME;
+ }
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--lifetime-soft",
+ (UINT64) -1,
+ &(*Data)->ProcessingPolicy->SaLifetime.SoftLifetime,
+ sizeof (UINT64),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= LIFETIME_SOFT;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ (*Data)->ProcessingPolicy->Mode = EfiIPsecTransport;
+ Status = GetNumber (
+ L"--mode",
+ 0,
+ &(*Data)->ProcessingPolicy->Mode,
+ sizeof (UINT32),
+ mMapIpSecMode,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= MODE;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-local");
+ if (ValueStr != NULL) {
+ Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->LocalTunnelAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--tunnel-local",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= TUNNEL_LOCAL;
+ }
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-remote");
+ if (ValueStr != NULL) {
+ Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->RemoteTunnelAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--tunnel-remote",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= TUNNEL_REMOTE;
+ }
+ }
+
+ (*Data)->ProcessingPolicy->TunnelOption->DF = EfiIPsecTunnelCopyDf;
+ Status = GetNumber (
+ L"--dont-fragment",
+ 0,
+ &(*Data)->ProcessingPolicy->TunnelOption->DF,
+ sizeof (UINT32),
+ mMapDfOption,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= DONT_FRAGMENT;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ (*Data)->ProcessingPolicy->Proto = EfiIPsecESP;
+ Status = GetNumber (
+ L"--ipsec-proto",
+ 0,
+ &(*Data)->ProcessingPolicy->Proto,
+ sizeof (UINT32),
+ mMapIpSecProtocol,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= IPSEC_PROTO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--encrypt-algo",
+ 0,
+ &(*Data)->ProcessingPolicy->EncAlgoId,
+ sizeof (UINT8),
+ mMapEncAlgo,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= ENCRYPT_ALGO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--auth-algo",
+ 0,
+ &(*Data)->ProcessingPolicy->AuthAlgoId,
+ sizeof (UINT8),
+ mMapAuthAlgo,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= AUTH_ALGO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Cannot check Mode against EfiIPsecTunnel, because user may want to change tunnel_remote only so the Mode is not set.
+ //
+ if ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE | DONT_FRAGMENT)) == 0) {
+ (*Data)->ProcessingPolicy->TunnelOption = NULL;
+ }
+
+ if ((*Mask & (EXT_SEQUENCE | SEQUENCE_OVERFLOW | FRAGMENT_CHECK | LIFEBYTE |
+ LIFETIME_SOFT | LIFETIME | MODE | TUNNEL_LOCAL | TUNNEL_REMOTE |
+ DONT_FRAGMENT | IPSEC_PROTO | AUTH_ALGO | ENCRYPT_ALGO)) == 0) {
+ if ((*Data)->Action != EfiIPsecActionProtect) {
+ //
+ // User may not provide additional parameter for Protect action, so we cannot simply set ProcessingPolicy to NULL.
+ //
+ (*Data)->ProcessingPolicy = NULL;
+ }
+ }
+
+ if (CreateNew) {
+ if ((*Mask & (LOCAL | REMOTE | PROTO | ACTION)) != (LOCAL | REMOTE | PROTO | ACTION)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--local --remote --proto --action"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else if (((*Data)->Action == EfiIPsecActionProtect) &&
+ ((*Data)->ProcessingPolicy->Mode == EfiIPsecTunnel) &&
+ ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE))) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--tunnel-local --tunnel-remote"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+ }
+
+ return ReturnStatus;
+}
+
+/**
+ Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA through ParamPackage list.
+
+ @param[out] SaId The pointer to the EFI_IPSEC_SA_ID structure.
+ @param[out] Data The pointer to the EFI_IPSEC_SA_DATA structure.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+ @param[out] Mask The pointer to the Mask.
+ @param[in] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+EFI_STATUS
+CreateSadEntry (
+ OUT EFI_IPSEC_SA_ID **SaId,
+ OUT EFI_IPSEC_SA_DATA **Data,
+ IN LIST_ENTRY *ParamPackage,
+ OUT UINT32 *Mask,
+ IN BOOLEAN CreateNew
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ UINTN AuthKeyLength;
+ UINTN EncKeyLength;
+ CONST CHAR16 *ValueStr;
+ UINTN DataSize;
+
+ Status = EFI_SUCCESS;
+ ReturnStatus = EFI_SUCCESS;
+ *Mask = 0;
+ AuthKeyLength = 0;
+ EncKeyLength = 0;
+
+ *SaId = AllocateZeroPool (sizeof (EFI_IPSEC_SA_ID));
+ ASSERT (*SaId != NULL);
+
+ //
+ // Convert user imput from string to integer, and fill in the Spi in EFI_IPSEC_SA_ID.
+ //
+ Status = GetNumber (L"--spi", (UINT32) -1, &(*SaId)->Spi, sizeof (UINT32), NULL, ParamPackage, FORMAT_NUMBER);
+ if (!EFI_ERROR (Status)) {
+ *Mask |= SPI;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the Proto in EFI_IPSEC_SA_ID.
+ //
+ Status = GetNumber (
+ L"--ipsec-proto",
+ 0,
+ &(*SaId)->Proto,
+ sizeof (EFI_IPSEC_PROTOCOL_TYPE),
+ mMapIpSecProtocol,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= IPSEC_PROTO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--dest");
+ if (ValueStr != NULL) {
+ Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*SaId)->DestAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--dest",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= DEST;
+ }
+ }
+
+ //
+ // Convert user imput from string to integer, and fill in EFI_IPSEC_SA_DATA.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");
+ if (ValueStr != NULL) {
+ AuthKeyLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");
+ if (ValueStr != NULL) {
+ EncKeyLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);
+ }
+
+ //
+ // EFI_IPSEC_SA_DATA:
+ // +------------
+ // | EFI_IPSEC_SA_DATA
+ // +-----------------------
+ // | AuthKey
+ // +-------------------------
+ // | EncKey
+ // +-------------------------
+ // | SpdSelector
+ //
+ // Notes: To make sure the address alignment add padding after each data if needed.
+ //
+ DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA));
+ DataSize = ALIGN_VARIABLE (DataSize + AuthKeyLength);
+ DataSize = ALIGN_VARIABLE (DataSize + EncKeyLength);
+ DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_SPD_SELECTOR));
+ DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IP_ADDRESS_INFO));
+ DataSize += sizeof (EFI_IP_ADDRESS_INFO);
+
+
+
+ *Data = AllocateZeroPool (DataSize);
+ ASSERT (*Data != NULL);
+
+ (*Data)->ManualSet = TRUE;
+ (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER (((*Data) + 1), sizeof (UINTN));
+ (*Data)->AlgoInfo.EspAlgoInfo.EncKey = (VOID *) ALIGN_POINTER (
+ ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.AuthKey + AuthKeyLength),
+ sizeof (UINTN)
+ );
+ (*Data)->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER (
+ ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.EncKey + EncKeyLength),
+ sizeof (UINTN)
+ );
+ (*Data)->SpdSelector->LocalAddress = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (
+ ((UINT8 *) (*Data)->SpdSelector + sizeof (EFI_IPSEC_SPD_SELECTOR)),
+ sizeof (UINTN));
+ (*Data)->SpdSelector->RemoteAddress = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (
+ (*Data)->SpdSelector->LocalAddress + 1,
+ sizeof (UINTN)
+ );
+
+ (*Data)->Mode = EfiIPsecTransport;
+ Status = GetNumber (
+ L"--mode",
+ 0,
+ &(*Data)->Mode,
+ sizeof (EFI_IPSEC_MODE),
+ mMapIpSecMode,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= MODE;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // According to RFC 4303-3.3.3. The first packet sent using a given SA
+ // will contain a sequence number of 1.
+ //
+ (*Data)->SNCount = 1;
+ Status = GetNumber (
+ L"--sequence-number",
+ (UINT64) -1,
+ &(*Data)->SNCount,
+ sizeof (UINT64),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= SEQUENCE_NUMBER;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ (*Data)->AntiReplayWindows = 0;
+ Status = GetNumber (
+ L"--antireplay-window",
+ (UINT8) -1,
+ &(*Data)->AntiReplayWindows,
+ sizeof (UINT8),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= SEQUENCE_NUMBER;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--encrypt-algo",
+ 0,
+ &(*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId,
+ sizeof (UINT8),
+ mMapEncAlgo,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= ENCRYPT_ALGO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");
+ if (ValueStr != NULL ) {
+ (*Data)->AlgoInfo.EspAlgoInfo.EncKeyLength = EncKeyLength;
+ CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.EncKey, ValueStr, EncKeyLength);
+ *Mask |= ENCRYPT_KEY;
+ } else {
+ (*Data)->AlgoInfo.EspAlgoInfo.EncKey = NULL;
+ }
+
+ Status = GetNumber (
+ L"--auth-algo",
+ 0,
+ &(*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId,
+ sizeof (UINT8),
+ mMapAuthAlgo,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= AUTH_ALGO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");
+ if (ValueStr != NULL) {
+ (*Data)->AlgoInfo.EspAlgoInfo.AuthKeyLength = AuthKeyLength;
+ CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.AuthKey, ValueStr, AuthKeyLength);
+ *Mask |= AUTH_KEY;
+ } else {
+ (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = NULL;
+ }
+
+ Status = GetNumber (
+ L"--lifebyte",
+ (UINT64) -1,
+ &(*Data)->SaLifetime.ByteCount,
+ sizeof (UINT64),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= LIFEBYTE;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--lifetime",
+ (UINT64) -1,
+ &(*Data)->SaLifetime.HardLifetime,
+ sizeof (UINT64),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= LIFETIME;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--lifetime-soft",
+ (UINT64) -1,
+ &(*Data)->SaLifetime.SoftLifetime,
+ sizeof (UINT64),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= LIFETIME_SOFT;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--path-mtu",
+ (UINT32) -1,
+ &(*Data)->PathMTU,
+ sizeof (UINT32),
+ NULL,
+ ParamPackage,
+ FORMAT_NUMBER
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= PATH_MTU;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ ReturnStatus = CreateSpdSelector ((*Data)->SpdSelector, ParamPackage, Mask);
+
+ if (CreateNew) {
+ if ((*Mask & (SPI | IPSEC_PROTO | DEST)) != (SPI | IPSEC_PROTO | DEST)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--spi --ipsec-proto --dest"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ if ((*SaId)->Proto == EfiIPsecAH) {
+ if ((*Mask & AUTH_ALGO) == 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
+ mHiiHandle,
+ mAppName,
+ L"--auth-algo"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != EFI_IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
+ mHiiHandle,
+ mAppName,
+ L"--auth-key"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+ } else {
+ if ((*Mask & ENCRYPT_ALGO) == 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
+ mHiiHandle,
+ mAppName,
+ L"--encrypt-algo"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else if ((*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId != EFI_IPSEC_EALG_NONE && (*Mask & ENCRYPT_KEY) == 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
+ mHiiHandle,
+ mAppName,
+ L"--encrypt-key"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+ }
+
+ return ReturnStatus;
+}
+
+/**
+ Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA through ParamPackage list.
+
+ @param[out] PadId The pointer to the EFI_IPSEC_PAD_ID structure.
+ @param[out] Data The pointer to the EFI_IPSEC_PAD_DATA structure.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+ @param[out] Mask The pointer to the Mask.
+ @param[in] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+EFI_STATUS
+CreatePadEntry (
+ OUT EFI_IPSEC_PAD_ID **PadId,
+ OUT EFI_IPSEC_PAD_DATA **Data,
+ IN LIST_ENTRY *ParamPackage,
+ OUT UINT32 *Mask,
+ IN BOOLEAN CreateNew
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ EFI_FILE_HANDLE FileHandle;
+ UINT64 FileSize;
+ UINTN AuthDataLength;
+ UINTN RevocationDataLength;
+ UINTN DataLength;
+ UINTN Index;
+ CONST CHAR16 *ValueStr;
+ UINTN DataSize;
+
+ Status = EFI_SUCCESS;
+ ReturnStatus = EFI_SUCCESS;
+ *Mask = 0;
+ AuthDataLength = 0;
+ RevocationDataLength = 0;
+
+ *PadId = AllocateZeroPool (sizeof (EFI_IPSEC_PAD_ID));
+ ASSERT (*PadId != NULL);
+
+ //
+ // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_ID.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-address");
+ if (ValueStr != NULL) {
+ (*PadId)->PeerIdValid = FALSE;
+ Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &(*PadId)->Id.IpAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
+ mHiiHandle,
+ mAppName,
+ L"--peer-address",
+ ValueStr
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ *Mask |= PEER_ADDRESS;
+ }
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-id");
+ if (ValueStr != NULL) {
+ (*PadId)->PeerIdValid = TRUE;
+ StrnCpy ((CHAR16 *) (*PadId)->Id.PeerId, ValueStr, ARRAY_SIZE ((*PadId)->Id.PeerId) - 1);
+ *Mask |= PEER_ID;
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");
+ if (ValueStr != NULL) {
+ if (ValueStr[0] == L'@') {
+ //
+ // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"
+ //
+ Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
+ mHiiHandle,
+ mAppName,
+ &ValueStr[1]
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ Status = ShellGetFileSize (FileHandle, &FileSize);
+ ShellCloseFile (&FileHandle);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
+ mHiiHandle,
+ mAppName,
+ &ValueStr[1]
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ AuthDataLength = (UINTN) FileSize;
+ }
+ }
+ } else {
+ AuthDataLength = StrLen (ValueStr);
+ }
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");
+ if (ValueStr != NULL) {
+ RevocationDataLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);
+ }
+
+ //
+ // Allocate Buffer for Data. Add padding after each struct to make sure the alignment
+ // in different Arch.
+ //
+ DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_PAD_DATA));
+ DataSize = ALIGN_VARIABLE (DataSize + AuthDataLength);
+ DataSize += RevocationDataLength;
+
+ *Data = AllocateZeroPool (DataSize);
+ ASSERT (*Data != NULL);
+
+ (*Data)->AuthData = (VOID *) ALIGN_POINTER ((*Data + 1), sizeof (UINTN));
+ (*Data)->RevocationData = (VOID *) ALIGN_POINTER (((UINT8 *) (*Data + 1) + AuthDataLength), sizeof (UINTN));
+ (*Data)->AuthProtocol = EfiIPsecAuthProtocolIKEv1;
+
+ //
+ // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_DATA.
+ //
+ Status = GetNumber (
+ L"--auth-proto",
+ 0,
+ &(*Data)->AuthProtocol,
+ sizeof (EFI_IPSEC_AUTH_PROTOCOL_TYPE),
+ mMapAuthProto,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= AUTH_PROTO;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetNumber (
+ L"--auth-method",
+ 0,
+ &(*Data)->AuthMethod,
+ sizeof (EFI_IPSEC_AUTH_METHOD),
+ mMapAuthMethod,
+ ParamPackage,
+ FORMAT_STRING
+ );
+ if (!EFI_ERROR (Status)) {
+ *Mask |= AUTH_METHOD;
+ }
+
+ if (Status == EFI_INVALID_PARAMETER) {
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id")) {
+ (*Data)->IkeIdFlag = TRUE;
+ *Mask |= IKE_ID;
+ }
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id-")) {
+ (*Data)->IkeIdFlag = FALSE;
+ *Mask |= IKE_ID;
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");
+ if (ValueStr != NULL) {
+ if (ValueStr[0] == L'@') {
+ //
+ // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"
+ //
+
+ Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
+ mHiiHandle,
+ mAppName,
+ &ValueStr[1]
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ (*Data)->AuthData = NULL;
+ } else {
+ DataLength = AuthDataLength;
+ Status = ShellReadFile (FileHandle, &DataLength, (*Data)->AuthData);
+ ShellCloseFile (&FileHandle);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
+ mHiiHandle,
+ mAppName,
+ &ValueStr[1]
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ (*Data)->AuthData = NULL;
+ } else {
+ ASSERT (DataLength == AuthDataLength);
+ *Mask |= AUTH_DATA;
+ }
+ }
+ } else {
+ for (Index = 0; Index < AuthDataLength; Index++) {
+ ((CHAR8 *) (*Data)->AuthData)[Index] = (CHAR8) ValueStr[Index];
+ }
+ (*Data)->AuthDataSize = AuthDataLength;
+ *Mask |= AUTH_DATA;
+ }
+ }
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");
+ if (ValueStr != NULL) {
+ CopyMem ((*Data)->RevocationData, ValueStr, RevocationDataLength);
+ (*Data)->RevocationDataSize = RevocationDataLength;
+ *Mask |= REVOCATION_DATA;
+ } else {
+ (*Data)->RevocationData = NULL;
+ }
+
+ if (CreateNew) {
+ if ((*Mask & (PEER_ID | PEER_ADDRESS)) == 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--peer-id --peer-address"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ } else if ((*Mask & (AUTH_METHOD | AUTH_DATA)) != (AUTH_METHOD | AUTH_DATA)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--auth-method --auth-data"
+ );
+ ReturnStatus = EFI_INVALID_PARAMETER;
+ }
+ }
+
+ return ReturnStatus;
+}
+
+CREATE_POLICY_ENTRY mCreatePolicyEntry[] = {
+ (CREATE_POLICY_ENTRY) CreateSpdEntry,
+ (CREATE_POLICY_ENTRY) CreateSadEntry,
+ (CREATE_POLICY_ENTRY) CreatePadEntry
+};
+
+/**
+ Combine old SPD entry with new SPD entry.
+
+ @param[in, out] OldSelector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
+ @param[in, out] OldData The pointer to the EFI_IPSEC_SPD_DATA structure.
+ @param[in] NewSelector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
+ @param[in] NewData The pointer to the EFI_IPSEC_SPD_DATA structure.
+ @param[in] Mask The pointer to the Mask.
+ @param[out] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Combined successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+EFI_STATUS
+CombineSpdEntry (
+ IN OUT EFI_IPSEC_SPD_SELECTOR *OldSelector,
+ IN OUT EFI_IPSEC_SPD_DATA *OldData,
+ IN EFI_IPSEC_SPD_SELECTOR *NewSelector,
+ IN EFI_IPSEC_SPD_DATA *NewData,
+ IN UINT32 Mask,
+ OUT BOOLEAN *CreateNew
+ )
+{
+
+ //
+ // Process Selector
+ //
+ *CreateNew = FALSE;
+ if ((Mask & LOCAL) == 0) {
+ NewSelector->LocalAddressCount = OldSelector->LocalAddressCount;
+ NewSelector->LocalAddress = OldSelector->LocalAddress;
+ } else if ((NewSelector->LocalAddressCount != OldSelector->LocalAddressCount) ||
+ (CompareMem (NewSelector->LocalAddress, OldSelector->LocalAddress, NewSelector->LocalAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {
+ *CreateNew = TRUE;
+ }
+
+ if ((Mask & REMOTE) == 0) {
+ NewSelector->RemoteAddressCount = OldSelector->RemoteAddressCount;
+ NewSelector->RemoteAddress = OldSelector->RemoteAddress;
+ } else if ((NewSelector->RemoteAddressCount != OldSelector->RemoteAddressCount) ||
+ (CompareMem (NewSelector->RemoteAddress, OldSelector->RemoteAddress, NewSelector->RemoteAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {
+ *CreateNew = TRUE;
+ }
+
+ if ((Mask & PROTO) == 0) {
+ NewSelector->NextLayerProtocol = OldSelector->NextLayerProtocol;
+ } else if (NewSelector->NextLayerProtocol != OldSelector->NextLayerProtocol) {
+ *CreateNew = TRUE;
+ }
+
+ switch (NewSelector->NextLayerProtocol) {
+ case EFI_IP4_PROTO_TCP:
+ case EFI_IP4_PROTO_UDP:
+ if ((Mask & LOCAL_PORT) == 0) {
+ NewSelector->LocalPort = OldSelector->LocalPort;
+ NewSelector->LocalPortRange = OldSelector->LocalPortRange;
+ } else if ((NewSelector->LocalPort != OldSelector->LocalPort) ||
+ (NewSelector->LocalPortRange != OldSelector->LocalPortRange)) {
+ *CreateNew = TRUE;
+ }
+
+ if ((Mask & REMOTE_PORT) == 0) {
+ NewSelector->RemotePort = OldSelector->RemotePort;
+ NewSelector->RemotePortRange = OldSelector->RemotePortRange;
+ } else if ((NewSelector->RemotePort != OldSelector->RemotePort) ||
+ (NewSelector->RemotePortRange != OldSelector->RemotePortRange)) {
+ *CreateNew = TRUE;
+ }
+ break;
+
+ case EFI_IP4_PROTO_ICMP:
+ if ((Mask & ICMP_TYPE) == 0) {
+ NewSelector->LocalPort = OldSelector->LocalPort;
+ } else if (NewSelector->LocalPort != OldSelector->LocalPort) {
+ *CreateNew = TRUE;
+ }
+
+ if ((Mask & ICMP_CODE) == 0) {
+ NewSelector->RemotePort = OldSelector->RemotePort;
+ } else if (NewSelector->RemotePort != OldSelector->RemotePort) {
+ *CreateNew = TRUE;
+ }
+ break;
+ }
+ //
+ // Process Data
+ //
+ if ((Mask & NAME) != 0) {
+ AsciiStrCpy ((CHAR8 *) OldData->Name, (CHAR8 *) NewData->Name);
+ }
+
+ if ((Mask & PACKET_FLAG) != 0) {
+ OldData->PackageFlag = NewData->PackageFlag;
+ }
+
+ if ((Mask & ACTION) != 0) {
+ OldData->Action = NewData->Action;
+ }
+
+ if (OldData->Action != EfiIPsecActionProtect) {
+ OldData->ProcessingPolicy = NULL;
+ } else {
+ //
+ // Protect
+ //
+ if (OldData->ProcessingPolicy == NULL) {
+ //
+ // Just point to new data if originally NULL.
+ //
+ OldData->ProcessingPolicy = NewData->ProcessingPolicy;
+ if (OldData->ProcessingPolicy->Mode == EfiIPsecTunnel &&
+ (Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)
+ ) {
+ //
+ // Change to Protect action and Tunnel mode, but without providing local/remote tunnel address.
+ //
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--tunnel-local --tunnel-remote"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ //
+ // Modify some of the data.
+ //
+ if ((Mask & EXT_SEQUENCE) != 0) {
+ OldData->ProcessingPolicy->ExtSeqNum = NewData->ProcessingPolicy->ExtSeqNum;
+ }
+
+ if ((Mask & SEQUENCE_OVERFLOW) != 0) {
+ OldData->ProcessingPolicy->SeqOverflow = NewData->ProcessingPolicy->SeqOverflow;
+ }
+
+ if ((Mask & FRAGMENT_CHECK) != 0) {
+ OldData->ProcessingPolicy->FragCheck = NewData->ProcessingPolicy->FragCheck;
+ }
+
+ if ((Mask & LIFEBYTE) != 0) {
+ OldData->ProcessingPolicy->SaLifetime.ByteCount = NewData->ProcessingPolicy->SaLifetime.ByteCount;
+ }
+
+ if ((Mask & LIFETIME_SOFT) != 0) {
+ OldData->ProcessingPolicy->SaLifetime.SoftLifetime = NewData->ProcessingPolicy->SaLifetime.SoftLifetime;
+ }
+
+ if ((Mask & LIFETIME) != 0) {
+ OldData->ProcessingPolicy->SaLifetime.HardLifetime = NewData->ProcessingPolicy->SaLifetime.HardLifetime;
+ }
+
+ if ((Mask & MODE) != 0) {
+ OldData->ProcessingPolicy->Mode = NewData->ProcessingPolicy->Mode;
+ }
+
+ if ((Mask & IPSEC_PROTO) != 0) {
+ OldData->ProcessingPolicy->Proto = NewData->ProcessingPolicy->Proto;
+ }
+
+ if ((Mask & AUTH_ALGO) != 0) {
+ OldData->ProcessingPolicy->AuthAlgoId = NewData->ProcessingPolicy->AuthAlgoId;
+ }
+
+ if ((Mask & ENCRYPT_ALGO) != 0) {
+ OldData->ProcessingPolicy->EncAlgoId = NewData->ProcessingPolicy->EncAlgoId;
+ }
+
+ if (OldData->ProcessingPolicy->Mode != EfiIPsecTunnel) {
+ OldData->ProcessingPolicy->TunnelOption = NULL;
+ } else {
+ if (OldData->ProcessingPolicy->TunnelOption == NULL) {
+ //
+ // Set from Transport mode to Tunnel mode, should ensure TUNNEL_LOCAL & TUNNEL_REMOTE both exists.
+ //
+ if ((Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--tunnel-local --tunnel-remote"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldData->ProcessingPolicy->TunnelOption = NewData->ProcessingPolicy->TunnelOption;
+ } else {
+ if ((Mask & TUNNEL_LOCAL) != 0) {
+ CopyMem (
+ &OldData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,
+ &NewData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,
+ sizeof (EFI_IP_ADDRESS)
+ );
+ }
+
+ if ((Mask & TUNNEL_REMOTE) != 0) {
+ CopyMem (
+ &OldData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,
+ &NewData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,
+ sizeof (EFI_IP_ADDRESS)
+ );
+ }
+
+ if ((Mask & DONT_FRAGMENT) != 0) {
+ OldData->ProcessingPolicy->TunnelOption->DF = NewData->ProcessingPolicy->TunnelOption->DF;
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Combine old SAD entry with new SAD entry.
+
+ @param[in, out] OldSaId The pointer to the EFI_IPSEC_SA_ID structure.
+ @param[in, out] OldData The pointer to the EFI_IPSEC_SA_DATA structure.
+ @param[in] NewSaId The pointer to the EFI_IPSEC_SA_ID structure.
+ @param[in] NewData The pointer to the EFI_IPSEC_SA_DATA structure.
+ @param[in] Mask The pointer to the Mask.
+ @param[out] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Combined successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+EFI_STATUS
+CombineSadEntry (
+ IN OUT EFI_IPSEC_SA_ID *OldSaId,
+ IN OUT EFI_IPSEC_SA_DATA *OldData,
+ IN EFI_IPSEC_SA_ID *NewSaId,
+ IN EFI_IPSEC_SA_DATA *NewData,
+ IN UINT32 Mask,
+ OUT BOOLEAN *CreateNew
+ )
+{
+
+ *CreateNew = FALSE;
+
+ if ((Mask & SPI) == 0) {
+ NewSaId->Spi = OldSaId->Spi;
+ } else if (NewSaId->Spi != OldSaId->Spi) {
+ *CreateNew = TRUE;
+ }
+
+ if ((Mask & IPSEC_PROTO) == 0) {
+ NewSaId->Proto = OldSaId->Proto;
+ } else if (NewSaId->Proto != OldSaId->Proto) {
+ *CreateNew = TRUE;
+ }
+
+ if ((Mask & DEST) == 0) {
+ CopyMem (&NewSaId->DestAddress, &OldSaId->DestAddress, sizeof (EFI_IP_ADDRESS));
+ } else if (CompareMem (&NewSaId->DestAddress, &OldSaId->DestAddress, sizeof (EFI_IP_ADDRESS)) != 0) {
+ *CreateNew = TRUE;
+ }
+
+ //
+ // Process SA_DATA.
+ //
+ if ((Mask & MODE) != 0) {
+ OldData->Mode = NewData->Mode;
+ }
+
+ if ((Mask & SEQUENCE_NUMBER) != 0) {
+ OldData->SNCount = NewData->SNCount;
+ }
+
+ if ((Mask & ANTIREPLAY_WINDOW) != 0) {
+ OldData->AntiReplayWindows = NewData->AntiReplayWindows;
+ }
+
+ if ((Mask & AUTH_ALGO) != 0) {
+ OldData->AlgoInfo.EspAlgoInfo.AuthAlgoId = NewData->AlgoInfo.EspAlgoInfo.AuthAlgoId;
+ }
+
+ if ((Mask & AUTH_KEY) != 0) {
+ OldData->AlgoInfo.EspAlgoInfo.AuthKey = NewData->AlgoInfo.EspAlgoInfo.AuthKey;
+ OldData->AlgoInfo.EspAlgoInfo.AuthKeyLength = NewData->AlgoInfo.EspAlgoInfo.AuthKeyLength;
+ }
+
+ if ((Mask & ENCRYPT_ALGO) != 0) {
+ OldData->AlgoInfo.EspAlgoInfo.EncAlgoId = NewData->AlgoInfo.EspAlgoInfo.EncAlgoId;
+ }
+
+ if ((Mask & ENCRYPT_KEY) != 0) {
+ OldData->AlgoInfo.EspAlgoInfo.EncKey = NewData->AlgoInfo.EspAlgoInfo.EncKey;
+ OldData->AlgoInfo.EspAlgoInfo.EncKeyLength = NewData->AlgoInfo.EspAlgoInfo.EncKeyLength;
+ }
+
+ if (NewSaId->Proto == EfiIPsecAH) {
+ if ((Mask & (ENCRYPT_ALGO | ENCRYPT_KEY)) != 0) {
+ //
+ // Should not provide encrypt_* if AH.
+ //
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_UNWANTED_PARAMETER),
+ mHiiHandle,
+ mAppName,
+ L"--encrypt-algo --encrypt-key"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (NewSaId->Proto == EfiIPsecESP && OldSaId->Proto == EfiIPsecAH) {
+ //
+ // AH -> ESP
+ // Should provide encrypt_algo at least.
+ //
+ if ((Mask & ENCRYPT_ALGO) == 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
+ mHiiHandle,
+ mAppName,
+ L"--encrypt-algo"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Encrypt_key should be provided if algorithm is not NONE.
+ //
+ if (NewData->AlgoInfo.EspAlgoInfo.EncAlgoId != EFI_IPSEC_EALG_NONE && (Mask & ENCRYPT_KEY) == 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
+ mHiiHandle,
+ mAppName,
+ L"--encrypt-algo"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if ((Mask & LIFEBYTE) != 0) {
+ OldData->SaLifetime.ByteCount = NewData->SaLifetime.ByteCount;
+ }
+
+ if ((Mask & LIFETIME_SOFT) != 0) {
+ OldData->SaLifetime.SoftLifetime = NewData->SaLifetime.SoftLifetime;
+ }
+
+ if ((Mask & LIFETIME) != 0) {
+ OldData->SaLifetime.HardLifetime = NewData->SaLifetime.HardLifetime;
+ }
+
+ if ((Mask & PATH_MTU) != 0) {
+ OldData->PathMTU = NewData->PathMTU;
+ }
+ //
+ // Process SpdSelector.
+ //
+ if (OldData->SpdSelector == NULL) {
+ if ((Mask & (LOCAL | REMOTE | PROTO | LOCAL_PORT | REMOTE_PORT | ICMP_TYPE | ICMP_CODE)) != 0) {
+ if ((Mask & (LOCAL | REMOTE | PROTO)) != (LOCAL | REMOTE | PROTO)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
+ mHiiHandle,
+ mAppName,
+ L"--local --remote --proto"
+ );
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldData->SpdSelector = NewData->SpdSelector;
+ }
+ } else {
+ if ((Mask & LOCAL) != 0) {
+ OldData->SpdSelector->LocalAddressCount = NewData->SpdSelector->LocalAddressCount;
+ OldData->SpdSelector->LocalAddress = NewData->SpdSelector->LocalAddress;
+ }
+
+ if ((Mask & REMOTE) != 0) {
+ OldData->SpdSelector->RemoteAddressCount = NewData->SpdSelector->RemoteAddressCount;
+ OldData->SpdSelector->RemoteAddress = NewData->SpdSelector->RemoteAddress;
+ }
+
+ if ((Mask & PROTO) != 0) {
+ OldData->SpdSelector->NextLayerProtocol = NewData->SpdSelector->NextLayerProtocol;
+ }
+
+ if (OldData->SpdSelector != NULL) {
+ switch (OldData->SpdSelector->NextLayerProtocol) {
+ case EFI_IP4_PROTO_TCP:
+ case EFI_IP4_PROTO_UDP:
+ if ((Mask & LOCAL_PORT) != 0) {
+ OldData->SpdSelector->LocalPort = NewData->SpdSelector->LocalPort;
+ }
+
+ if ((Mask & REMOTE_PORT) != 0) {
+ OldData->SpdSelector->RemotePort = NewData->SpdSelector->RemotePort;
+ }
+ break;
+
+ case EFI_IP4_PROTO_ICMP:
+ if ((Mask & ICMP_TYPE) != 0) {
+ OldData->SpdSelector->LocalPort = (UINT8) NewData->SpdSelector->LocalPort;
+ }
+
+ if ((Mask & ICMP_CODE) != 0) {
+ OldData->SpdSelector->RemotePort = (UINT8) NewData->SpdSelector->RemotePort;
+ }
+ break;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Combine old PAD entry with new PAD entry.
+
+ @param[in, out] OldPadId The pointer to the EFI_IPSEC_PAD_ID structure.
+ @param[in, out] OldData The pointer to the EFI_IPSEC_PAD_DATA structure.
+ @param[in] NewPadId The pointer to the EFI_IPSEC_PAD_ID structure.
+ @param[in] NewData The pointer to the EFI_IPSEC_PAD_DATA structure.
+ @param[in] Mask The pointer to the Mask.
+ @param[out] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Combined successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+EFI_STATUS
+CombinePadEntry (
+ IN OUT EFI_IPSEC_PAD_ID *OldPadId,
+ IN OUT EFI_IPSEC_PAD_DATA *OldData,
+ IN EFI_IPSEC_PAD_ID *NewPadId,
+ IN EFI_IPSEC_PAD_DATA *NewData,
+ IN UINT32 Mask,
+ OUT BOOLEAN *CreateNew
+ )
+{
+
+ *CreateNew = FALSE;
+
+ if ((Mask & (PEER_ID | PEER_ADDRESS)) == 0) {
+ CopyMem (NewPadId, OldPadId, sizeof (EFI_IPSEC_PAD_ID));
+ } else {
+ if ((Mask & PEER_ID) != 0) {
+ if (OldPadId->PeerIdValid) {
+ if (StrCmp ((CONST CHAR16 *) OldPadId->Id.PeerId, (CONST CHAR16 *) NewPadId->Id.PeerId) != 0) {
+ *CreateNew = TRUE;
+ }
+ } else {
+ *CreateNew = TRUE;
+ }
+ } else {
+ //
+ // MASK & PEER_ADDRESS
+ //
+ if (OldPadId->PeerIdValid) {
+ *CreateNew = TRUE;
+ } else {
+ if ((CompareMem (&OldPadId->Id.IpAddress.Address, &NewPadId->Id.IpAddress.Address, sizeof (EFI_IP_ADDRESS)) != 0) ||
+ (OldPadId->Id.IpAddress.PrefixLength != NewPadId->Id.IpAddress.PrefixLength)) {
+ *CreateNew = TRUE;
+ }
+ }
+ }
+ }
+
+ if ((Mask & AUTH_PROTO) != 0) {
+ OldData->AuthProtocol = NewData->AuthProtocol;
+ }
+
+ if ((Mask & AUTH_METHOD) != 0) {
+ OldData->AuthMethod = NewData->AuthMethod;
+ }
+
+ if ((Mask & IKE_ID) != 0) {
+ OldData->IkeIdFlag = NewData->IkeIdFlag;
+ }
+
+ if ((Mask & AUTH_DATA) != 0) {
+ OldData->AuthDataSize = NewData->AuthDataSize;
+ OldData->AuthData = NewData->AuthData;
+ }
+
+ if ((Mask & REVOCATION_DATA) != 0) {
+ OldData->RevocationDataSize = NewData->RevocationDataSize;
+ OldData->RevocationData = NewData->RevocationData;
+ }
+
+ return EFI_SUCCESS;
+}
+
+COMBINE_POLICY_ENTRY mCombinePolicyEntry[] = {
+ (COMBINE_POLICY_ENTRY) CombineSpdEntry,
+ (COMBINE_POLICY_ENTRY) CombineSadEntry,
+ (COMBINE_POLICY_ENTRY) CombinePadEntry
+};
+
+/**
+ Edit entry information in the database.
+
+ @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.
+ @param[in] Data The pointer to the data.
+ @param[in] Context The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.
+
+ @retval EFI_SUCCESS Continue the iteration.
+ @retval EFI_ABORTED Abort the iteration.
+**/
+EFI_STATUS
+EditOperatePolicyEntry (
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
+ IN VOID *Data,
+ IN EDIT_POLICY_ENTRY_CONTEXT *Context
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN CreateNew;
+
+ if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {
+ ASSERT (Context->DataType < 3);
+
+ Status = mCombinePolicyEntry[Context->DataType] (
+ Selector,
+ Data,
+ Context->Selector,
+ Context->Data,
+ Context->Mask,
+ &CreateNew
+ );
+ if (!EFI_ERROR (Status)) {
+ if (CreateNew) {
+ //
+ // Insert new entry before old entry
+ //
+ Status = mIpSecConfig->SetData (
+ mIpSecConfig,
+ Context->DataType,
+ Context->Selector,
+ Data,
+ Selector
+ );
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Delete old entry
+ //
+ Status = mIpSecConfig->SetData (
+ mIpSecConfig,
+ Context->DataType,
+ Selector,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ Status = mIpSecConfig->SetData (
+ mIpSecConfig,
+ Context->DataType,
+ Context->Selector,
+ Data,
+ NULL
+ );
+ }
+ }
+
+ Context->Status = Status;
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Edit entry information in database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Edit entry information successfully.
+ @retval EFI_NOT_FOUND Can't find the specified entry.
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+EditPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ )
+{
+ EFI_STATUS Status;
+ EDIT_POLICY_ENTRY_CONTEXT Context;
+ CONST CHAR16 *ValueStr;
+
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");
+ if (ValueStr == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);
+ return EFI_NOT_FOUND;
+ }
+
+ Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);
+ if (!EFI_ERROR (Status)) {
+ Context.DataType = DataType;
+ Context.Status = EFI_NOT_FOUND;
+ Status = mCreatePolicyEntry[DataType] (&Context.Selector, &Context.Data, ParamPackage, &Context.Mask, FALSE);
+ if (!EFI_ERROR (Status)) {
+ ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) EditOperatePolicyEntry, &Context);
+ Status = Context.Status;
+ }
+
+ if (Context.Selector != NULL) {
+ gBS->FreePool (Context.Selector);
+ }
+
+ if (Context.Data != NULL) {
+ gBS->FreePool (Context.Data);
+ }
+ }
+
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);
+ } else if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_EDIT_FAILED), mHiiHandle, mAppName);
+ }
+
+ return Status;
+
+}
+
+/**
+ Insert entry information in database.
+
+ @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.
+ @param[in] Data The pointer to the data.
+ @param[in] Context The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.
+
+ @retval EFI_SUCCESS Continue the iteration.
+ @retval EFI_ABORTED Abort the iteration.
+**/
+EFI_STATUS
+InsertPolicyEntry (
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
+ IN VOID *Data,
+ IN INSERT_POLICY_ENTRY_CONTEXT *Context
+ )
+{
+ //
+ // Found the entry which we want to insert before.
+ //
+ if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {
+
+ Context->Status = mIpSecConfig->SetData (
+ mIpSecConfig,
+ Context->DataType,
+ Context->Selector,
+ Context->Data,
+ Selector
+ );
+ //
+ // Abort the iteration after the insertion.
+ //
+ return EFI_ABORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Insert or add entry information in database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Insert or add entry information successfully.
+ @retval EFI_NOT_FOUND Can't find the specified entry.
+ @retval EFI_BUFFER_TOO_SMALL The entry already existed.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+AddOrInsertPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ )
+{
+ EFI_STATUS Status;
+ EFI_IPSEC_CONFIG_SELECTOR *Selector;
+ VOID *Data;
+ INSERT_POLICY_ENTRY_CONTEXT Context;
+ UINT32 Mask;
+ UINTN DataSize;
+ CONST CHAR16 *ValueStr;
+
+ Status = mCreatePolicyEntry[DataType] (&Selector, &Data, ParamPackage, &Mask, TRUE);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Find if the Selector to be inserted already exists.
+ //
+ DataSize = 0;
+ Status = mIpSecConfig->GetData (
+ mIpSecConfig,
+ DataType,
+ Selector,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_EXISTS), mHiiHandle, mAppName);
+ } else if (ShellCommandLineGetFlag (ParamPackage, L"-a")) {
+ Status = mIpSecConfig->SetData (
+ mIpSecConfig,
+ DataType,
+ Selector,
+ Data,
+ NULL
+ );
+ } else {
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");
+ if (ValueStr == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);
+ return EFI_NOT_FOUND;
+ }
+
+ Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);
+ if (!EFI_ERROR (Status)) {
+ Context.DataType = DataType;
+ Context.Status = EFI_NOT_FOUND;
+ Context.Selector = Selector;
+ Context.Data = Data;
+
+ ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) InsertPolicyEntry, &Context);
+ Status = Context.Status;
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);
+ }
+ }
+ }
+
+ gBS->FreePool (Selector);
+ gBS->FreePool (Data);
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_UNSUPPORT), mHiiHandle, mAppName);
+ } else if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_FAILED), mHiiHandle, mAppName);
+ }
+
+ return Status;
+}
diff --git a/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h b/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h new file mode 100644 index 0000000000..5161bacccb --- /dev/null +++ b/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h @@ -0,0 +1,158 @@ +/** @file
+ The function declaration of policy entry operation in IpSecConfig application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _POLICY_ENTRY_OPERATION_H_
+#define _POLICY_ENTRY_OPERATION_H_
+
+#define LOCAL BIT(0)
+#define REMOTE BIT(1)
+#define PROTO BIT(2)
+#define LOCAL_PORT BIT(3)
+#define REMOTE_PORT BIT(4)
+#define ICMP_TYPE BIT(5)
+#define ICMP_CODE BIT(6)
+#define NAME BIT(7)
+#define PACKET_FLAG BIT(8)
+#define ACTION BIT(9)
+#define EXT_SEQUENCE BIT(10)
+#define SEQUENCE_OVERFLOW BIT(11)
+#define FRAGMENT_CHECK BIT(12)
+#define LIFEBYTE BIT(13)
+#define LIFETIME_SOFT BIT(14)
+#define LIFETIME BIT(15)
+#define MODE BIT(16)
+#define TUNNEL_LOCAL BIT(17)
+#define TUNNEL_REMOTE BIT(18)
+#define DONT_FRAGMENT BIT(19)
+#define IPSEC_PROTO BIT(20)
+#define AUTH_ALGO BIT(21)
+#define ENCRYPT_ALGO BIT(22)
+#define SPI BIT(23)
+#define DEST BIT(24)
+#define SEQUENCE_NUMBER BIT(25)
+#define ANTIREPLAY_WINDOW BIT(26)
+#define AUTH_KEY BIT(27)
+#define ENCRYPT_KEY BIT(28)
+#define PATH_MTU BIT(29)
+
+#define PEER_ID BIT(0)
+#define PEER_ADDRESS BIT(1)
+#define AUTH_PROTO BIT(2)
+#define AUTH_METHOD BIT(3)
+#define IKE_ID BIT(4)
+#define AUTH_DATA BIT(5)
+#define REVOCATION_DATA BIT(6)
+
+typedef struct {
+ EFI_IPSEC_CONFIG_DATA_TYPE DataType;
+ EFI_IPSEC_CONFIG_SELECTOR *Selector; // Data to be inserted.
+ VOID *Data;
+ UINT32 Mask;
+ POLICY_ENTRY_INDEXER Indexer;
+ EFI_STATUS Status; // Indicate whether insertion succeeds.
+} EDIT_POLICY_ENTRY_CONTEXT;
+
+typedef struct {
+ EFI_IPSEC_CONFIG_DATA_TYPE DataType;
+ EFI_IPSEC_CONFIG_SELECTOR *Selector; // Data to be inserted.
+ VOID *Data;
+ POLICY_ENTRY_INDEXER Indexer;
+ EFI_STATUS Status; // Indicate whether insertion succeeds.
+} INSERT_POLICY_ENTRY_CONTEXT;
+
+/**
+ The prototype for the CreateSpdEntry()/CreateSadEntry()/CreatePadEntry().
+ Fill in EFI_IPSEC_CONFIG_SELECTOR and corresponding data thru ParamPackage list.
+
+ @param[out] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR union.
+ @param[out] Data The pointer to corresponding data.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+ @param[out] Mask The pointer to the Mask.
+ @param[in] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Filled in EFI_IPSEC_CONFIG_SELECTOR and corresponding data successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+typedef
+EFI_STATUS
+(*CREATE_POLICY_ENTRY) (
+ OUT EFI_IPSEC_CONFIG_SELECTOR **Selector,
+ OUT VOID **Data,
+ IN LIST_ENTRY *ParamPackage,
+ OUT UINT32 *Mask,
+ IN BOOLEAN CreateNew
+ );
+
+/**
+ The prototype for the CombineSpdEntry()/CombineSadEntry()/CombinePadEntry().
+ Combine old SPD/SAD/PAD entry with new SPD/SAD/PAD entry.
+
+ @param[in, out] OldSelector The pointer to the old EFI_IPSEC_CONFIG_SELECTOR union.
+ @param[in, out] OldData The pointer to the corresponding old data.
+ @param[in] NewSelector The pointer to the new EFI_IPSEC_CONFIG_SELECTOR union.
+ @param[in] NewData The pointer to the corresponding new data.
+ @param[in] Mask The pointer to the Mask.
+ @param[out] CreateNew The switch to create new.
+
+ @retval EFI_SUCCESS Combined successfully.
+ @retval EFI_INVALID_PARAMETER Invalid user input parameter.
+
+**/
+typedef
+EFI_STATUS
+(* COMBINE_POLICY_ENTRY) (
+ EFI_IPSEC_CONFIG_SELECTOR *OldSelector,
+ VOID *OldData,
+ EFI_IPSEC_CONFIG_SELECTOR *NewSelector,
+ VOID *NewData,
+ UINT32 Mask,
+ BOOLEAN *CreateNew
+ );
+
+/**
+ Insert or add entry information in database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Insert or add entry information successfully.
+ @retval EFI_NOT_FOUND Can't find the specified entry.
+ @retval EFI_BUFFER_TOO_SMALL The entry already existed.
+ @retval EFI_UNSUPPORTED The operation is not supported./
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+AddOrInsertPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ );
+
+/**
+ Edit entry information in the database according to datatype.
+
+ @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
+ @param[in] ParamPackage The pointer to the ParamPackage list.
+
+ @retval EFI_SUCCESS Edit entry information successfully.
+ @retval EFI_NOT_FOUND Can't find the specified entry.
+ @retval Others Some mistaken case.
+**/
+EFI_STATUS
+EditPolicyEntry (
+ IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
+ IN LIST_ENTRY *ParamPackage
+ );
+#endif
diff --git a/NetworkPkg/Application/Ping6/Ia32/Tsc.c b/NetworkPkg/Application/Ping6/Ia32/Tsc.c new file mode 100644 index 0000000000..e2eae99077 --- /dev/null +++ b/NetworkPkg/Application/Ping6/Ia32/Tsc.c @@ -0,0 +1,28 @@ +/** @file
+ The implement to read TSC in IA32 platform.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+/**
+ Reads and returns the current value of the Time Stamp Counter (TSC).
+
+ @return The current value of TSC.
+
+**/
+UINT64
+ReadTime ()
+{
+ return AsmReadTsc ();
+}
diff --git a/NetworkPkg/Application/Ping6/Ipf/Itc.c b/NetworkPkg/Application/Ping6/Ipf/Itc.c new file mode 100644 index 0000000000..131e5c0e30 --- /dev/null +++ b/NetworkPkg/Application/Ping6/Ipf/Itc.c @@ -0,0 +1,28 @@ +/** @file
+ The implement to read ITC in IA64 platform.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+/**
+ Reads and returns the current value of the Interval Timer Counter Register (ITC).
+
+ @return The current value of ITC.
+
+**/
+UINT64
+ReadTime ()
+{
+ return AsmReadItc ();
+}
diff --git a/NetworkPkg/Application/Ping6/Ping6.c b/NetworkPkg/Application/Ping6/Ping6.c new file mode 100644 index 0000000000..b783c5a027 --- /dev/null +++ b/NetworkPkg/Application/Ping6/Ping6.c @@ -0,0 +1,1179 @@ +/** @file
+ The implementation for Ping6 application.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/ShellLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HiiLib.h>
+#include <Library/NetLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/ServiceBinding.h>
+#include <Protocol/Ip6.h>
+#include <Protocol/Ip6Config.h>
+
+#include "Ping6.h"
+
+SHELL_PARAM_ITEM Ping6ParamList[] = {
+ {
+ L"-l",
+ TypeValue
+ },
+ {
+ L"-n",
+ TypeValue
+ },
+ {
+ L"-s",
+ TypeValue
+ },
+ {
+ L"-?",
+ TypeFlag
+ },
+ {
+ NULL,
+ TypeMax
+ },
+};
+
+//
+// Global Variables in Ping6 application.
+//
+EFI_HII_HANDLE mHiiHandle;
+CONST CHAR16 *mIp6DstString;
+CONST CHAR16 *mIp6SrcString;
+EFI_GUID mEfiPing6Guid = EFI_PING6_GUID;
+UINT32 mFrequency = 0;
+/**
+ Get and caculate the frequency in tick/ms.
+ The result is saved in the globle variable mFrequency
+
+ @retval EFI_SUCCESS Caculated the frequency successfully.
+ @retval Others Failed to caculate the frequency.
+
+**/
+EFI_STATUS
+Ping6GetFrequency (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+ UINT64 CurrentTick;
+ UINT32 TimerPeriod;
+
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &Cpu);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTick, (UINT64 *) &TimerPeriod);
+
+ if (EFI_ERROR (Status)) {
+ //
+ // For NT32 Simulator only. 358049 is a similar value to keep timer granularity.
+ // Set the timer period by ourselves.
+ //
+ TimerPeriod = NTTIMERPERIOD;
+ }
+ //
+ // The timer period is in femtosecond (1 femtosecond is 1e-15 second).
+ // So 1e+12 is divided by timer period to produce the freq in tick/ms.
+ //
+ mFrequency = (UINT32) DivU64x32 (1000000000000ULL, TimerPeriod);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get and caculate the duration in ms.
+
+ @param[in] Begin The start point of time.
+ @param[in] End The end point of time.
+
+ @return The duration in ms.
+
+**/
+UINT32
+Ping6CalculateTick (
+ IN UINT64 Begin,
+ IN UINT64 End
+ )
+{
+ ASSERT (End > Begin);
+ return (UINT32) DivU64x32 (End - Begin, mFrequency);
+}
+
+/**
+ Destroy IPING6_ICMP6_TX_INFO, and recollect the memory.
+
+ @param[in] TxInfo The pointer to PING6_ICMP6_TX_INFO.
+
+**/
+VOID
+Ping6DestroyTxInfo (
+ IN PING6_ICMP6_TX_INFO *TxInfo
+ )
+{
+ EFI_IP6_TRANSMIT_DATA *TxData;
+ EFI_IP6_FRAGMENT_DATA *FragData;
+ UINTN Index;
+
+ ASSERT (TxInfo != NULL);
+
+ if (TxInfo->Token != NULL) {
+
+ if (TxInfo->Token->Event != NULL) {
+ gBS->CloseEvent (TxInfo->Token->Event);
+ }
+
+ TxData = TxInfo->Token->Packet.TxData;
+ if (TxData != NULL) {
+
+ if (TxData->OverrideData != NULL) {
+ FreePool (TxData->OverrideData);
+ }
+
+ if (TxData->ExtHdrs != NULL) {
+ FreePool (TxData->ExtHdrs);
+ }
+
+ for (Index = 0; Index < TxData->FragmentCount; Index++) {
+ FragData = TxData->FragmentTable[Index].FragmentBuffer;
+ if (FragData != NULL) {
+ FreePool (FragData);
+ }
+ }
+ }
+
+ FreePool (TxInfo->Token);
+ }
+
+ FreePool (TxInfo);
+}
+
+/**
+ Match the request, and reply with SequenceNum/TimeStamp.
+
+ @param[in] Private The pointer to PING6_PRIVATE_DATA.
+ @param[in] Packet The pointer to ICMP6_ECHO_REQUEST_REPLY.
+
+ @retval EFI_SUCCESS The match is successful.
+ @retval EFI_NOT_FOUND The reply can't be matched with any request.
+
+**/
+EFI_STATUS
+Ping6MatchEchoReply (
+ IN PING6_PRIVATE_DATA *Private,
+ IN ICMP6_ECHO_REQUEST_REPLY *Packet
+ )
+{
+ PING6_ICMP6_TX_INFO *TxInfo;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *NextEntry;
+
+ NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
+ TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);
+
+ if ((TxInfo->SequenceNum == Packet->SequenceNum) && (TxInfo->TimeStamp == Packet->TimeStamp)) {
+ Private->RxCount++;
+ RemoveEntryList (&TxInfo->Link);
+ Ping6DestroyTxInfo (TxInfo);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ The original intention is to send a request.
+ Currently, the application retransmits an icmp6 echo request packet
+ per second in sendnumber times that is specified by the user.
+ Because nothing can be done here, all things move to the timer rountine.
+
+ @param[in] Event A EFI_EVENT type event.
+ @param[in] Context The pointer to Context.
+
+**/
+VOID
+EFIAPI
+Ping6OnEchoRequestSent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+}
+
+/**
+ receive reply, match and print reply infomation.
+
+ @param[in] Event A EFI_EVENT type event.
+ @param[in] Context The pointer to context.
+
+**/
+VOID
+EFIAPI
+Ping6OnEchoReplyReceived (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ PING6_PRIVATE_DATA *Private;
+ EFI_IP6_COMPLETION_TOKEN *RxToken;
+ EFI_IP6_RECEIVE_DATA *RxData;
+ ICMP6_ECHO_REQUEST_REPLY *Reply;
+ UINT32 PayLoad;
+ UINT32 Rtt;
+ CHAR8 Near;
+
+ Private = (PING6_PRIVATE_DATA *) Context;
+
+ if (Private->Status == EFI_ABORTED) {
+ return;
+ }
+
+ RxToken = &Private->RxToken;
+ RxData = RxToken->Packet.RxData;
+ Reply = RxData->FragmentTable[0].FragmentBuffer;
+ PayLoad = RxData->DataLength;
+
+ if (RxData->Header->NextHeader != IP6_ICMP) {
+ goto ON_EXIT;
+ }
+
+ if (!IP6_IS_MULTICAST (&Private->DstAddress) &&
+ !EFI_IP6_EQUAL (&RxData->Header->SourceAddress, &Private->DstAddress)) {
+ goto ON_EXIT;
+ }
+
+ if ((Reply->Type != ICMP_V6_ECHO_REPLY) || (Reply->Code != 0)) {
+ goto ON_EXIT;
+ }
+
+ if (PayLoad != Private->BufferSize) {
+ goto ON_EXIT;
+ }
+ //
+ // Check whether the reply matches the sent request before.
+ //
+ Status = Ping6MatchEchoReply (Private, Reply);
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Display statistics on this icmp6 echo reply packet.
+ //
+ Rtt = Ping6CalculateTick (Reply->TimeStamp, ReadTime ());
+ if (Rtt != 0) {
+ Near = (CHAR8) '=';
+ } else {
+ Near = (CHAR8) '<';
+ }
+
+ Private->RttSum += Rtt;
+ Private->RttMin = Private->RttMin > Rtt ? Rtt : Private->RttMin;
+ Private->RttMax = Private->RttMax < Rtt ? Rtt : Private->RttMax;
+
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_PING6_REPLY_INFO),
+ mHiiHandle,
+ PayLoad,
+ mIp6DstString,
+ Reply->SequenceNum,
+ RxData->Header->HopLimit,
+ Near,
+ Rtt
+ );
+
+ON_EXIT:
+
+ if (Private->RxCount < Private->SendNum) {
+ //
+ // Continue to receive icmp6 echo reply packets.
+ //
+ RxToken->Status = EFI_ABORTED;
+
+ Status = Private->Ip6->Receive (Private->Ip6, RxToken);
+
+ if (EFI_ERROR (Status)) {
+ Private->Status = EFI_ABORTED;
+ }
+ } else {
+ //
+ // All reply have already been received from the dest host.
+ //
+ Private->Status = EFI_SUCCESS;
+ }
+ //
+ // Singal to recycle the each rxdata here, not at the end of process.
+ //
+ gBS->SignalEvent (RxData->RecycleSignal);
+}
+
+/**
+ Initial EFI_IP6_COMPLETION_TOKEN.
+
+ @param[in] Private The pointer of PING6_PRIVATE_DATA.
+ @param[in] TimeStamp The TimeStamp of request.
+ @param[in] SequenceNum The SequenceNum of request.
+
+ @return The pointer of EFI_IP6_COMPLETION_TOKEN.
+
+**/
+EFI_IP6_COMPLETION_TOKEN *
+Ping6GenerateToken (
+ IN PING6_PRIVATE_DATA *Private,
+ IN UINT64 TimeStamp,
+ IN UINT16 SequenceNum
+ )
+{
+ EFI_STATUS Status;
+ EFI_IP6_COMPLETION_TOKEN *Token;
+ EFI_IP6_TRANSMIT_DATA *TxData;
+ ICMP6_ECHO_REQUEST_REPLY *Request;
+
+ Request = AllocateZeroPool (Private->BufferSize);
+
+ if (Request == NULL) {
+ return NULL;
+ }
+ //
+ // Assembly icmp6 echo request packet.
+ //
+ Request->Type = ICMP_V6_ECHO_REQUEST;
+ Request->Code = 0;
+ Request->SequenceNum = SequenceNum;
+ Request->TimeStamp = TimeStamp;
+ Request->Identifier = 0;
+ //
+ // Leave check sum to ip6 layer, since it has no idea of source address
+ // selection.
+ //
+ Request->Checksum = 0;
+
+ TxData = AllocateZeroPool (sizeof (EFI_IP6_TRANSMIT_DATA));
+
+ if (TxData == NULL) {
+ FreePool (Request);
+ return NULL;
+ }
+ //
+ // Assembly ipv6 token for transmit.
+ //
+ TxData->OverrideData = 0;
+ TxData->ExtHdrsLength = 0;
+ TxData->ExtHdrs = NULL;
+ TxData->DataLength = Private->BufferSize;
+ TxData->FragmentCount = 1;
+ TxData->FragmentTable[0].FragmentBuffer = (VOID *) Request;
+ TxData->FragmentTable[0].FragmentLength = Private->BufferSize;
+
+ Token = AllocateZeroPool (sizeof (EFI_IP6_COMPLETION_TOKEN));
+
+ if (Token == NULL) {
+ FreePool (Request);
+ FreePool (TxData);
+ return NULL;
+ }
+
+ Token->Status = EFI_ABORTED;
+ Token->Packet.TxData = TxData;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ Ping6OnEchoRequestSent,
+ Private,
+ &Token->Event
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (Request);
+ FreePool (TxData);
+ FreePool (Token);
+ return NULL;
+ }
+
+ return Token;
+}
+
+/**
+ Transmit the EFI_IP6_COMPLETION_TOKEN.
+
+ @param[in] Private The pointer of PING6_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS Transmitted successfully.
+ @retval EFI_OUT_OF_RESOURCES No memory is available on the platform.
+ @retval others Transmitted unsuccessfully.
+
+**/
+EFI_STATUS
+Ping6SendEchoRequest (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ PING6_ICMP6_TX_INFO *TxInfo;
+
+ TxInfo = AllocateZeroPool (sizeof (PING6_ICMP6_TX_INFO));
+
+ if (TxInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TxInfo->TimeStamp = ReadTime ();
+ TxInfo->SequenceNum = (UINT16) (Private->TxCount + 1);
+
+ TxInfo->Token = Ping6GenerateToken (
+ Private,
+ TxInfo->TimeStamp,
+ TxInfo->SequenceNum
+ );
+
+ if (TxInfo->Token == NULL) {
+ Ping6DestroyTxInfo (TxInfo);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = Private->Ip6->Transmit (Private->Ip6, TxInfo->Token);
+
+ if (EFI_ERROR (Status)) {
+ Ping6DestroyTxInfo (TxInfo);
+ return Status;
+ }
+
+ InsertTailList (&Private->TxList, &TxInfo->Link);
+ Private->TxCount++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Place a completion token into the receive packet queue to receive the echo reply.
+
+ @param[in] Private The pointer of PING6_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS Put the token into the receive packet queue successfully.
+ @retval others Put the token into the receive packet queue unsuccessfully.
+
+**/
+EFI_STATUS
+Ping6ReceiveEchoReply (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ ZeroMem (&Private->RxToken, sizeof (EFI_IP6_COMPLETION_TOKEN));
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ Ping6OnEchoReplyReceived,
+ Private,
+ &Private->RxToken.Event
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Private->RxToken.Status = EFI_NOT_READY;
+
+ return Private->Ip6->Receive (Private->Ip6, &Private->RxToken);
+}
+
+/**
+ Remove the timeout request from the list.
+
+ @param[in] Event A EFI_EVENT type event.
+ @param[in] Context The pointer to Context.
+
+**/
+VOID
+EFIAPI
+Ping6OnTimerRoutine (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ PING6_PRIVATE_DATA *Private;
+ PING6_ICMP6_TX_INFO *TxInfo;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *NextEntry;
+ UINT32 Time;
+
+ Private = (PING6_PRIVATE_DATA *) Context;
+
+ //
+ // Retransmit icmp6 echo request packets per second in sendnumber times.
+ //
+ if (Private->TxCount < Private->SendNum) {
+
+ Status = Ping6SendEchoRequest (Private);
+ if (Private->TxCount != 0){
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_SEND_REQUEST), mHiiHandle, Private->TxCount + 1);
+ }
+ }
+ }
+ //
+ // Check whether any icmp6 echo request in the list timeout.
+ //
+ NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
+ TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);
+ Time = Ping6CalculateTick (TxInfo->TimeStamp, ReadTime ());
+
+ //
+ // Remove the timeout echo request from txlist.
+ //
+ if (Time > PING6_DEFAULT_TIMEOUT) {
+
+ if (EFI_ERROR (TxInfo->Token->Status)) {
+ Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);
+ }
+ //
+ // Remove the timeout icmp6 echo request from list.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_TIMEOUT), mHiiHandle, TxInfo->SequenceNum);
+
+ RemoveEntryList (&TxInfo->Link);
+ Ping6DestroyTxInfo (TxInfo);
+
+ if (IsListEmpty (&Private->TxList) && (Private->TxCount == Private->SendNum)) {
+ //
+ // All the left icmp6 echo request in the list timeout.
+ //
+ Private->Status = EFI_TIMEOUT;
+ }
+ }
+ }
+}
+
+/**
+ Create a valid IP6 instance.
+
+ @param[in] Private The pointer of PING6_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS Create a valid IP6 instance successfully.
+ @retval EFI_ABORTED Locate handle with ip6 service binding protocol unsuccessfully.
+ @retval EFI_INVALID_PARAMETER The source address is unspecified when the destination address is a link -ocal address.
+ @retval EFI_OUT_OF_RESOURCES No memory is available on the platform.
+ @retval EFI_NOT_FOUND The source address is not found.
+**/
+EFI_STATUS
+Ping6CreateIp6Instance (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleIndex;
+ UINTN HandleNum;
+ EFI_HANDLE *HandleBuffer;
+ EFI_SERVICE_BINDING_PROTOCOL *Ip6Sb;
+ EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
+ EFI_IP6_CONFIG_DATA Ip6Config;
+ EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
+ UINTN IfInfoSize;
+ EFI_IPv6_ADDRESS *Addr;
+ UINTN AddrIndex;
+
+ HandleBuffer = NULL;
+ Ip6Sb = NULL;
+ IfInfo = NULL;
+ IfInfoSize = 0;
+
+ //
+ // Locate all the handles with ip6 service binding protocol.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiIp6ServiceBindingProtocolGuid,
+ NULL,
+ &HandleNum,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status) || (HandleNum == 0)) {
+ return EFI_ABORTED;
+ }
+ //
+ // Source address is required when pinging a link-local address on multi-
+ // interfaces host.
+ //
+ if (NetIp6IsLinkLocalAddr (&Private->DstAddress) &&
+ NetIp6IsUnspecifiedAddr (&Private->SrcAddress) &&
+ (HandleNum > 1)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SOURCE), mHiiHandle);
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_ERROR;
+ }
+ //
+ // For each ip6 protocol, check interface addresses list.
+ //
+ for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {
+
+ Ip6Sb = NULL;
+ IfInfo = NULL;
+ IfInfoSize = 0;
+
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gEfiIp6ServiceBindingProtocolGuid,
+ (VOID **) &Ip6Sb
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ if (NetIp6IsUnspecifiedAddr (&Private->SrcAddress)) {
+ //
+ // No need to match interface address.
+ //
+ break;
+ } else {
+ //
+ // Ip6config protocol and ip6 service binding protocol are installed
+ // on the same handle.
+ //
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gEfiIp6ConfigProtocolGuid,
+ (VOID **) &Ip6Cfg
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+ //
+ // Get the interface information size.
+ //
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &IfInfoSize,
+ NULL
+ );
+
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+
+ IfInfo = AllocateZeroPool (IfInfoSize);
+
+ if (IfInfo == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+ //
+ // Get the interface info.
+ //
+ Status = Ip6Cfg->GetData (
+ Ip6Cfg,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &IfInfoSize,
+ IfInfo
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6CFG_GETDATA), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+ //
+ // Check whether the source address is one of the interface addresses.
+ //
+ for (AddrIndex = 0; AddrIndex < IfInfo->AddressInfoCount; AddrIndex++) {
+
+ Addr = &(IfInfo->AddressInfo[AddrIndex].Address);
+ if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) {
+ //
+ // Match a certain interface address.
+ //
+ break;
+ }
+ }
+
+ if (AddrIndex < IfInfo->AddressInfoCount) {
+ //
+ // Found a nic handle with right interface address.
+ //
+ break;
+ }
+ }
+
+ FreePool (IfInfo);
+ IfInfo = NULL;
+ }
+ //
+ // No exact interface address matched.
+ //
+
+ if (HandleIndex == HandleNum) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_SOURCE_NOT_FOUND), mHiiHandle, mIp6SrcString);
+ Status = EFI_NOT_FOUND;
+ goto ON_ERROR;
+ }
+
+ Private->NicHandle = HandleBuffer[HandleIndex];
+
+ ASSERT (Ip6Sb != NULL);
+ Status = Ip6Sb->CreateChild (Ip6Sb, &Private->Ip6ChildHandle);
+
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ Status = gBS->OpenProtocol (
+ Private->Ip6ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ (VOID **) &Private->Ip6,
+ Private->ImageHandle,
+ Private->Ip6ChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ ZeroMem (&Ip6Config, sizeof (EFI_IP6_CONFIG_DATA));
+
+ //
+ // Configure the ip6 instance for icmp6 packet exchange.
+ //
+ Ip6Config.DefaultProtocol = 58;
+ Ip6Config.AcceptAnyProtocol = FALSE;
+ Ip6Config.AcceptIcmpErrors = TRUE;
+ Ip6Config.AcceptPromiscuous = FALSE;
+ Ip6Config.TrafficClass = 0;
+ Ip6Config.HopLimit = 128;
+ Ip6Config.FlowLabel = 0;
+ Ip6Config.ReceiveTimeout = 0;
+ Ip6Config.TransmitTimeout = 0;
+
+ IP6_COPY_ADDRESS (&Ip6Config.StationAddress, &Private->SrcAddress);
+
+ IP6_COPY_ADDRESS (&Ip6Config.DestinationAddress, &Private->DstAddress);
+
+ Status = Private->Ip6->Configure (Private->Ip6, &Ip6Config);
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_CONFIG), mHiiHandle, Status);
+ goto ON_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ if (IfInfo != NULL) {
+ FreePool (IfInfo);
+ }
+
+ if ((Ip6Sb != NULL) && (Private->Ip6ChildHandle != NULL)) {
+ Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);
+ }
+
+ return Status;
+}
+
+/**
+ Destory the IP6 instance.
+
+ @param[in] Private The pointer of PING6_PRIVATE_DATA.
+
+**/
+VOID
+Ping6DestoryIp6Instance (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_SERVICE_BINDING_PROTOCOL *Ip6Sb;
+
+ gBS->CloseProtocol (
+ Private->Ip6ChildHandle,
+ &gEfiIp6ProtocolGuid,
+ Private->ImageHandle,
+ Private->Ip6ChildHandle
+ );
+
+ Status = gBS->HandleProtocol (
+ Private->NicHandle,
+ &gEfiIp6ServiceBindingProtocolGuid,
+ (VOID **) &Ip6Sb
+ );
+
+ if (!EFI_ERROR(Status)) {
+ Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);
+ }
+}
+
+/**
+ The Ping6 Process.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[in] SendNumber The send request count.
+ @param[in] BufferSize The send buffer size.
+ @param[in] SrcAddress The source IPv6 address.
+ @param[in] DstAddress The destination IPv6 address.
+
+ @retval EFI_SUCCESS The ping6 processed successfullly.
+ @retval others The ping6 processed unsuccessfully.
+
+**/
+EFI_STATUS
+Ping6 (
+ IN EFI_HANDLE ImageHandle,
+ IN UINT32 SendNumber,
+ IN UINT32 BufferSize,
+ IN EFI_IPv6_ADDRESS *SrcAddress,
+ IN EFI_IPv6_ADDRESS *DstAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+ PING6_PRIVATE_DATA *Private;
+ PING6_ICMP6_TX_INFO *TxInfo;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *NextEntry;
+
+ Private = AllocateZeroPool (sizeof (PING6_PRIVATE_DATA));
+
+ ASSERT (Private != NULL);
+
+ Private->ImageHandle = ImageHandle;
+ Private->SendNum = SendNumber;
+ Private->BufferSize = BufferSize;
+ Private->RttMin = 0xFFFF;
+ Private->Status = EFI_NOT_READY;
+
+ InitializeListHead (&Private->TxList);
+
+ IP6_COPY_ADDRESS (&Private->SrcAddress, SrcAddress);
+ IP6_COPY_ADDRESS (&Private->DstAddress, DstAddress);
+
+ //
+ // Open and configure a ip6 instance for ping6.
+ //
+ Status = Ping6CreateIp6Instance (Private);
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Print the command line itself.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_START), mHiiHandle, mIp6DstString, Private->BufferSize);
+ //
+ // Create a ipv6 token to receive the first icmp6 echo reply packet.
+ //
+ Status = Ping6ReceiveEchoReply (Private);
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Create and start timer to send icmp6 echo request packet per second.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ Ping6OnTimerRoutine,
+ Private,
+ &Private->Timer
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Create a ipv6 token to send the first icmp6 echo request packet.
+ //
+ Status = Ping6SendEchoRequest (Private);
+ //
+ // EFI_NOT_READY for IPsec is enable and IKE is not established.
+ //
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
+ if(Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_NOSOURCE_INDOMAIN), mHiiHandle, mIp6DstString);
+ }
+
+ goto ON_EXIT;
+ }
+
+ Status = gBS->SetTimer (
+ Private->Timer,
+ TimerPeriodic,
+ PING6_ONE_SECOND
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Control the ping6 process by two factors:
+ // 1. Hot key
+ // 2. Private->Status
+ // 2.1. success means all icmp6 echo request packets get reply packets.
+ // 2.2. timeout means the last icmp6 echo reply request timeout to get reply.
+ // 2.3. noready means ping6 process is on-the-go.
+ //
+ while (Private->Status == EFI_NOT_READY) {
+ Private->Ip6->Poll (Private->Ip6);
+
+ //
+ // Terminate the ping6 process by 'esc' or 'ctl-c'.
+ //
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+
+ if (!EFI_ERROR(Status)) {
+ if ((Key.UnicodeChar == 0x1b) || (Key.UnicodeChar == 0x03) ||
+ ((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_ESC))) {
+ goto ON_STAT;
+ }
+ }
+ }
+
+ON_STAT:
+ //
+ // Display the statistics in all.
+ //
+ gBS->SetTimer (Private->Timer, TimerCancel, 0);
+
+ if (Private->TxCount != 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_PING6_STAT),
+ mHiiHandle,
+ Private->TxCount,
+ Private->RxCount,
+ (100 * (Private->TxCount - Private->RxCount)) / Private->TxCount,
+ Private->RttSum
+ );
+ }
+
+ if (Private->RxCount != 0) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_PING6_RTT),
+ mHiiHandle,
+ Private->RttMin,
+ Private->RttMax,
+ Private->RttSum / Private->RxCount
+ );
+ }
+
+ON_EXIT:
+
+ if (Private != NULL) {
+ Private->Status = EFI_ABORTED;
+
+ NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
+ TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link);
+
+ Status = Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);
+
+ RemoveEntryList (&TxInfo->Link);
+ Ping6DestroyTxInfo (TxInfo);
+ }
+
+ if (Private->Timer != NULL) {
+ gBS->CloseEvent (Private->Timer);
+ }
+
+ if (Private->Ip6 != NULL) {
+ Status = Private->Ip6->Cancel (Private->Ip6, &Private->RxToken);
+ }
+
+ if (Private->RxToken.Event != NULL) {
+ gBS->CloseEvent (Private->RxToken.Event);
+ }
+
+ if (Private->Ip6ChildHandle != NULL) {
+ Ping6DestoryIp6Instance (Private);
+ }
+
+ FreePool (Private);
+ }
+
+ return Status;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
+ both device drivers and bus drivers.
+
+ The entry point for the Ping6 application that parses the command line input and calls the Ping6 process.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETETR Input parameters combination is invalid.
+ @retval Others Some errors occur.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePing6 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_IPv6_ADDRESS DstAddress;
+ EFI_IPv6_ADDRESS SrcAddress;
+ UINT64 BufferSize;
+ UINTN SendNumber;
+ LIST_ENTRY *ParamPackage;
+ CONST CHAR16 *ValueStr;
+ CONST CHAR16 *ValueStrPtr;
+ UINTN NonOptionCount;
+
+ //
+ // Register our string package with HII and return the handle to it.
+ //
+ mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, Ping6Strings, NULL);
+ ASSERT (mHiiHandle != NULL);
+
+ Status = ShellCommandLineParseEx (Ping6ParamList, &ParamPackage, NULL, TRUE, FALSE);
+ if (EFI_ERROR(Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), mHiiHandle);
+ goto ON_EXIT;
+ }
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-?")) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_HELP), mHiiHandle);
+ goto ON_EXIT;
+ }
+
+ SendNumber = 10;
+ BufferSize = 16;
+
+ //
+ // Parse the paramter of count number.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-n");
+ ValueStrPtr = ValueStr;
+ if (ValueStr != NULL) {
+ SendNumber = ShellStrToUintn (ValueStrPtr);
+
+ //
+ // ShellStrToUintn will return 0 when input is 0 or an invalid input string.
+ //
+ if ((SendNumber == 0) || (SendNumber > PING6_MAX_SEND_NUMBER)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SEND_NUMBER), mHiiHandle, ValueStr);
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Parse the paramter of buffer size.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");
+ ValueStrPtr = ValueStr;
+ if (ValueStr != NULL) {
+ BufferSize = ShellStrToUintn (ValueStrPtr);
+
+ //
+ // ShellStrToUintn will return 0 when input is 0 or an invalid input string.
+ //
+ if ((BufferSize < 16) || (BufferSize > PING6_MAX_BUFFER_SIZE)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_BUFFER_SIZE), mHiiHandle, ValueStr);
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+
+ ZeroMem (&SrcAddress, sizeof (EFI_IPv6_ADDRESS));
+ ZeroMem (&DstAddress, sizeof (EFI_IPv6_ADDRESS));
+
+ //
+ // Parse the paramter of source ip address.
+ //
+ ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");
+ ValueStrPtr = ValueStr;
+ if (ValueStr != NULL) {
+ mIp6SrcString = ValueStr;
+ Status = NetLibStrToIp6 (ValueStrPtr, &SrcAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP), mHiiHandle, ValueStr);
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Parse the paramter of destination ip address.
+ //
+ NonOptionCount = ShellCommandLineGetCount();
+ ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32)(NonOptionCount-1));
+ if (NonOptionCount != 2) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), mHiiHandle);
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ ValueStrPtr = ValueStr;
+ if (ValueStr != NULL) {
+ mIp6DstString = ValueStr;
+ Status = NetLibStrToIp6 (ValueStrPtr, &DstAddress);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP), mHiiHandle, ValueStr);
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+ //
+ // Get frequency to calculate the time from ticks.
+ //
+ Status = Ping6GetFrequency ();
+
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+ //
+ // Enter into ping6 process.
+ //
+ Status = Ping6 (
+ ImageHandle,
+ (UINT32)SendNumber,
+ (UINT32)BufferSize,
+ &SrcAddress,
+ &DstAddress
+ );
+
+ON_EXIT:
+ ShellCommandLineFreeVarList (ParamPackage);
+ HiiRemovePackages (mHiiHandle);
+ return Status;
+}
diff --git a/NetworkPkg/Application/Ping6/Ping6.h b/NetworkPkg/Application/Ping6/Ping6.h new file mode 100644 index 0000000000..02271e1b58 --- /dev/null +++ b/NetworkPkg/Application/Ping6/Ping6.h @@ -0,0 +1,92 @@ +/** @file
+ The interface function declaration of shell application Ping6 (Ping for v6 series).
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PING6_H_
+#define _PING6_H_
+
+#define EFI_PING6_GUID \
+ { \
+ 0x3f0b2478, 0x3619, 0x46c5, {0x81, 0x50, 0xa5, 0xab, 0xdd, 0xb6, 0x6b, 0xd9} \
+ }
+
+#define PING6_DEFAULT_TIMEOUT 5000
+#define PING6_MAX_SEND_NUMBER 10000
+#define PING6_MAX_BUFFER_SIZE 32768
+#define PING6_ONE_SECOND 10000000
+
+//
+// A similar amount of time that passes in femtoseconds
+// for each increment of TimerValue. It is for NT32 only.
+//
+#define NTTIMERPERIOD 358049
+
+#pragma pack(1)
+
+typedef struct _ICMP6_ECHO_REQUEST_REPLY {
+ UINT8 Type;
+ UINT8 Code;
+ UINT16 Checksum;
+ UINT16 Identifier;
+ UINT16 SequenceNum;
+ UINT64 TimeStamp;
+ UINT8 Data[1];
+} ICMP6_ECHO_REQUEST_REPLY;
+
+#pragma pack()
+
+typedef struct _PING6_ICMP6_TX_INFO {
+ LIST_ENTRY Link;
+ UINT16 SequenceNum;
+ UINT64 TimeStamp;
+ EFI_IP6_COMPLETION_TOKEN *Token;
+} PING6_ICMP6_TX_INFO;
+
+typedef struct _PING6_PRIVATE_DATA {
+ EFI_HANDLE ImageHandle;
+ EFI_HANDLE NicHandle;
+ EFI_HANDLE Ip6ChildHandle;
+ EFI_IP6_PROTOCOL *Ip6;
+ EFI_EVENT Timer;
+
+ EFI_STATUS Status;
+ LIST_ENTRY TxList;
+ EFI_IP6_COMPLETION_TOKEN RxToken;
+ UINT16 RxCount;
+ UINT16 TxCount;
+ UINT32 RttSum;
+ UINT32 RttMin;
+ UINT32 RttMax;
+ UINT32 SequenceNum;
+
+ EFI_IPv6_ADDRESS SrcAddress;
+ EFI_IPv6_ADDRESS DstAddress;
+ UINT32 SendNum;
+ UINT32 BufferSize;
+} PING6_PRIVATE_DATA;
+
+/**
+ Reads and returns the current value of register.
+ In IA64, the register is the Interval Timer Vector (ITV).
+ In X86(IA32/X64), the register is the Time Stamp Counter (TSC)
+
+ @return The current value of the register.
+
+**/
+UINT64
+ReadTime (
+ VOID
+ );
+
+#endif
diff --git a/NetworkPkg/Application/Ping6/Ping6.inf b/NetworkPkg/Application/Ping6/Ping6.inf new file mode 100644 index 0000000000..56b2163ead --- /dev/null +++ b/NetworkPkg/Application/Ping6/Ping6.inf @@ -0,0 +1,64 @@ +## @file
+# Component description file for Ping6 application.
+#
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = Ping6
+ FILE_GUID = F35F733F-5235-4d7b-83FA-97780CEBCB20
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializePing6
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ Ping6.c
+ Ping6Strings.uni
+ Ping6.h
+
+[Sources.IA32]
+ Ia32/Tsc.c
+
+[Sources.X64]
+ X64/Tsc.c
+
+[Sources.IPF]
+ Ipf/Itc.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
+ UefiApplicationEntryPoint
+ BaseMemoryLib
+ ShellLib
+ MemoryAllocationLib
+ DebugLib
+ HiiLib
+ NetLib
+
+[Protocols]
+ gEfiCpuArchProtocolGuid ## CONSUMS
+ gEfiIp6ProtocolGuid ## CONSUMS
+ gEfiIp6ServiceBindingProtocolGuid ## CONSUMS
+ gEfiIp6ConfigProtocolGuid ## CONSUMS
diff --git a/NetworkPkg/Application/Ping6/Ping6Strings.uni b/NetworkPkg/Application/Ping6/Ping6Strings.uni Binary files differnew file mode 100644 index 0000000000..c8b919c4ce --- /dev/null +++ b/NetworkPkg/Application/Ping6/Ping6Strings.uni diff --git a/NetworkPkg/Application/Ping6/X64/Tsc.c b/NetworkPkg/Application/Ping6/X64/Tsc.c new file mode 100644 index 0000000000..b3e7bdbb96 --- /dev/null +++ b/NetworkPkg/Application/Ping6/X64/Tsc.c @@ -0,0 +1,28 @@ +/** @file
+ The implement to read TSC in X64 platform.
+
+ Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+
+/**
+ Reads and returns the current value of Time Stamp Counter (TSC).
+
+ @return The current value of TSC
+
+**/
+UINT64
+ReadTime ()
+{
+ return AsmReadTsc ();
+}
diff --git a/NetworkPkg/Application/VConfig/VConfig.c b/NetworkPkg/Application/VConfig/VConfig.c new file mode 100644 index 0000000000..c948131ffc --- /dev/null +++ b/NetworkPkg/Application/VConfig/VConfig.c @@ -0,0 +1,668 @@ +/** @file
+ Shell application for VLAN configuration.
+
+ Copyright (C) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Protocol/VlanConfig.h>
+
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/NetLib.h>
+
+#define INVALID_NIC_INDEX 0xffff
+#define INVALID_VLAN_ID 0xffff
+
+//
+// This is the generated String package data for all .UNI files.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 VConfigStrings[];
+
+EFI_HANDLE mImageHandle = NULL;
+EFI_HII_HANDLE mHiiHandle = NULL;
+
+SHELL_PARAM_ITEM mParamList[] = {
+ {
+ L"-l",
+ TypeValue
+ },
+ {
+ L"-a",
+ TypeMaxValue
+ },
+ {
+ L"-d",
+ TypeValue
+ },
+ {
+ NULL,
+ TypeMax
+ }
+};
+
+/**
+ Locate the network interface handle buffer.
+
+ @param[out] NumberOfHandles Pointer to the number of handles.
+ @param[out] HandleBuffer Pointer to the buffer to store the returned handles.
+
+**/
+VOID
+LocateNicHandleBuffer (
+ OUT UINTN *NumberOfHandles,
+ OUT EFI_HANDLE **HandleBuffer
+ )
+{
+ EFI_STATUS Status;
+
+ *NumberOfHandles = 0;
+ *HandleBuffer = NULL;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiVlanConfigProtocolGuid,
+ NULL,
+ NumberOfHandles,
+ HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_LOCATE_FAIL), mHiiHandle, Status);
+ }
+}
+
+/**
+ Extract the decimal index from the network interface name.
+
+ @param[in] Name Name of the network interface.
+
+ @retval INVALID_NIC_INDEX Failed to extract the network interface index.
+ @return others The network interface index.
+
+**/
+UINTN
+NicNameToIndex (
+ IN CHAR16 *Name
+ )
+{
+ CHAR16 *Str;
+
+ Str = Name + 3;
+ if ((StrnCmp (Name, L"eth", 3) != 0) || (*Str == 0)) {
+ return INVALID_NIC_INDEX;
+ }
+
+ while (*Str != 0) {
+ if ((*Str < L'0') || (*Str > L'9')) {
+ return INVALID_NIC_INDEX;
+ }
+
+ Str++;
+ }
+
+ return (UINT16) StrDecimalToUintn (Name + 3);
+}
+
+/**
+ Find network interface device handle by its name.
+
+ @param[in] Name Name of the network interface.
+
+ @retval NULL Cannot find the network interface.
+ @return others Handle of the network interface.
+
+**/
+EFI_HANDLE
+NicNameToHandle (
+ IN CHAR16 *Name
+ )
+{
+ UINTN NumberOfHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ EFI_HANDLE Handle;
+
+ //
+ // Find all NIC handles.
+ //
+ LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);
+ if (NumberOfHandles == 0) {
+ return NULL;
+ }
+
+ Index = NicNameToIndex (Name);
+ if (Index >= NumberOfHandles) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_IF), mHiiHandle, Name);
+ Handle = NULL;
+ } else {
+ Handle = HandleBuffer[Index];
+ }
+
+ FreePool (HandleBuffer);
+ return Handle;
+}
+
+/**
+ Open VlanConfig protocol from a handle.
+
+ @param[in] Handle The handle to open the VlanConfig protocol.
+
+ @return The VlanConfig protocol interface.
+
+**/
+EFI_VLAN_CONFIG_PROTOCOL *
+OpenVlanConfigProtocol (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
+
+ VlanConfig = NULL;
+ gBS->OpenProtocol (
+ Handle,
+ &gEfiVlanConfigProtocolGuid,
+ (VOID **) &VlanConfig,
+ mImageHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ return VlanConfig;
+}
+
+/**
+ Close VlanConfig protocol of a handle.
+
+ @param[in] Handle The handle to close the VlanConfig protocol.
+
+**/
+VOID
+CloseVlanConfigProtocol (
+ IN EFI_HANDLE Handle
+ )
+{
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiVlanConfigProtocolGuid,
+ mImageHandle,
+ Handle
+ );
+}
+
+/**
+ Display VLAN configuration of a network interface.
+
+ @param[in] Handle Handle of the network interface.
+ @param[in] NicIndex Index of the network interface.
+
+**/
+VOID
+ShowNicVlanInfo (
+ IN EFI_HANDLE Handle,
+ IN UINTN NicIndex
+ )
+{
+ CHAR16 *MacStr;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
+ UINT16 NumberOfVlan;
+ EFI_VLAN_FIND_DATA *VlanData;
+
+ VlanConfig = OpenVlanConfigProtocol (Handle);
+ if (VlanConfig == NULL) {
+ return ;
+ }
+
+ MacStr = NULL;
+ Status = NetLibGetMacString (Handle, mImageHandle, &MacStr);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_MAC_FAIL), mHiiHandle, Status);
+ goto Exit;
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_ETH_MAC), mHiiHandle, NicIndex, MacStr);
+
+ Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VLAN), mHiiHandle);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_FIND_FAIL), mHiiHandle, Status);
+ }
+
+ goto Exit;
+ }
+
+ for (Index = 0; Index < NumberOfVlan; Index++) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_VCONFIG_VLAN_DISPLAY),
+ mHiiHandle,
+ VlanData[Index].VlanId,
+ VlanData[Index].Priority
+ );
+ }
+
+ FreePool (VlanData);
+
+Exit:
+ CloseVlanConfigProtocol (Handle);
+
+ if (MacStr != NULL) {
+ FreePool (MacStr);
+ }
+}
+
+/**
+ Display the VLAN configuration of all, or a specified network interface.
+
+ @param[in] Name Name of the network interface. If NULL, the VLAN
+ configuration of all network will be displayed.
+
+**/
+VOID
+DisplayVlan (
+ IN CHAR16 *Name OPTIONAL
+ )
+{
+ UINTN NumberOfHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ EFI_HANDLE NicHandle;
+
+ if (Name != NULL) {
+ //
+ // Display specified NIC
+ //
+ NicHandle = NicNameToHandle (Name);
+ if (NicHandle == NULL) {
+ return ;
+ }
+
+ ShowNicVlanInfo (NicHandle, 0);
+ return ;
+ }
+
+ //
+ // Find all NIC handles
+ //
+ LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);
+ if (NumberOfHandles == 0) {
+ return ;
+ }
+
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ ShowNicVlanInfo (HandleBuffer[Index], Index);
+ }
+
+ FreePool (HandleBuffer);
+}
+
+/**
+ Convert a NULL-terminated unicode decimal VLAN ID string to VLAN ID.
+
+ @param[in] String Pointer to VLAN ID string from user input.
+
+ @retval Value translated from String, or INVALID_VLAN_ID is string is invalid.
+
+**/
+UINT16
+StrToVlanId (
+ IN CHAR16 *String
+ )
+{
+ CHAR16 *Str;
+
+ if (String == NULL) {
+ return INVALID_VLAN_ID;
+ }
+
+ Str = String;
+ while ((*Str >= '0') && (*Str <= '9')) {
+ Str++;
+ }
+
+ if (*Str != 0) {
+ return INVALID_VLAN_ID;
+ }
+
+ return (UINT16) StrDecimalToUintn (String);
+}
+
+/**
+ Add a VLAN device.
+
+ @param[in] ParamStr Parameter string from user input.
+
+**/
+VOID
+AddVlan (
+ IN CHAR16 *ParamStr
+ )
+{
+ CHAR16 *Name;
+ CHAR16 *VlanIdStr;
+ CHAR16 *PriorityStr;
+ CHAR16 *StrPtr;
+ BOOLEAN IsSpace;
+ UINTN VlanId;
+ UINTN Priority;
+ EFI_HANDLE Handle;
+ EFI_HANDLE VlanHandle;
+ EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
+ EFI_STATUS Status;
+
+ VlanConfig = NULL;
+ Priority = 0;
+
+ if (ParamStr == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);
+ return ;
+ }
+
+ StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);
+ if (StrPtr == NULL) {
+ return ;
+ }
+
+ Name = StrPtr;
+ VlanIdStr = NULL;
+ PriorityStr = NULL;
+ IsSpace = FALSE;
+ while (*StrPtr != 0) {
+ if (*StrPtr == L' ') {
+ *StrPtr = 0;
+ IsSpace = TRUE;
+ } else {
+ if (IsSpace) {
+ //
+ // Start of a parameter.
+ //
+ if (VlanIdStr == NULL) {
+ //
+ // 2nd parameter is VLAN ID.
+ //
+ VlanIdStr = StrPtr;
+ } else if (PriorityStr == NULL) {
+ //
+ // 3rd parameter is Priority.
+ //
+ PriorityStr = StrPtr;
+ } else {
+ //
+ // Ignore else parameters.
+ //
+ break;
+ }
+ }
+
+ IsSpace = FALSE;
+ }
+
+ StrPtr++;
+ }
+
+ Handle = NicNameToHandle (Name);
+ if (Handle == NULL) {
+ goto Exit;
+ }
+
+ VlanConfig = OpenVlanConfigProtocol (Handle);
+ if (VlanConfig == NULL) {
+ goto Exit;
+ }
+
+ //
+ // Check VLAN ID.
+ //
+ if ((VlanIdStr == NULL) || (*VlanIdStr == 0)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);
+ goto Exit;
+ }
+
+ VlanId = StrToVlanId (VlanIdStr);
+ if (VlanId > 4094) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);
+ goto Exit;
+ }
+
+ //
+ // Check Priority.
+ //
+ if ((PriorityStr != NULL) && (*PriorityStr != 0)) {
+ Priority = StrDecimalToUintn (PriorityStr);
+ if (Priority > 7) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_PRIORITY), mHiiHandle, PriorityStr);
+ goto Exit;
+ }
+ }
+
+ //
+ // Set VLAN
+ //
+ Status = VlanConfig->Set (VlanConfig, (UINT16) VlanId, (UINT8) Priority);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_FAIL), mHiiHandle, Status);
+ goto Exit;
+ }
+
+ //
+ // Connect the VLAN device.
+ //
+ VlanHandle = NetLibGetVlanHandle (Handle, (UINT16) VlanId);
+ if (VlanHandle != NULL) {
+ gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_SUCCESS), mHiiHandle);
+
+Exit:
+ if (VlanConfig != NULL) {
+ CloseVlanConfigProtocol (Handle);
+ }
+
+ FreePool (Name);
+}
+
+/**
+ Remove a VLAN device.
+
+ @param[in] ParamStr Parameter string from user input.
+
+**/
+VOID
+DeleteVlan (
+ CHAR16 *ParamStr
+ )
+{
+ CHAR16 *Name;
+ CHAR16 *VlanIdStr;
+ CHAR16 *StrPtr;
+ UINTN VlanId;
+ EFI_HANDLE Handle;
+ EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
+ EFI_STATUS Status;
+ UINT16 NumberOfVlan;
+ EFI_VLAN_FIND_DATA *VlanData;
+
+ VlanConfig = NULL;
+
+ if (ParamStr == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);
+ return ;
+ }
+
+ StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);
+ if (StrPtr == NULL) {
+ return ;
+ }
+
+ Name = StrPtr;
+ VlanIdStr = NULL;
+ while (*StrPtr != 0) {
+ if (*StrPtr == L'.') {
+ *StrPtr = 0;
+ VlanIdStr = StrPtr + 1;
+ break;
+ }
+
+ StrPtr++;
+ }
+
+ Handle = NicNameToHandle (Name);
+ if (Handle == NULL) {
+ goto Exit;
+ }
+
+ VlanConfig = OpenVlanConfigProtocol (Handle);
+ if (VlanConfig == NULL) {
+ goto Exit;
+ }
+
+ //
+ // Check VLAN ID
+ //
+ if (VlanIdStr == NULL || *VlanIdStr == 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);
+ goto Exit;
+ }
+
+ VlanId = StrToVlanId (VlanIdStr);
+ if (VlanId > 4094) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);
+ goto Exit;
+ }
+
+ //
+ // Delete VLAN.
+ //
+ Status = VlanConfig->Remove (VlanConfig, (UINT16) VlanId);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NOT_FOUND), mHiiHandle);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_FAIL), mHiiHandle, Status);
+ }
+
+ goto Exit;
+ }
+
+ //
+ // Check whether this is the last VLAN to remove.
+ //
+ Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
+ if (EFI_ERROR (Status)) {
+ //
+ // This is the last VLAN to remove, try to connect the controller handle.
+ //
+ gBS->ConnectController (Handle, NULL, NULL, TRUE);
+ } else {
+ FreePool (VlanData);
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_SUCCESS), mHiiHandle);
+
+Exit:
+ if (VlanConfig != NULL) {
+ CloseVlanConfigProtocol (Handle);
+ }
+
+ FreePool (Name);
+}
+
+/**
+ The actual entry point for the application.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point executed successfully.
+ @retval other Some error occur when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+VlanConfigMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ LIST_ENTRY *List;
+ CONST CHAR16 *Str;
+
+ mImageHandle = ImageHandle;
+
+ //
+ // Register our string package to HII database.
+ //
+ mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, VConfigStrings, NULL);
+ if (mHiiHandle == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ List = NULL;
+ ShellCommandLineParseEx (mParamList, &List, NULL, FALSE, FALSE);
+ if (List == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);
+ goto Exit;
+ }
+
+ if (ShellCommandLineGetFlag (List, L"-?")) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_HELP), mHiiHandle);
+ goto Exit;
+ }
+
+ if (ShellCommandLineGetFlag (List, L"-l")) {
+ Str = ShellCommandLineGetValue (List, L"-l");
+ DisplayVlan ((CHAR16 *) Str);
+ goto Exit;
+ }
+
+ if (ShellCommandLineGetFlag (List, L"-a")) {
+ Str = ShellCommandLineGetValue (List, L"-a");
+ AddVlan ((CHAR16 *) Str);
+ goto Exit;
+ }
+
+ if (ShellCommandLineGetFlag (List, L"-d")) {
+ Str = ShellCommandLineGetValue (List, L"-d");
+ DeleteVlan ((CHAR16 *) Str);
+ goto Exit;
+ }
+
+ //
+ // No valid argument till now.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);
+
+Exit:
+ if (List != NULL) {
+ ShellCommandLineFreeVarList (List);
+ }
+
+ //
+ // Remove our string package from HII database.
+ //
+ HiiRemovePackages (mHiiHandle);
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/Application/VConfig/VConfig.inf b/NetworkPkg/Application/VConfig/VConfig.inf new file mode 100644 index 0000000000..e69da02f7b --- /dev/null +++ b/NetworkPkg/Application/VConfig/VConfig.inf @@ -0,0 +1,47 @@ +## @file
+# Component files for VLAN configuration shell application.
+#
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = VConfig
+ FILE_GUID = 87E36301-0406-44db-AAF3-9E0E591F3725
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = VlanConfigMain
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Sources]
+ VConfigStrings.uni
+ VConfig.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiBootServicesTableLib
+ UefiLib
+ ShellLib
+ NetLib
+ MemoryAllocationLib
+ HiiLib
+
+[Protocols]
+ gEfiVlanConfigProtocolGuid
diff --git a/NetworkPkg/Application/VConfig/VConfigStrings.uni b/NetworkPkg/Application/VConfig/VConfigStrings.uni Binary files differnew file mode 100644 index 0000000000..e8bdcefee8 --- /dev/null +++ b/NetworkPkg/Application/VConfig/VConfigStrings.uni |