summaryrefslogtreecommitdiff
path: root/ShellPkg/Library/UefiShellNetwork2CommandsLib
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Library/UefiShellNetwork2CommandsLib')
-rw-r--r--ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c3820
-rw-r--r--ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c2754
-rw-r--r--ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c172
-rw-r--r--ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h132
-rw-r--r--ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf120
-rw-r--r--ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni320
6 files changed, 3659 insertions, 3659 deletions
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
index 5cb92c485b..8361624eb4 100644
--- a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
+++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c
@@ -1,1910 +1,1910 @@
-/** @file
- The implementation for Shell command IfConfig6.
-
- Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
- (C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "UefiShellNetwork2CommandsLib.h"
-
-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;
-
-SHELL_PARAM_ITEM mIfConfig6CheckList[] = {
- {
- L"-b",
- TypeFlag
- },
- {
- L"-s",
- TypeMaxValue
- },
- {
- L"-l",
- TypeValue
- },
- {
- L"-r",
- TypeValue
- },
- {
- L"-?",
- TypeFlag
- },
- {
- NULL,
- TypeMax
- },
-};
-
-VAR_CHECK_ITEM mIfConfig6SetCheckList[] = {
- {
- 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
- },
-};
-
-/**
- Free the ARG_LIST.
-
- @param List Pointer to ARG_LIST to free.
-**/
-VOID
-IfConfig6FreeArgList (
- ARG_LIST *List
- )
-{
- ARG_LIST *Next;
-
- while (List->Next != NULL) {
- Next = List->Next;
- FreePool (List);
- List = Next;
- }
-
- FreePool (List);
-}
-
-/**
- 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 *
-IfConfig6SplitStrToList (
- IN CONST CHAR16 *String,
- IN CHAR16 Separator
- )
-{
- CHAR16 *Str;
- CHAR16 *ArgStr;
- ARG_LIST *ArgList;
- ARG_LIST *ArgNode;
-
- if ((String == NULL) || (*String == L'\0')) {
- return NULL;
- }
-
- //
- // Copy the CONST string to a local copy.
- //
- Str = AllocateCopyPool (StrSize (String), String);
- if (Str == NULL) {
- return NULL;
- }
-
- ArgStr = Str;
-
- //
- // init a node for the list head.
- //
- ArgNode = (ARG_LIST *)AllocateZeroPool (sizeof (ARG_LIST));
- if (ArgNode == NULL) {
- return 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));
- if (ArgNode->Next == NULL) {
- //
- // Free the local copy of string stored in the first node
- //
- FreePool (ArgList->Arg);
- IfConfig6FreeArgList (ArgList);
- return 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] Event The event this notify function registered to.
- @param[in] Context Pointer to the context data registered to the event.
-
-**/
-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), gShellNetwork2HiiHandle, Node[Index]);
- if (Index + 1 < Size) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
- }
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
-}
-
-/**
- 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), gShellNetwork2HiiHandle);
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
-
- while ((Index < PREFIXMAXLEN) && (Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0)) {
- 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), gShellNetwork2HiiHandle, Ip->Addr[Index]);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), gShellNetwork2HiiHandle, Ip->Addr[Index + 1]);
- }
-
- if (Index + 2 < PREFIXMAXLEN) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
- }
- }
-
- if (PrefixLen != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), gShellNetwork2HiiHandle, *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] BufSize 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;
-
- Prefix = 0;
- 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] BufSize 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 Status;
- }
-
- //
- // 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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 SHELL_SUCCESS The IfConfig6 list processed successfully.
- @retval others The IfConfig6 list process failed.
-
-**/
-SHELL_STATUS
-IfConfig6ShowInterfaceInfo (
- IN LIST_ENTRY *IfList
- )
-{
- LIST_ENTRY *Entry;
- IFCONFIG6_INTERFACE_CB *IfCb;
- UINTN Index;
-
- Entry = IfList->ForwardLink;
-
- if (IsListEmpty (IfList)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
- }
-
- //
- // 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), gShellNetwork2HiiHandle);
-
- //
- // Print interface name.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME), gShellNetwork2HiiHandle, IfCb->IfInfo->Name);
-
- //
- // Print interface config policy.
- //
- if (IfCb->Policy == Ip6ConfigPolicyAutomatic) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO), gShellNetwork2HiiHandle);
- } else {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN), gShellNetwork2HiiHandle);
- }
-
- //
- // Print dad transmit.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS), gShellNetwork2HiiHandle, IfCb->Xmits);
-
- //
- // Print interface id if has.
- //
- if (IfCb->IfId != NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD), gShellNetwork2HiiHandle);
-
- IfConfig6PrintMacAddr (
- IfCb->IfId->Id,
- 8
- );
- }
-
- //
- // Print mac address of the interface.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD), gShellNetwork2HiiHandle);
-
- 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), gShellNetwork2HiiHandle);
-
- 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), gShellNetwork2HiiHandle);
- }
-
- //
- // Print dns server addresses list of the interface if has.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD), gShellNetwork2HiiHandle);
-
- for (Index = 0; Index < IfCb->DnsCnt; Index++) {
- IfConfig6PrintIpAddr (
- &IfCb->DnsAddr[Index],
- NULL
- );
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
- }
-
- //
- // Print route table of the interface if has.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD), gShellNetwork2HiiHandle);
-
- 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), gShellNetwork2HiiHandle);
-
- IfConfig6PrintIpAddr (
- &IfCb->IfInfo->RouteTable[Index].Gateway,
- NULL
- );
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
- }
-
- Entry = Entry->ForwardLink;
- }
-
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), gShellNetwork2HiiHandle);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
-
- return SHELL_SUCCESS;
-}
-
-/**
- The clean process of the IfConfig6 application.
-
- @param[in] IfList The pointer of IfList(interface list).
- @param[in] IfName The pointer of interface name.
-
- @retval SHELL_SUCCESS The IfConfig6 clean processed successfully.
- @retval others The IfConfig6 clean process failed.
-
-**/
-SHELL_STATUS
-IfConfig6ClearInterfaceInfo (
- IN LIST_ENTRY *IfList,
- IN CHAR16 *IfName
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
- LIST_ENTRY *Entry;
- IFCONFIG6_INTERFACE_CB *IfCb;
- EFI_IP6_CONFIG_POLICY Policy;
-
- Entry = IfList->ForwardLink;
- Status = EFI_SUCCESS;
- ShellStatus = SHELL_SUCCESS;
-
- if (IsListEmpty (IfList)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
- }
-
- //
- // Go through the interface list.If the interface name is specified, then
- // need to refresh the configuration.
- //
- while (Entry != IfList) {
- IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
-
- if ((IfName != NULL) && (StrCmp (IfName, IfCb->IfInfo->Name) == 0)) {
- Policy = Ip6ConfigPolicyManual;
-
- Status = IfCb->IfCfg->SetData (
- IfCb->IfCfg,
- Ip6ConfigDataTypePolicy,
- sizeof (EFI_IP6_CONFIG_POLICY),
- &Policy
- );
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork2HiiHandle, L"ifconfig6");
- ShellStatus = SHELL_ACCESS_DENIED;
- break;
- }
- }
-
- Policy = Ip6ConfigPolicyAutomatic;
-
- Status = IfCb->IfCfg->SetData (
- IfCb->IfCfg,
- Ip6ConfigDataTypePolicy,
- sizeof (EFI_IP6_CONFIG_POLICY),
- &Policy
- );
-
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork2HiiHandle, L"ifconfig6");
- ShellStatus = SHELL_ACCESS_DENIED;
- break;
- }
-
- Entry = Entry->ForwardLink;
- }
-
- return ShellStatus;
-}
-
-/**
- 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 SHELL_SUCCESS The IfConfig6 set processed successfully.
- @retval others The IfConfig6 set process failed.
-
-**/
-SHELL_STATUS
-IfConfig6SetInterfaceInfo (
- IN LIST_ENTRY *IfList,
- IN ARG_LIST *VarArg
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
- 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), gShellNetwork2HiiHandle);
- return SHELL_INVALID_PARAMETER;
- }
-
- //
- // Make sure to set only one interface each time.
- //
- IfCb = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link);
- Status = EFI_SUCCESS;
- ShellStatus = SHELL_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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
-
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- IfConfig6ManualAddressNotify,
- &IsAddressOk,
- &MappedEvt
- );
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
-
- //
- // Parse the setting variables.
- //
- while (VarArg != NULL) {
- //
- // Check invalid parameters (duplication & unknown & conflict).
- //
- CheckCode = IfConfig6RetriveCheckListByName (
- mIfConfig6SetCheckList,
- VarArg->Arg,
- FALSE
- );
-
- if (VarCheckOk != CheckCode) {
- switch (CheckCode) {
- case VarCheckDuplicate:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);
- break;
-
- case VarCheckConflict:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);
- break;
-
- case VarCheckUnknown:
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), gShellNetwork2HiiHandle, 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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
-
- VarArg = VarArg->Next;
-
- if (VarArg != NULL) {
- if (StrCmp (VarArg->Arg, L"host") == 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_IP_CONFIG), gShellNetwork2HiiHandle, Status);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- } else if (StrCmp (VarArg->Arg, L"gw") == 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_GW_CONFIG), gShellNetwork2HiiHandle, Status);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- } else if (StrCmp (VarArg->Arg, L"dns") == 0) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_DNS_CONFIG), gShellNetwork2HiiHandle, Status);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
- }
- } 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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"host");
- continue;
- } else {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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), gShellNetwork2HiiHandle, Status);
- ShellStatus = SHELL_ACCESS_DENIED;
- 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), gShellNetwork2HiiHandle, Status);
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
-
- IfInfo = AllocateZeroPool (DataSize);
-
- if (IfInfo == NULL) {
- ShellStatus = SHELL_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), gShellNetwork2HiiHandle, Status);
- ShellStatus = SHELL_ACCESS_DENIED;
- 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), gShellNetwork2HiiHandle);
- IfConfig6PrintIpAddr (
- &CfgManAddr[Index].Address,
- &CfgManAddr[Index].PrefixLength
- );
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
- }
- }
- } 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) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"gw");
- continue;
- } else {
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
- }
-
- //
- // Set static gateway ip6 address list.
- //
- Status = IfCb->IfCfg->SetData (
- IfCb->IfCfg,
- Ip6ConfigDataTypeGateway,
- AddrSize,
- CfgAddr
- );
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_GW), gShellNetwork2HiiHandle, 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) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"dns");
- continue;
- } else {
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
- }
-
- //
- // Set static DNS server ip6 address list.
- //
- Status = IfCb->IfCfg->SetData (
- IfCb->IfCfg,
- Ip6ConfigDataTypeDnsServer,
- AddrSize,
- CfgAddr
- );
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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)) {
- ShellStatus = SHELL_INVALID_PARAMETER;
- 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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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 ShellStatus;
-}
-
-/**
- The IfConfig6 main process.
-
- @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
-
- @retval SHELL_SUCCESS IfConfig6 processed successfully.
- @retval others The IfConfig6 process failed.
-
-**/
-SHELL_STATUS
-IfConfig6 (
- IN IFCONFIG6_PRIVATE_DATA *Private
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
-
- ShellStatus = SHELL_SUCCESS;
-
- //
- // Get configure information of all interfaces.
- //
- Status = IfConfig6GetInterfaceInfo (
- Private->ImageHandle,
- Private->IfName,
- &Private->IfList
- );
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_NOT_FOUND;
- goto ON_EXIT;
- }
-
- switch (Private->OpCode) {
- case IfConfig6OpList:
- ShellStatus = IfConfig6ShowInterfaceInfo (&Private->IfList);
- break;
-
- case IfConfig6OpClear:
- ShellStatus = IfConfig6ClearInterfaceInfo (&Private->IfList, Private->IfName);
- break;
-
- case IfConfig6OpSet:
- ShellStatus = IfConfig6SetInterfaceInfo (&Private->IfList, Private->VarArg);
- break;
-
- default:
- ShellStatus = SHELL_UNSUPPORTED;
- }
-
-ON_EXIT:
-
- return ShellStatus;
-}
-
-/**
- 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;
-
- ASSERT (Private != NULL);
-
- //
- // Clean the list which save the set config Args.
- //
- if (Private->VarArg != NULL) {
- IfConfig6FreeArgList (Private->VarArg);
- }
-
- 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);
-}
-
-/**
- Function for 'ifconfig6' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @retval SHELL_SUCCESS ifconfig6 command processed successfully.
- @retval others The ifconfig6 command process failed.
-
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunIfconfig6 (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
- IFCONFIG6_PRIVATE_DATA *Private;
- LIST_ENTRY *ParamPackage;
- CONST CHAR16 *ValueStr;
- ARG_LIST *ArgList;
- CHAR16 *ProblemParam;
- CHAR16 *Str;
-
- Private = NULL;
- Status = EFI_INVALID_PARAMETER;
- ShellStatus = SHELL_SUCCESS;
-
- Status = ShellCommandLineParseEx (mIfConfig6CheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND), gShellNetwork2HiiHandle, L"ifconfig6", ProblemParam);
- ShellStatus = SHELL_INVALID_PARAMETER;
- 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), gShellNetwork2HiiHandle);
- ShellStatus = SHELL_INVALID_PARAMETER;
- 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), gShellNetwork2HiiHandle);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
-
- Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));
-
- if (Private == NULL) {
- ShellStatus = SHELL_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 = AllocateCopyPool (StrSize (ValueStr), ValueStr);
- if (Str == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
-
- 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 = AllocateCopyPool (StrSize (ValueStr), ValueStr);
- if (Str == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
-
- 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), gShellNetwork2HiiHandle);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
-
- //
- // To split the configuration into multi-section.
- //
- ArgList = IfConfig6SplitStrToList (ValueStr, L' ');
- if (ArgList == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
-
- 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), gShellNetwork2HiiHandle);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
- }
-
- //
- // Main process of ifconfig6.
- //
- ShellStatus = IfConfig6 (Private);
-
-ON_EXIT:
-
- ShellCommandLineFreeVarList (ParamPackage);
- if (Private != NULL) {
- IfConfig6Cleanup (Private);
- }
-
- return ShellStatus;
-}
+/** @file
+ The implementation for Shell command IfConfig6.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "UefiShellNetwork2CommandsLib.h"
+
+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;
+
+SHELL_PARAM_ITEM mIfConfig6CheckList[] = {
+ {
+ L"-b",
+ TypeFlag
+ },
+ {
+ L"-s",
+ TypeMaxValue
+ },
+ {
+ L"-l",
+ TypeValue
+ },
+ {
+ L"-r",
+ TypeValue
+ },
+ {
+ L"-?",
+ TypeFlag
+ },
+ {
+ NULL,
+ TypeMax
+ },
+};
+
+VAR_CHECK_ITEM mIfConfig6SetCheckList[] = {
+ {
+ 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
+ },
+};
+
+/**
+ Free the ARG_LIST.
+
+ @param List Pointer to ARG_LIST to free.
+**/
+VOID
+IfConfig6FreeArgList (
+ ARG_LIST *List
+ )
+{
+ ARG_LIST *Next;
+
+ while (List->Next != NULL) {
+ Next = List->Next;
+ FreePool (List);
+ List = Next;
+ }
+
+ FreePool (List);
+}
+
+/**
+ 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 *
+IfConfig6SplitStrToList (
+ IN CONST CHAR16 *String,
+ IN CHAR16 Separator
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ArgStr;
+ ARG_LIST *ArgList;
+ ARG_LIST *ArgNode;
+
+ if ((String == NULL) || (*String == L'\0')) {
+ return NULL;
+ }
+
+ //
+ // Copy the CONST string to a local copy.
+ //
+ Str = AllocateCopyPool (StrSize (String), String);
+ if (Str == NULL) {
+ return NULL;
+ }
+
+ ArgStr = Str;
+
+ //
+ // init a node for the list head.
+ //
+ ArgNode = (ARG_LIST *)AllocateZeroPool (sizeof (ARG_LIST));
+ if (ArgNode == NULL) {
+ return 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));
+ if (ArgNode->Next == NULL) {
+ //
+ // Free the local copy of string stored in the first node
+ //
+ FreePool (ArgList->Arg);
+ IfConfig6FreeArgList (ArgList);
+ return 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] Event The event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the event.
+
+**/
+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), gShellNetwork2HiiHandle, Node[Index]);
+ if (Index + 1 < Size) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
+ }
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
+}
+
+/**
+ 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), gShellNetwork2HiiHandle);
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
+
+ while ((Index < PREFIXMAXLEN) && (Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0)) {
+ 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), gShellNetwork2HiiHandle, Ip->Addr[Index]);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), gShellNetwork2HiiHandle, Ip->Addr[Index + 1]);
+ }
+
+ if (Index + 2 < PREFIXMAXLEN) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
+ }
+ }
+
+ if (PrefixLen != NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), gShellNetwork2HiiHandle, *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] BufSize 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;
+
+ Prefix = 0;
+ 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] BufSize 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 Status;
+ }
+
+ //
+ // 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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 SHELL_SUCCESS The IfConfig6 list processed successfully.
+ @retval others The IfConfig6 list process failed.
+
+**/
+SHELL_STATUS
+IfConfig6ShowInterfaceInfo (
+ IN LIST_ENTRY *IfList
+ )
+{
+ LIST_ENTRY *Entry;
+ IFCONFIG6_INTERFACE_CB *IfCb;
+ UINTN Index;
+
+ Entry = IfList->ForwardLink;
+
+ if (IsListEmpty (IfList)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
+ }
+
+ //
+ // 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), gShellNetwork2HiiHandle);
+
+ //
+ // Print interface name.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME), gShellNetwork2HiiHandle, IfCb->IfInfo->Name);
+
+ //
+ // Print interface config policy.
+ //
+ if (IfCb->Policy == Ip6ConfigPolicyAutomatic) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO), gShellNetwork2HiiHandle);
+ } else {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN), gShellNetwork2HiiHandle);
+ }
+
+ //
+ // Print dad transmit.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS), gShellNetwork2HiiHandle, IfCb->Xmits);
+
+ //
+ // Print interface id if has.
+ //
+ if (IfCb->IfId != NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD), gShellNetwork2HiiHandle);
+
+ IfConfig6PrintMacAddr (
+ IfCb->IfId->Id,
+ 8
+ );
+ }
+
+ //
+ // Print mac address of the interface.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD), gShellNetwork2HiiHandle);
+
+ 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), gShellNetwork2HiiHandle);
+
+ 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), gShellNetwork2HiiHandle);
+ }
+
+ //
+ // Print dns server addresses list of the interface if has.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD), gShellNetwork2HiiHandle);
+
+ for (Index = 0; Index < IfCb->DnsCnt; Index++) {
+ IfConfig6PrintIpAddr (
+ &IfCb->DnsAddr[Index],
+ NULL
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
+ }
+
+ //
+ // Print route table of the interface if has.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD), gShellNetwork2HiiHandle);
+
+ 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), gShellNetwork2HiiHandle);
+
+ IfConfig6PrintIpAddr (
+ &IfCb->IfInfo->RouteTable[Index].Gateway,
+ NULL
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
+ }
+
+ Entry = Entry->ForwardLink;
+ }
+
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), gShellNetwork2HiiHandle);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
+
+ return SHELL_SUCCESS;
+}
+
+/**
+ The clean process of the IfConfig6 application.
+
+ @param[in] IfList The pointer of IfList(interface list).
+ @param[in] IfName The pointer of interface name.
+
+ @retval SHELL_SUCCESS The IfConfig6 clean processed successfully.
+ @retval others The IfConfig6 clean process failed.
+
+**/
+SHELL_STATUS
+IfConfig6ClearInterfaceInfo (
+ IN LIST_ENTRY *IfList,
+ IN CHAR16 *IfName
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+ LIST_ENTRY *Entry;
+ IFCONFIG6_INTERFACE_CB *IfCb;
+ EFI_IP6_CONFIG_POLICY Policy;
+
+ Entry = IfList->ForwardLink;
+ Status = EFI_SUCCESS;
+ ShellStatus = SHELL_SUCCESS;
+
+ if (IsListEmpty (IfList)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
+ }
+
+ //
+ // Go through the interface list.If the interface name is specified, then
+ // need to refresh the configuration.
+ //
+ while (Entry != IfList) {
+ IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
+
+ if ((IfName != NULL) && (StrCmp (IfName, IfCb->IfInfo->Name) == 0)) {
+ Policy = Ip6ConfigPolicyManual;
+
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypePolicy,
+ sizeof (EFI_IP6_CONFIG_POLICY),
+ &Policy
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork2HiiHandle, L"ifconfig6");
+ ShellStatus = SHELL_ACCESS_DENIED;
+ break;
+ }
+ }
+
+ Policy = Ip6ConfigPolicyAutomatic;
+
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypePolicy,
+ sizeof (EFI_IP6_CONFIG_POLICY),
+ &Policy
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork2HiiHandle, L"ifconfig6");
+ ShellStatus = SHELL_ACCESS_DENIED;
+ break;
+ }
+
+ Entry = Entry->ForwardLink;
+ }
+
+ return ShellStatus;
+}
+
+/**
+ 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 SHELL_SUCCESS The IfConfig6 set processed successfully.
+ @retval others The IfConfig6 set process failed.
+
+**/
+SHELL_STATUS
+IfConfig6SetInterfaceInfo (
+ IN LIST_ENTRY *IfList,
+ IN ARG_LIST *VarArg
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+ 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), gShellNetwork2HiiHandle);
+ return SHELL_INVALID_PARAMETER;
+ }
+
+ //
+ // Make sure to set only one interface each time.
+ //
+ IfCb = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link);
+ Status = EFI_SUCCESS;
+ ShellStatus = SHELL_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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IfConfig6ManualAddressNotify,
+ &IsAddressOk,
+ &MappedEvt
+ );
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Parse the setting variables.
+ //
+ while (VarArg != NULL) {
+ //
+ // Check invalid parameters (duplication & unknown & conflict).
+ //
+ CheckCode = IfConfig6RetriveCheckListByName (
+ mIfConfig6SetCheckList,
+ VarArg->Arg,
+ FALSE
+ );
+
+ if (VarCheckOk != CheckCode) {
+ switch (CheckCode) {
+ case VarCheckDuplicate:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);
+ break;
+
+ case VarCheckConflict:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);
+ break;
+
+ case VarCheckUnknown:
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), gShellNetwork2HiiHandle, 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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+
+ VarArg = VarArg->Next;
+
+ if (VarArg != NULL) {
+ if (StrCmp (VarArg->Arg, L"host") == 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_IP_CONFIG), gShellNetwork2HiiHandle, Status);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ } else if (StrCmp (VarArg->Arg, L"gw") == 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_GW_CONFIG), gShellNetwork2HiiHandle, Status);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ } else if (StrCmp (VarArg->Arg, L"dns") == 0) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_DNS_CONFIG), gShellNetwork2HiiHandle, Status);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+ } 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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"host");
+ continue;
+ } else {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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), gShellNetwork2HiiHandle, Status);
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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), gShellNetwork2HiiHandle, Status);
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+
+ IfInfo = AllocateZeroPool (DataSize);
+
+ if (IfInfo == NULL) {
+ ShellStatus = SHELL_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), gShellNetwork2HiiHandle, Status);
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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), gShellNetwork2HiiHandle);
+ IfConfig6PrintIpAddr (
+ &CfgManAddr[Index].Address,
+ &CfgManAddr[Index].PrefixLength
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
+ }
+ }
+ } 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) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"gw");
+ continue;
+ } else {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Set static gateway ip6 address list.
+ //
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeGateway,
+ AddrSize,
+ CfgAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_GW), gShellNetwork2HiiHandle, 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) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"dns");
+ continue;
+ } else {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Set static DNS server ip6 address list.
+ //
+ Status = IfCb->IfCfg->SetData (
+ IfCb->IfCfg,
+ Ip6ConfigDataTypeDnsServer,
+ AddrSize,
+ CfgAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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)) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ 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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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 ShellStatus;
+}
+
+/**
+ The IfConfig6 main process.
+
+ @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
+
+ @retval SHELL_SUCCESS IfConfig6 processed successfully.
+ @retval others The IfConfig6 process failed.
+
+**/
+SHELL_STATUS
+IfConfig6 (
+ IN IFCONFIG6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+
+ ShellStatus = SHELL_SUCCESS;
+
+ //
+ // Get configure information of all interfaces.
+ //
+ Status = IfConfig6GetInterfaceInfo (
+ Private->ImageHandle,
+ Private->IfName,
+ &Private->IfList
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_NOT_FOUND;
+ goto ON_EXIT;
+ }
+
+ switch (Private->OpCode) {
+ case IfConfig6OpList:
+ ShellStatus = IfConfig6ShowInterfaceInfo (&Private->IfList);
+ break;
+
+ case IfConfig6OpClear:
+ ShellStatus = IfConfig6ClearInterfaceInfo (&Private->IfList, Private->IfName);
+ break;
+
+ case IfConfig6OpSet:
+ ShellStatus = IfConfig6SetInterfaceInfo (&Private->IfList, Private->VarArg);
+ break;
+
+ default:
+ ShellStatus = SHELL_UNSUPPORTED;
+ }
+
+ON_EXIT:
+
+ return ShellStatus;
+}
+
+/**
+ 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;
+
+ ASSERT (Private != NULL);
+
+ //
+ // Clean the list which save the set config Args.
+ //
+ if (Private->VarArg != NULL) {
+ IfConfig6FreeArgList (Private->VarArg);
+ }
+
+ 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);
+}
+
+/**
+ Function for 'ifconfig6' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+
+ @retval SHELL_SUCCESS ifconfig6 command processed successfully.
+ @retval others The ifconfig6 command process failed.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunIfconfig6 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+ IFCONFIG6_PRIVATE_DATA *Private;
+ LIST_ENTRY *ParamPackage;
+ CONST CHAR16 *ValueStr;
+ ARG_LIST *ArgList;
+ CHAR16 *ProblemParam;
+ CHAR16 *Str;
+
+ Private = NULL;
+ Status = EFI_INVALID_PARAMETER;
+ ShellStatus = SHELL_SUCCESS;
+
+ Status = ShellCommandLineParseEx (mIfConfig6CheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND), gShellNetwork2HiiHandle, L"ifconfig6", ProblemParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ 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), gShellNetwork2HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ 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), gShellNetwork2HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));
+
+ if (Private == NULL) {
+ ShellStatus = SHELL_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 = AllocateCopyPool (StrSize (ValueStr), ValueStr);
+ if (Str == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ 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 = AllocateCopyPool (StrSize (ValueStr), ValueStr);
+ if (Str == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ 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), gShellNetwork2HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ //
+ // To split the configuration into multi-section.
+ //
+ ArgList = IfConfig6SplitStrToList (ValueStr, L' ');
+ if (ArgList == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ 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), gShellNetwork2HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Main process of ifconfig6.
+ //
+ ShellStatus = IfConfig6 (Private);
+
+ON_EXIT:
+
+ ShellCommandLineFreeVarList (ParamPackage);
+ if (Private != NULL) {
+ IfConfig6Cleanup (Private);
+ }
+
+ return ShellStatus;
+}
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
index 43d578bd6a..3ddac0ba93 100644
--- a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
+++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c
@@ -1,1377 +1,1377 @@
-/** @file
- The implementation for Ping6 application.
-
- Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UefiShellNetwork2CommandsLib.h"
-
-#define PING6_DEFAULT_TIMEOUT 5000
-#define PING6_MAX_SEND_NUMBER 10000
-#define PING6_MAX_BUFFER_SIZE 32768
-#define PING6_ONE_SECOND 10000000
-#define STALL_1_MILLI_SECOND 1000
-
-#pragma pack(1)
-
-typedef struct _ICMP6_ECHO_REQUEST_REPLY {
- UINT8 Type;
- UINT8 Code;
- UINT16 Checksum;
- UINT16 Identifier;
- UINT16 SequenceNum;
- UINT32 TimeStamp;
- UINT8 Data[1];
-} ICMP6_ECHO_REQUEST_REPLY;
-
-#pragma pack()
-
-typedef struct _PING6_ICMP6_TX_INFO {
- LIST_ENTRY Link;
- UINT16 SequenceNum;
- UINT32 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;
-
- UINT32 TimerPeriod;
- UINT32 RttTimerTick;
- EFI_EVENT RttTimer;
-
- EFI_STATUS Status;
- LIST_ENTRY TxList;
- EFI_IP6_COMPLETION_TOKEN RxToken;
- UINT16 RxCount;
- UINT16 TxCount;
- UINT64 RttSum;
- UINT64 RttMin;
- UINT64 RttMax;
- UINT32 SequenceNum;
-
- EFI_IPv6_ADDRESS SrcAddress;
- EFI_IPv6_ADDRESS DstAddress;
- UINT32 SendNum;
- UINT32 BufferSize;
-} PING6_PRIVATE_DATA;
-
-SHELL_PARAM_ITEM Ping6ParamList[] = {
- {
- L"-l",
- TypeValue
- },
- {
- L"-n",
- TypeValue
- },
- {
- L"-s",
- TypeValue
- },
- {
- L"-?",
- TypeFlag
- },
- {
- NULL,
- TypeMax
- },
-};
-
-//
-// Global Variables in Ping6 application.
-//
-CONST CHAR16 *mIp6DstString;
-CONST CHAR16 *mIp6SrcString;
-EFI_CPU_ARCH_PROTOCOL *Cpu = NULL;
-
-/**
- RTT timer tick routine.
-
- @param[in] Event A EFI_EVENT type event.
- @param[in] Context The pointer to Context.
-
-**/
-VOID
-EFIAPI
-Ping6RttTimerTickRoutine (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- UINT32 *RttTimerTick;
-
- RttTimerTick = (UINT32 *)Context;
- (*RttTimerTick)++;
-}
-
-/**
- Get the timer period of the system.
-
- This function tries to get the system timer period by creating
- an 1ms period timer.
-
- @return System timer period in MS, or 0 if operation failed.
-
-**/
-UINT32
-Ping6GetTimerPeriod (
- VOID
- )
-{
- EFI_STATUS Status;
- UINT32 RttTimerTick;
- EFI_EVENT TimerEvent;
- UINT32 StallCounter;
- EFI_TPL OldTpl;
-
- RttTimerTick = 0;
- StallCounter = 0;
-
- Status = gBS->CreateEvent (
- EVT_TIMER | EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- Ping6RttTimerTickRoutine,
- &RttTimerTick,
- &TimerEvent
- );
- if (EFI_ERROR (Status)) {
- return 0;
- }
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- Status = gBS->SetTimer (
- TimerEvent,
- TimerPeriodic,
- TICKS_PER_MS
- );
- if (EFI_ERROR (Status)) {
- gBS->CloseEvent (TimerEvent);
- return 0;
- }
-
- while (RttTimerTick < 10) {
- gBS->Stall (STALL_1_MILLI_SECOND);
- ++StallCounter;
- }
-
- gBS->RestoreTPL (OldTpl);
-
- gBS->SetTimer (TimerEvent, TimerCancel, 0);
- gBS->CloseEvent (TimerEvent);
-
- return StallCounter / RttTimerTick;
-}
-
-/**
- Initialize the timer event for RTT (round trip time).
-
- @param[in] Private The pointer to PING6_PRIVATE_DATA.
-
- @retval EFI_SUCCESS RTT timer is started.
- @retval Others Failed to start the RTT timer.
-
-**/
-EFI_STATUS
-Ping6InitRttTimer (
- IN PING6_PRIVATE_DATA *Private
- )
-{
- EFI_STATUS Status;
-
- Private->TimerPeriod = Ping6GetTimerPeriod ();
- if (Private->TimerPeriod == 0) {
- return EFI_ABORTED;
- }
-
- Private->RttTimerTick = 0;
- Status = gBS->CreateEvent (
- EVT_TIMER | EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- Ping6RttTimerTickRoutine,
- &Private->RttTimerTick,
- &Private->RttTimer
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = gBS->SetTimer (
- Private->RttTimer,
- TimerPeriodic,
- TICKS_PER_MS
- );
- if (EFI_ERROR (Status)) {
- gBS->CloseEvent (Private->RttTimer);
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Free RTT timer event resource.
-
- @param[in] Private The pointer to PING6_PRIVATE_DATA.
-
-**/
-VOID
-Ping6FreeRttTimer (
- IN PING6_PRIVATE_DATA *Private
- )
-{
- if (Private->RttTimer != NULL) {
- gBS->SetTimer (Private->RttTimer, TimerCancel, 0);
- gBS->CloseEvent (Private->RttTimer);
- }
-}
-
-/**
- Read the current time.
-
- @param[in] Private The pointer to PING6_PRIVATE_DATA.
-
- @retval the current tick value.
-**/
-UINT32
-Ping6ReadTime (
- IN PING6_PRIVATE_DATA *Private
- )
-{
- return Private->RttTimerTick;
-}
-
-/**
- Get and calculate the duration in ms.
-
- @param[in] Private The pointer to PING6_PRIVATE_DATA.
- @param[in] Begin The start point of time.
- @param[in] End The end point of time.
-
- @return The duration in ms.
-
-**/
-UINT32
-Ping6CalculateTick (
- IN PING6_PRIVATE_DATA *Private,
- IN UINT32 Begin,
- IN UINT32 End
- )
-{
- if (End < Begin) {
- return (0);
- }
-
- return (End - Begin) * Private->TimerPeriod;
-}
-
-/**
- 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
-Ping6OnMatchEchoReply (
- 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 routine.
-
- @param[in] Event A EFI_EVENT type event.
- @param[in] Context The pointer to Context.
-
-**/
-VOID
-EFIAPI
-Ping6OnEchoRequestSent6 (
- 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
-Ping6OnEchoReplyReceived6 (
- 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;
-
- 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 = Ping6OnMatchEchoReply (Private, Reply);
- if (EFI_ERROR (Status)) {
- goto ON_EXIT;
- }
-
- //
- // Display statistics on this icmp6 echo reply packet.
- //
- Rtt = Ping6CalculateTick (Private, Reply->TimeStamp, Ping6ReadTime (Private));
-
- 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),
- gShellNetwork2HiiHandle,
- PayLoad,
- mIp6DstString,
- Reply->SequenceNum,
- RxData->Header->HopLimit,
- Rtt,
- Rtt + Private->TimerPeriod
- );
-
-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)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_RECEIVE), gShellNetwork2HiiHandle, 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 UINT32 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,
- Ping6OnEchoRequestSent6,
- 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 = Ping6ReadTime (Private);
- 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
-Ping6OnReceiveEchoReply (
- IN PING6_PRIVATE_DATA *Private
- )
-{
- EFI_STATUS Status;
-
- ZeroMem (&Private->RxToken, sizeof (EFI_IP6_COMPLETION_TOKEN));
-
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- Ping6OnEchoReplyReceived6,
- Private,
- &Private->RxToken.Event
- );
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Private->RxToken.Status = EFI_NOT_READY;
-
- Status = Private->Ip6->Receive (Private->Ip6, &Private->RxToken);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_RECEIVE), gShellNetwork2HiiHandle, Status);
- }
-
- return Status;
-}
-
-/**
- Remove the timeout request from the list.
-
- @param[in] Event A EFI_EVENT type event.
- @param[in] Context The pointer to Context.
-
-**/
-VOID
-EFIAPI
-Ping6OnTimerRoutine6 (
- 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;
- UINT64 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), gShellNetwork2HiiHandle, 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 (Private, TxInfo->TimeStamp, Ping6ReadTime (Private));
-
- //
- // 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), gShellNetwork2HiiHandle, 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
-Ping6CreateIpInstance (
- IN PING6_PRIVATE_DATA *Private
- )
-{
- EFI_STATUS Status;
- UINTN HandleIndex;
- UINTN HandleNum;
- EFI_HANDLE *HandleBuffer;
- BOOLEAN UnspecifiedSrc;
- EFI_STATUS MediaStatus;
- 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;
- UnspecifiedSrc = FALSE;
- MediaStatus = EFI_SUCCESS;
- 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;
- }
-
- if (NetIp6IsUnspecifiedAddr (&Private->SrcAddress)) {
- //
- // SrcAddress is unspecified. So, both connected and configured interface will be automatic selected.
- //
- UnspecifiedSrc = TRUE;
- }
-
- //
- // Source address is required when pinging a link-local address.
- //
- if (NetIp6IsLinkLocalAddr (&Private->DstAddress) && UnspecifiedSrc) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SOURCE), gShellNetwork2HiiHandle);
- 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;
-
- if (UnspecifiedSrc) {
- //
- // Check media.
- //
- NetLibDetectMediaWaitTimeout (HandleBuffer[HandleIndex], 0, &MediaStatus);
- if (MediaStatus != EFI_SUCCESS) {
- //
- // Skip this one.
- //
- continue;
- }
- }
-
- Status = gBS->HandleProtocol (
- HandleBuffer[HandleIndex],
- &gEfiIp6ServiceBindingProtocolGuid,
- (VOID **)&Ip6Sb
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
-
- //
- // 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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 (UnspecifiedSrc) {
- if (!NetIp6IsUnspecifiedAddr (Addr) && !NetIp6IsLinkLocalAddr (Addr)) {
- //
- // Select the interface automatically.
- //
- CopyMem (&Private->SrcAddress, Addr, sizeof (Private->SrcAddress));
- break;
- }
- } else 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_CONFIGD_NIC_NF), gShellNetwork2HiiHandle);
- 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), gShellNetwork2HiiHandle, 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;
-}
-
-/**
- Destroy the IP6 instance.
-
- @param[in] Private The pointer of PING6_PRIVATE_DATA.
-
-**/
-VOID
-Ping6DestroyIpInstance (
- 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 SHELL_SUCCESS The ping6 processed successfullly.
- @retval others The ping6 processed unsuccessfully.
-
-**/
-SHELL_STATUS
-ShellPing6 (
- 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;
- SHELL_STATUS ShellStatus;
-
- ShellStatus = SHELL_SUCCESS;
- Private = AllocateZeroPool (sizeof (PING6_PRIVATE_DATA));
-
- if (Private == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"Ping6");
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto ON_EXIT;
- }
-
- Private->ImageHandle = ImageHandle;
- Private->SendNum = SendNumber;
- Private->BufferSize = BufferSize;
- Private->RttMin = ~((UINT64)(0x0));
- 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 = Ping6CreateIpInstance (Private);
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
-
- //
- // Print the command line itself.
- //
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_START), gShellNetwork2HiiHandle, mIp6DstString, Private->BufferSize);
- //
- // Create a ipv6 token to receive the first icmp6 echo reply packet.
- //
- Status = Ping6OnReceiveEchoReply (Private);
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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,
- Ping6OnTimerRoutine6,
- Private,
- &Private->Timer
- );
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- goto ON_EXIT;
- }
-
- //
- // Start a timer to calculate the RTT.
- //
- Status = Ping6InitRttTimer (Private);
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- if (Status == EFI_NOT_FOUND) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_NOSOURCE_INDOMAIN), gShellNetwork2HiiHandle, mIp6DstString);
- }
-
- goto ON_EXIT;
- }
-
- Status = gBS->SetTimer (
- Private->Timer,
- TimerPeriodic,
- PING6_ONE_SECOND
- );
-
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_ACCESS_DENIED;
- 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),
- gShellNetwork2HiiHandle,
- 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),
- gShellNetwork2HiiHandle,
- Private->RttMin,
- Private->RttMin + Private->TimerPeriod,
- Private->RttMax,
- Private->RttMax + Private->TimerPeriod,
- DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL),
- DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL) + Private->TimerPeriod
- );
- }
-
-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);
- }
-
- Ping6FreeRttTimer (Private);
-
- 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) {
- Ping6DestroyIpInstance (Private);
- }
-
- FreePool (Private);
- }
-
- return ShellStatus;
-}
-
-/**
- Function for 'ping6' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @retval SHELL_SUCCESS The ping6 processed successfullly.
- @retval others The ping6 processed unsuccessfully.
-
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunPing6 (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
- EFI_IPv6_ADDRESS DstAddress;
- EFI_IPv6_ADDRESS SrcAddress;
- UINT64 BufferSize;
- UINTN SendNumber;
- LIST_ENTRY *ParamPackage;
- CONST CHAR16 *ValueStr;
- CONST CHAR16 *ValueStrPtr;
- UINTN NonOptionCount;
- CHAR16 *ProblemParam;
-
- ProblemParam = NULL;
- ShellStatus = SHELL_SUCCESS;
-
- Status = ShellCommandLineParseEx (Ping6ParamList, &ParamPackage, &ProblemParam, TRUE, FALSE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), gShellNetwork2HiiHandle);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
-
- SendNumber = 10;
- BufferSize = 16;
-
- //
- // Parse the parameter 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), gShellNetwork2HiiHandle, ValueStr);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
- }
-
- //
- // Parse the parameter 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), gShellNetwork2HiiHandle, ValueStr);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
- }
-
- ZeroMem (&SrcAddress, sizeof (EFI_IPv6_ADDRESS));
- ZeroMem (&DstAddress, sizeof (EFI_IPv6_ADDRESS));
-
- //
- // Parse the parameter 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), gShellNetwork2HiiHandle, ValueStr);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
- }
-
- //
- // Parse the parameter of destination ip address.
- //
- NonOptionCount = ShellCommandLineGetCount (ParamPackage);
- ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32)(NonOptionCount-1));
- if (NonOptionCount != 2) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), gShellNetwork2HiiHandle);
- ShellStatus = SHELL_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), gShellNetwork2HiiHandle, ValueStr);
- ShellStatus = SHELL_INVALID_PARAMETER;
- goto ON_EXIT;
- }
- }
-
- //
- // Enter into ping6 process.
- //
- ShellStatus = ShellPing6 (
- ImageHandle,
- (UINT32)SendNumber,
- (UINT32)BufferSize,
- &SrcAddress,
- &DstAddress
- );
-
-ON_EXIT:
- ShellCommandLineFreeVarList (ParamPackage);
- return ShellStatus;
-}
+/** @file
+ The implementation for Ping6 application.
+
+ Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UefiShellNetwork2CommandsLib.h"
+
+#define PING6_DEFAULT_TIMEOUT 5000
+#define PING6_MAX_SEND_NUMBER 10000
+#define PING6_MAX_BUFFER_SIZE 32768
+#define PING6_ONE_SECOND 10000000
+#define STALL_1_MILLI_SECOND 1000
+
+#pragma pack(1)
+
+typedef struct _ICMP6_ECHO_REQUEST_REPLY {
+ UINT8 Type;
+ UINT8 Code;
+ UINT16 Checksum;
+ UINT16 Identifier;
+ UINT16 SequenceNum;
+ UINT32 TimeStamp;
+ UINT8 Data[1];
+} ICMP6_ECHO_REQUEST_REPLY;
+
+#pragma pack()
+
+typedef struct _PING6_ICMP6_TX_INFO {
+ LIST_ENTRY Link;
+ UINT16 SequenceNum;
+ UINT32 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;
+
+ UINT32 TimerPeriod;
+ UINT32 RttTimerTick;
+ EFI_EVENT RttTimer;
+
+ EFI_STATUS Status;
+ LIST_ENTRY TxList;
+ EFI_IP6_COMPLETION_TOKEN RxToken;
+ UINT16 RxCount;
+ UINT16 TxCount;
+ UINT64 RttSum;
+ UINT64 RttMin;
+ UINT64 RttMax;
+ UINT32 SequenceNum;
+
+ EFI_IPv6_ADDRESS SrcAddress;
+ EFI_IPv6_ADDRESS DstAddress;
+ UINT32 SendNum;
+ UINT32 BufferSize;
+} PING6_PRIVATE_DATA;
+
+SHELL_PARAM_ITEM Ping6ParamList[] = {
+ {
+ L"-l",
+ TypeValue
+ },
+ {
+ L"-n",
+ TypeValue
+ },
+ {
+ L"-s",
+ TypeValue
+ },
+ {
+ L"-?",
+ TypeFlag
+ },
+ {
+ NULL,
+ TypeMax
+ },
+};
+
+//
+// Global Variables in Ping6 application.
+//
+CONST CHAR16 *mIp6DstString;
+CONST CHAR16 *mIp6SrcString;
+EFI_CPU_ARCH_PROTOCOL *Cpu = NULL;
+
+/**
+ RTT timer tick routine.
+
+ @param[in] Event A EFI_EVENT type event.
+ @param[in] Context The pointer to Context.
+
+**/
+VOID
+EFIAPI
+Ping6RttTimerTickRoutine (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINT32 *RttTimerTick;
+
+ RttTimerTick = (UINT32 *)Context;
+ (*RttTimerTick)++;
+}
+
+/**
+ Get the timer period of the system.
+
+ This function tries to get the system timer period by creating
+ an 1ms period timer.
+
+ @return System timer period in MS, or 0 if operation failed.
+
+**/
+UINT32
+Ping6GetTimerPeriod (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 RttTimerTick;
+ EFI_EVENT TimerEvent;
+ UINT32 StallCounter;
+ EFI_TPL OldTpl;
+
+ RttTimerTick = 0;
+ StallCounter = 0;
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ Ping6RttTimerTickRoutine,
+ &RttTimerTick,
+ &TimerEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return 0;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+ Status = gBS->SetTimer (
+ TimerEvent,
+ TimerPeriodic,
+ TICKS_PER_MS
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseEvent (TimerEvent);
+ return 0;
+ }
+
+ while (RttTimerTick < 10) {
+ gBS->Stall (STALL_1_MILLI_SECOND);
+ ++StallCounter;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ gBS->SetTimer (TimerEvent, TimerCancel, 0);
+ gBS->CloseEvent (TimerEvent);
+
+ return StallCounter / RttTimerTick;
+}
+
+/**
+ Initialize the timer event for RTT (round trip time).
+
+ @param[in] Private The pointer to PING6_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS RTT timer is started.
+ @retval Others Failed to start the RTT timer.
+
+**/
+EFI_STATUS
+Ping6InitRttTimer (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ Private->TimerPeriod = Ping6GetTimerPeriod ();
+ if (Private->TimerPeriod == 0) {
+ return EFI_ABORTED;
+ }
+
+ Private->RttTimerTick = 0;
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ Ping6RttTimerTickRoutine,
+ &Private->RttTimerTick,
+ &Private->RttTimer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->SetTimer (
+ Private->RttTimer,
+ TimerPeriodic,
+ TICKS_PER_MS
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseEvent (Private->RttTimer);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Free RTT timer event resource.
+
+ @param[in] Private The pointer to PING6_PRIVATE_DATA.
+
+**/
+VOID
+Ping6FreeRttTimer (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ if (Private->RttTimer != NULL) {
+ gBS->SetTimer (Private->RttTimer, TimerCancel, 0);
+ gBS->CloseEvent (Private->RttTimer);
+ }
+}
+
+/**
+ Read the current time.
+
+ @param[in] Private The pointer to PING6_PRIVATE_DATA.
+
+ @retval the current tick value.
+**/
+UINT32
+Ping6ReadTime (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ return Private->RttTimerTick;
+}
+
+/**
+ Get and calculate the duration in ms.
+
+ @param[in] Private The pointer to PING6_PRIVATE_DATA.
+ @param[in] Begin The start point of time.
+ @param[in] End The end point of time.
+
+ @return The duration in ms.
+
+**/
+UINT32
+Ping6CalculateTick (
+ IN PING6_PRIVATE_DATA *Private,
+ IN UINT32 Begin,
+ IN UINT32 End
+ )
+{
+ if (End < Begin) {
+ return (0);
+ }
+
+ return (End - Begin) * Private->TimerPeriod;
+}
+
+/**
+ 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
+Ping6OnMatchEchoReply (
+ 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 routine.
+
+ @param[in] Event A EFI_EVENT type event.
+ @param[in] Context The pointer to Context.
+
+**/
+VOID
+EFIAPI
+Ping6OnEchoRequestSent6 (
+ 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
+Ping6OnEchoReplyReceived6 (
+ 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;
+
+ 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 = Ping6OnMatchEchoReply (Private, Reply);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Display statistics on this icmp6 echo reply packet.
+ //
+ Rtt = Ping6CalculateTick (Private, Reply->TimeStamp, Ping6ReadTime (Private));
+
+ 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),
+ gShellNetwork2HiiHandle,
+ PayLoad,
+ mIp6DstString,
+ Reply->SequenceNum,
+ RxData->Header->HopLimit,
+ Rtt,
+ Rtt + Private->TimerPeriod
+ );
+
+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)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_RECEIVE), gShellNetwork2HiiHandle, 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 UINT32 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,
+ Ping6OnEchoRequestSent6,
+ 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 = Ping6ReadTime (Private);
+ 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
+Ping6OnReceiveEchoReply (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ ZeroMem (&Private->RxToken, sizeof (EFI_IP6_COMPLETION_TOKEN));
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ Ping6OnEchoReplyReceived6,
+ Private,
+ &Private->RxToken.Event
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Private->RxToken.Status = EFI_NOT_READY;
+
+ Status = Private->Ip6->Receive (Private->Ip6, &Private->RxToken);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_RECEIVE), gShellNetwork2HiiHandle, Status);
+ }
+
+ return Status;
+}
+
+/**
+ Remove the timeout request from the list.
+
+ @param[in] Event A EFI_EVENT type event.
+ @param[in] Context The pointer to Context.
+
+**/
+VOID
+EFIAPI
+Ping6OnTimerRoutine6 (
+ 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;
+ UINT64 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), gShellNetwork2HiiHandle, 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 (Private, TxInfo->TimeStamp, Ping6ReadTime (Private));
+
+ //
+ // 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), gShellNetwork2HiiHandle, 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
+Ping6CreateIpInstance (
+ IN PING6_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleIndex;
+ UINTN HandleNum;
+ EFI_HANDLE *HandleBuffer;
+ BOOLEAN UnspecifiedSrc;
+ EFI_STATUS MediaStatus;
+ 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;
+ UnspecifiedSrc = FALSE;
+ MediaStatus = EFI_SUCCESS;
+ 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;
+ }
+
+ if (NetIp6IsUnspecifiedAddr (&Private->SrcAddress)) {
+ //
+ // SrcAddress is unspecified. So, both connected and configured interface will be automatic selected.
+ //
+ UnspecifiedSrc = TRUE;
+ }
+
+ //
+ // Source address is required when pinging a link-local address.
+ //
+ if (NetIp6IsLinkLocalAddr (&Private->DstAddress) && UnspecifiedSrc) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SOURCE), gShellNetwork2HiiHandle);
+ 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;
+
+ if (UnspecifiedSrc) {
+ //
+ // Check media.
+ //
+ NetLibDetectMediaWaitTimeout (HandleBuffer[HandleIndex], 0, &MediaStatus);
+ if (MediaStatus != EFI_SUCCESS) {
+ //
+ // Skip this one.
+ //
+ continue;
+ }
+ }
+
+ Status = gBS->HandleProtocol (
+ HandleBuffer[HandleIndex],
+ &gEfiIp6ServiceBindingProtocolGuid,
+ (VOID **)&Ip6Sb
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // 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), gShellNetwork2HiiHandle, 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), gShellNetwork2HiiHandle, 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 (UnspecifiedSrc) {
+ if (!NetIp6IsUnspecifiedAddr (Addr) && !NetIp6IsLinkLocalAddr (Addr)) {
+ //
+ // Select the interface automatically.
+ //
+ CopyMem (&Private->SrcAddress, Addr, sizeof (Private->SrcAddress));
+ break;
+ }
+ } else 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_CONFIGD_NIC_NF), gShellNetwork2HiiHandle);
+ 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), gShellNetwork2HiiHandle, 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;
+}
+
+/**
+ Destroy the IP6 instance.
+
+ @param[in] Private The pointer of PING6_PRIVATE_DATA.
+
+**/
+VOID
+Ping6DestroyIpInstance (
+ 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 SHELL_SUCCESS The ping6 processed successfullly.
+ @retval others The ping6 processed unsuccessfully.
+
+**/
+SHELL_STATUS
+ShellPing6 (
+ 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;
+ SHELL_STATUS ShellStatus;
+
+ ShellStatus = SHELL_SUCCESS;
+ Private = AllocateZeroPool (sizeof (PING6_PRIVATE_DATA));
+
+ if (Private == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"Ping6");
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Private->ImageHandle = ImageHandle;
+ Private->SendNum = SendNumber;
+ Private->BufferSize = BufferSize;
+ Private->RttMin = ~((UINT64)(0x0));
+ 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 = Ping6CreateIpInstance (Private);
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Print the command line itself.
+ //
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_START), gShellNetwork2HiiHandle, mIp6DstString, Private->BufferSize);
+ //
+ // Create a ipv6 token to receive the first icmp6 echo reply packet.
+ //
+ Status = Ping6OnReceiveEchoReply (Private);
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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,
+ Ping6OnTimerRoutine6,
+ Private,
+ &Private->Timer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Start a timer to calculate the RTT.
+ //
+ Status = Ping6InitRttTimer (Private);
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ if (Status == EFI_NOT_FOUND) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_NOSOURCE_INDOMAIN), gShellNetwork2HiiHandle, mIp6DstString);
+ }
+
+ goto ON_EXIT;
+ }
+
+ Status = gBS->SetTimer (
+ Private->Timer,
+ TimerPeriodic,
+ PING6_ONE_SECOND
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_ACCESS_DENIED;
+ 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),
+ gShellNetwork2HiiHandle,
+ 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),
+ gShellNetwork2HiiHandle,
+ Private->RttMin,
+ Private->RttMin + Private->TimerPeriod,
+ Private->RttMax,
+ Private->RttMax + Private->TimerPeriod,
+ DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL),
+ DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL) + Private->TimerPeriod
+ );
+ }
+
+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);
+ }
+
+ Ping6FreeRttTimer (Private);
+
+ 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) {
+ Ping6DestroyIpInstance (Private);
+ }
+
+ FreePool (Private);
+ }
+
+ return ShellStatus;
+}
+
+/**
+ Function for 'ping6' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+
+ @retval SHELL_SUCCESS The ping6 processed successfullly.
+ @retval others The ping6 processed unsuccessfully.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunPing6 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus;
+ EFI_IPv6_ADDRESS DstAddress;
+ EFI_IPv6_ADDRESS SrcAddress;
+ UINT64 BufferSize;
+ UINTN SendNumber;
+ LIST_ENTRY *ParamPackage;
+ CONST CHAR16 *ValueStr;
+ CONST CHAR16 *ValueStrPtr;
+ UINTN NonOptionCount;
+ CHAR16 *ProblemParam;
+
+ ProblemParam = NULL;
+ ShellStatus = SHELL_SUCCESS;
+
+ Status = ShellCommandLineParseEx (Ping6ParamList, &ParamPackage, &ProblemParam, TRUE, FALSE);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), gShellNetwork2HiiHandle);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ SendNumber = 10;
+ BufferSize = 16;
+
+ //
+ // Parse the parameter 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), gShellNetwork2HiiHandle, ValueStr);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Parse the parameter 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), gShellNetwork2HiiHandle, ValueStr);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+
+ ZeroMem (&SrcAddress, sizeof (EFI_IPv6_ADDRESS));
+ ZeroMem (&DstAddress, sizeof (EFI_IPv6_ADDRESS));
+
+ //
+ // Parse the parameter 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), gShellNetwork2HiiHandle, ValueStr);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Parse the parameter of destination ip address.
+ //
+ NonOptionCount = ShellCommandLineGetCount (ParamPackage);
+ ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32)(NonOptionCount-1));
+ if (NonOptionCount != 2) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), gShellNetwork2HiiHandle);
+ ShellStatus = SHELL_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), gShellNetwork2HiiHandle, ValueStr);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+ }
+
+ //
+ // Enter into ping6 process.
+ //
+ ShellStatus = ShellPing6 (
+ ImageHandle,
+ (UINT32)SendNumber,
+ (UINT32)BufferSize,
+ &SrcAddress,
+ &DstAddress
+ );
+
+ON_EXIT:
+ ShellCommandLineFreeVarList (ParamPackage);
+ return ShellStatus;
+}
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c
index 20445ca4af..139cbf94a0 100644
--- a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c
+++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.c
@@ -1,86 +1,86 @@
-/** @file
- Main file for NULL named library for network2 shell command functions.
-
- Copyright (c) 2016, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "UefiShellNetwork2CommandsLib.h"
-
-CONST CHAR16 gShellNetwork2FileName[] = L"ShellCommands";
-EFI_HII_HANDLE gShellNetwork2HiiHandle = NULL;
-
-/**
- return the file name of the help text file if not using HII.
-
- @return The string pointer to the file name.
-**/
-CONST CHAR16 *
-EFIAPI
-ShellCommandGetManFileNameNetwork2 (
- VOID
- )
-{
- return (gShellNetwork2FileName);
-}
-
-/**
- Constructor for the Shell Network2 Commands library.
-
- Install the handlers for Network2 UEFI Shell 2.0 profile commands.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-
- @retval EFI_SUCCESS The shell command handlers were installed successfully.
- @retval EFI_UNSUPPORTED The shell level required was not found.
-**/
-EFI_STATUS
-EFIAPI
-ShellNetwork2CommandsLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- gShellNetwork2HiiHandle = NULL;
-
- //
- // check our bit of the profiles mask
- //
- if ((PcdGet8 (PcdShellProfileMask) & BIT4) == 0) {
- return (EFI_SUCCESS);
- }
-
- gShellNetwork2HiiHandle = HiiAddPackages (&gShellNetwork2HiiGuid, gImageHandle, UefiShellNetwork2CommandsLibStrings, NULL);
- if (gShellNetwork2HiiHandle == NULL) {
- return (EFI_DEVICE_ERROR);
- }
-
- //
- // install our shell command handlers
- //
- ShellCommandRegisterCommandName (L"ping6", ShellCommandRunPing6, ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE, gShellNetwork2HiiHandle, STRING_TOKEN (STR_GET_HELP_PING6));
- ShellCommandRegisterCommandName (L"ifconfig6", ShellCommandRunIfconfig6, ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE, gShellNetwork2HiiHandle, STRING_TOKEN (STR_GET_HELP_IFCONFIG6));
-
- return EFI_SUCCESS;
-}
-
-/**
- Destructor for the library. free any resources.
-
- @param ImageHandle The image handle of the process.
- @param SystemTable The EFI System Table pointer.
-**/
-EFI_STATUS
-EFIAPI
-ShellNetwork2CommandsLibDestructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- if (gShellNetwork2HiiHandle != NULL) {
- HiiRemovePackages (gShellNetwork2HiiHandle);
- }
-
- return EFI_SUCCESS;
-}
+/** @file
+ Main file for NULL named library for network2 shell command functions.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved. <BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "UefiShellNetwork2CommandsLib.h"
+
+CONST CHAR16 gShellNetwork2FileName[] = L"ShellCommands";
+EFI_HII_HANDLE gShellNetwork2HiiHandle = NULL;
+
+/**
+ return the file name of the help text file if not using HII.
+
+ @return The string pointer to the file name.
+**/
+CONST CHAR16 *
+EFIAPI
+ShellCommandGetManFileNameNetwork2 (
+ VOID
+ )
+{
+ return (gShellNetwork2FileName);
+}
+
+/**
+ Constructor for the Shell Network2 Commands library.
+
+ Install the handlers for Network2 UEFI Shell 2.0 profile commands.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS The shell command handlers were installed successfully.
+ @retval EFI_UNSUPPORTED The shell level required was not found.
+**/
+EFI_STATUS
+EFIAPI
+ShellNetwork2CommandsLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ gShellNetwork2HiiHandle = NULL;
+
+ //
+ // check our bit of the profiles mask
+ //
+ if ((PcdGet8 (PcdShellProfileMask) & BIT4) == 0) {
+ return (EFI_SUCCESS);
+ }
+
+ gShellNetwork2HiiHandle = HiiAddPackages (&gShellNetwork2HiiGuid, gImageHandle, UefiShellNetwork2CommandsLibStrings, NULL);
+ if (gShellNetwork2HiiHandle == NULL) {
+ return (EFI_DEVICE_ERROR);
+ }
+
+ //
+ // install our shell command handlers
+ //
+ ShellCommandRegisterCommandName (L"ping6", ShellCommandRunPing6, ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE, gShellNetwork2HiiHandle, STRING_TOKEN (STR_GET_HELP_PING6));
+ ShellCommandRegisterCommandName (L"ifconfig6", ShellCommandRunIfconfig6, ShellCommandGetManFileNameNetwork2, 0, L"network2", TRUE, gShellNetwork2HiiHandle, STRING_TOKEN (STR_GET_HELP_IFCONFIG6));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Destructor for the library. free any resources.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+**/
+EFI_STATUS
+EFIAPI
+ShellNetwork2CommandsLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (gShellNetwork2HiiHandle != NULL) {
+ HiiRemovePackages (gShellNetwork2HiiHandle);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h
index 9feab2578d..06da737505 100644
--- a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h
+++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.h
@@ -1,66 +1,66 @@
-/** @file
- Main file for NULL named library for network2 shell command functions.
-
- Copyright (c) 2016, Intel Corporation. All rights reserved. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_
-#define _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_
-
-#include <Protocol/Cpu.h>
-#include <Protocol/ServiceBinding.h>
-#include <Protocol/Ip6.h>
-#include <Protocol/Ip6Config.h>
-
-#include <Guid/ShellLibHiiGuid.h>
-
-#include <Library/ShellLib.h>
-#include <Library/ShellCommandLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PcdLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/HiiLib.h>
-#include <Library/NetLib.h>
-
-extern EFI_HII_HANDLE gShellNetwork2HiiHandle;
-
-/**
- Function for 'ping6' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @retval SHELL_SUCCESS The ping6 processed successfullly.
- @retval others The ping6 processed unsuccessfully.
-
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunPing6 (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-/**
- Function for 'ifconfig6' command.
-
- @param[in] ImageHandle Handle to the Image (NULL if Internal).
- @param[in] SystemTable Pointer to the System Table (NULL if Internal).
-
- @retval SHELL_SUCCESS The ifconfig6 command processed successfully.
- @retval others The ifconfig6 command process failed.
-
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunIfconfig6 (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-#endif
+/** @file
+ Main file for NULL named library for network2 shell command functions.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved. <BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_
+#define _UEFI_SHELL_NETWORK2_COMMANDS_LIB_H_
+
+#include <Protocol/Cpu.h>
+#include <Protocol/ServiceBinding.h>
+#include <Protocol/Ip6.h>
+#include <Protocol/Ip6Config.h>
+
+#include <Guid/ShellLibHiiGuid.h>
+
+#include <Library/ShellLib.h>
+#include <Library/ShellCommandLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HiiLib.h>
+#include <Library/NetLib.h>
+
+extern EFI_HII_HANDLE gShellNetwork2HiiHandle;
+
+/**
+ Function for 'ping6' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+
+ @retval SHELL_SUCCESS The ping6 processed successfullly.
+ @retval others The ping6 processed unsuccessfully.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunPing6 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Function for 'ifconfig6' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+
+ @retval SHELL_SUCCESS The ifconfig6 command processed successfully.
+ @retval others The ifconfig6 command process failed.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunIfconfig6 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
index 9ffcf85248..7b984d51a7 100644
--- a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
@@ -1,60 +1,60 @@
-## @file
-# Provides shell network2 functions
-#
-# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved. <BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010006
- BASE_NAME = UefiShellNetwork2CommandsLib
- FILE_GUID = D94E3B82-908E-46bf-A7B9-C7B7F17B1B7D
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 1.0
- LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
- CONSTRUCTOR = ShellNetwork2CommandsLibConstructor
- DESTRUCTOR = ShellNetwork2CommandsLibDestructor
-
-[Sources.common]
- UefiShellNetwork2CommandsLib.uni
- UefiShellNetwork2CommandsLib.c
- UefiShellNetwork2CommandsLib.h
- Ping6.c
- Ifconfig6.c
-
-[Packages]
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- NetworkPkg/NetworkPkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- BaseMemoryLib
- DebugLib
- ShellCommandLib
- ShellLib
- UefiLib
- UefiRuntimeServicesTableLib
- UefiBootServicesTableLib
- PcdLib
- HiiLib
- FileHandleLib
- NetLib
-
-[Pcd]
- gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES
-
-[Protocols]
- gEfiCpuArchProtocolGuid ## CONSUMES
- gEfiTimerArchProtocolGuid ## CONSUMES
- gEfiIp6ProtocolGuid ## SOMETIMES_CONSUMES
- gEfiIp6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
- gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
-
-[Guids]
- gShellNetwork2HiiGuid ## SOMETIMES_CONSUMES ## HII
+## @file
+# Provides shell network2 functions
+#
+# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = UefiShellNetwork2CommandsLib
+ FILE_GUID = D94E3B82-908E-46bf-A7B9-C7B7F17B1B7D
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
+ CONSTRUCTOR = ShellNetwork2CommandsLibConstructor
+ DESTRUCTOR = ShellNetwork2CommandsLibDestructor
+
+[Sources.common]
+ UefiShellNetwork2CommandsLib.uni
+ UefiShellNetwork2CommandsLib.c
+ UefiShellNetwork2CommandsLib.h
+ Ping6.c
+ Ifconfig6.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ ShellCommandLib
+ ShellLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ PcdLib
+ HiiLib
+ FileHandleLib
+ NetLib
+
+[Pcd]
+ gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES
+
+[Protocols]
+ gEfiCpuArchProtocolGuid ## CONSUMES
+ gEfiTimerArchProtocolGuid ## CONSUMES
+ gEfiIp6ProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiIp6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gShellNetwork2HiiGuid ## SOMETIMES_CONSUMES ## HII
diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni
index cb9d39a33f..18266f4c33 100644
--- a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni
+++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.uni
@@ -1,160 +1,160 @@
-/** @file
-
- String definitions for UEFI Shell network 2 commands
- Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
- (C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- Module Name:
-
- UefiShellNetwork2CommandsLib.uni
-
- Abstract:
-
- String definitions for UEFI Shell 2.0 network 2 commands
-**/
-
-#langdef en-US "english"
-
-#string STR_GEN_ERR_AD #language en-US "%H%s%N: Access denied.\r\n"
-#string STR_GEN_OUT_MEM #language en-US "%H%s%N: Memory allocation was not successful.\r\n"
-
-#string STR_PING6_INVALID_IP #language en-US "%Ping6: Invalid IP6 address, %s\r\n"
-#string STR_PING6_INVALID_INPUT #language en-US "%Ping6: Invalid input, please type 'Ping6 -?'for help\r\n"
-#string STR_PING6_INVALID_SEND_NUMBER #language en-US "%Ping6: Invalid send number, %s\r\n"
-#string STR_PING6_INVALID_BUFFER_SIZE #language en-US "%Ping6: Invalid buffer size, %s\r\n"
-#string STR_PING6_INVALID_SOURCE #language en-US "%Ping6: Require source interface option\r\n"
-#string STR_PING6_IP6_CONFIG #language en-US "%Ping6: The process of Ip6 Configure %r\r\n"
-#string STR_PING6_IP6_RECEIVE #language en-US "%Ping6: Place the receive token %r\r\n"
-#string STR_PING6_IP6CFG_GETDATA #language en-US "%Ping6: Get data of the interface information %r\r\n"
-#string STR_PING6_SEND_REQUEST #language en-US "Echo request sequence %d fails.\r\n"
-#string STR_PING6_CONFIGD_NIC_NF #language en-US "%Ping6: No configured interfaces were found.\r\n"
-#string STR_PING6_NOSOURCE_INDOMAIN #language en-US "No sources in %s's multicast domain.\r\n"
-#string STR_PING6_START #language en-US "Ping %s %d data bytes\r\n"
-#string STR_PING6_TIMEOUT #language en-US "Echo request sequence %d timeout.\r\n"
-#string STR_PING6_REPLY_INFO #language en-US "%d bytes from %s : icmp_seq=%d ttl=%d time=%d~%dms\r\n"
-#string STR_PING6_STAT #language en-US "\n%d packets transmitted, %d received, %d%% packet loss, time %dms\r\n"
-#string STR_PING6_RTT #language en-US "\nRtt(round trip time) min=%d~%dms max=%d~%dms avg=%d~%dms\r\n"
-
-#string STR_IFCONFIG6_ERR_IP6CFG_GETDATA #language en-US "Get data of the interface information %hr\r\n"
-#string STR_IFCONFIG6_INFO_BREAK #language en-US "-----------------------------------------------------------------"
-#string STR_IFCONFIG6_INFO_COLON #language en-US ":"
-#string STR_IFCONFIG6_INFO_JOINT #language en-US " >> "
-#string STR_IFCONFIG6_INFO_NEWLINE #language en-US "\r\n"
-#string STR_IFCONFIG6_INFO_IF_NAME #language en-US "\n%Hname : %s%N\r\n"
-#string STR_IFCONFIG6_INFO_POLICY_AUTO #language en-US "%Hpolicy : automatic%N\r\n"
-#string STR_IFCONFIG6_INFO_POLICY_MAN #language en-US "%Hpolicy : manual%N\r\n"
-#string STR_IFCONFIG6_INFO_DAD_TRANSMITS #language en-US "%Hdad xmits : %d%N\r\n"
-#string STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD #language en-US "%Hinterface id : %N"
-#string STR_IFCONFIG6_INFO_MAC_ADDR_HEAD #language en-US "%Hmac addr : %N"
-#string STR_IFCONFIG6_INFO_MAC_ADDR_BODY #language en-US "%02x"
-#string STR_IFCONFIG6_INFO_IP_ADDR_HEAD #language en-US "\n%Hhost addr : %N\r\n"
-#string STR_IFCONFIG6_INFO_DNS_ADDR_HEAD #language en-US "\n%Hdns server : %N\r\n"
-#string STR_IFCONFIG6_INFO_IP_ADDR_BODY #language en-US "%02x"
-#string STR_IFCONFIG6_INFO_IP_ADDR_BODY4BIT #language en-US "%x"
-#string STR_IFCONFIG6_INFO_ROUTE_HEAD #language en-US "\n%Hroute table : %N\r\n"
-#string STR_IFCONFIG6_INFO_PREFIX_LEN #language en-US "/%d"
-#string STR_IFCONFIG6_LINE_HELP #language en-US "Displays or modifies the IPv6 configuration"
-#string STR_IFCONFIG6_ERR_LACK_INTERFACE #language en-US "Lack interface name.\r\n"
- "Usage: IfConfig6 -s <Name> \r\n"
- "Example: IfConfig6 -s eth0 auto\r\n"
-#string STR_IFCONFIG6_LACK_OPTION #language en-US "Flags lack. Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_CONFLICT_OPTIONS #language en-US "Flags conflict. Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_LACK_COMMAND #language en-US "Lack interface config option.\r\n"
- "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_INVALID_INTERFACE #language en-US "Invalid interface name.\r\n"
- "Hint: Use {IfConfig6 -l} to check existing interface names.\r\n"
-#string STR_IFCONFIG6_ERR_INVALID_COMMAND #language en-US "Invalid command. Bad command %H%s%N is skipped.\r\n"
- "Hint: Incorrect option or arguments. Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_LACK_ARGUMENTS #language en-US "Lack arguments. Bad command %H%s%N is skipped.\r\n"
- "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_LACK_OPTION #language en-US "Lack options.\r\n"
- "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_MAN_HOST #language en-US "Manual address configuration failed. Please retry.\r\n"
-
-#string STR_IFCONFIG6_ERR_MAN_GW #language en-US "Gateway address configuration failed. Please check the argument.\r\n"
-
-#string STR_IFCONFIG6_ERR_INVALID_IP_CONFIG #language en-US "The IP address is not configurable when the policy is Ip6ConfigPolicyAutomatic.\r\n"
-
-#string STR_IFCONFIG6_ERR_INVALID_GW_CONFIG #language en-US "The gateway address is not configurable when the policy is Ip6ConfigPolicyAutomatic.\r\n"
-
-#string STR_IFCONFIG6_ERR_INVALID_DNS_CONFIG #language en-US "The DNS server address is not configurable when the policy is Ip6ConfigPolicyAutomatic.\r\n"
-
-#string STR_IFCONFIG6_ERR_DUPLICATE_COMMAND #language en-US "Duplicate commands. Bad command %H%s%N is skipped.\r\n"
- "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_CONFLICT_COMMAND #language en-US "Conflict commands. Bad command %H%s%N is skipped.\r\n"
- "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_UNKNOWN_COMMAND #language en-US "Unknown commands. Bad command %H%s%N is skipped.\r\n"
- "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
-#string STR_IFCONFIG6_ERR_ADDRESS_FAILED #language en-US "Failed to configure IPv6 address: "
-
-
-#string STR_GET_HELP_PING6 #language en-US ""
-".TH ping6 0 "Ping a target machine with UEFI IPv6 network stack."\r\n"
-".SH NAME\r\n"
-"Ping a target machine with UEFI IPv6 network stack.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"Ping6 [-l size] [-n count] [-s SourceIp] TargetIp\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" -l size Send buffer size, in bytes(default=16, min=16, max=32768).\r\n"
-" -n count Send request count, (default=10, min=1, max=10000).\r\n"
-" -s SourceIp Source IPv6 address.\r\n"
-" TargetIp Target IPv6 address.\r\n"
-"NOTES:\r\n"
-" 1. When TargetIp is a link local address, SourceIp needs to be specified.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"Examples:\r\n"
-" * To ping the target host by sending 5 request with 1000 bytes from 2002::1\r\n"
-" Shell:\> Ping6 -s 2002::1 2002::2 -l 1000 -n 5\r\n"
-" \r\n"
-" * To ping the target host with 1000 bytes\r\n"
-" Shell:\> Ping6 2002::2 -l 1000\r\n"
-
-#string STR_GET_HELP_IFCONFIG6 #language en-US ""
-".TH ifconfig6 0 "Displays or modifies IPv6 configuration for network interface."\r\n"
-".SH NAME\r\n"
-"Displays or modifies IPv6 configuration for network interface.\r\n"
-".SH SYNOPSIS\r\n"
-" \r\n"
-"IfConfig6 -r [Name] | -l [Name] \r\n"
-"IfConfig6 -s <Name> [dad <Num>] [auto | [man [id <mac>] [host <IPv6> gw <IPv6>]\r\n"
-" [dns <IPv6>]]]\r\n"
-".SH OPTIONS\r\n"
-" \r\n"
-" Name Adapter name, i.e., eth0\r\n"
-" -r [Name] Reconfigure all or specified interface, and set\r\n"
-" automatic policy. If specified interface is already\r\n"
-" set to automatic,then refresh the IPv6 configuration.\r\n"
-" -l [Name] List the configuration of the specified interface.\r\n"
-" -s <Name> dad <Num> Set dad transmits count of the specified interface.\r\n"
-" -s <Name> auto Set automatic policy of the specified interface.\r\n"
-" -s <Name> man id <Mac> Set alternative interface id of the specified \r\n"
-" interface. Must under manual policy.\r\n"
-" -s <Name> man host <IPv6> gw <IPv6>\r\n"
-" Set static host IP and gateway address of the\r\n"
-" specified interface. Must under manual policy.\r\n"
-" -s <Name> man dns <IPv6> Set DNS server IP addresses of the specified\r\n"
-" interface.Must under manual policy.\r\n"
-".SH EXAMPLES\r\n"
-" \r\n"
-"EXAMPLES:\r\n"
-" * To list the configuration for the interface eth0:\r\n"
-" Shell:\> ifConfig6 -l eth0\r\n"
-" \r\n"
-" * To use automatic configuration to request the IPv6 address configuration\r\n"
-" dynamically for the interface eth0:\r\n"
-" Shell:\> ifconfig6 -s eth0 auto\r\n"
-" \r\n"
-" * To set the dad transmits count for eth0 under automatic policy:\r\n"
-" Shell:\> ifconfig6 -s eth0 auto dad 10\r\n"
-" \r\n"
-" * To set the alternative interface id of eth0 under manual policy:\r\n"
-" Shell:\> ifconfig6 -s eth0 man id ff:dd:aa:88:66:cc\r\n"
-" \r\n"
-" * To use the static IP6 addresses configuration for the interface eth0,\r\n"
-" and this configuration survives the network reload:\r\n"
-" Shell:\> ifconfig6 -s eth0 man host 2002::1/64 2002::2/64 gw 2002::3/64\r\n"
+/** @file
+
+ String definitions for UEFI Shell network 2 commands
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ Module Name:
+
+ UefiShellNetwork2CommandsLib.uni
+
+ Abstract:
+
+ String definitions for UEFI Shell 2.0 network 2 commands
+**/
+
+#langdef en-US "english"
+
+#string STR_GEN_ERR_AD #language en-US "%H%s%N: Access denied.\r\n"
+#string STR_GEN_OUT_MEM #language en-US "%H%s%N: Memory allocation was not successful.\r\n"
+
+#string STR_PING6_INVALID_IP #language en-US "%Ping6: Invalid IP6 address, %s\r\n"
+#string STR_PING6_INVALID_INPUT #language en-US "%Ping6: Invalid input, please type 'Ping6 -?'for help\r\n"
+#string STR_PING6_INVALID_SEND_NUMBER #language en-US "%Ping6: Invalid send number, %s\r\n"
+#string STR_PING6_INVALID_BUFFER_SIZE #language en-US "%Ping6: Invalid buffer size, %s\r\n"
+#string STR_PING6_INVALID_SOURCE #language en-US "%Ping6: Require source interface option\r\n"
+#string STR_PING6_IP6_CONFIG #language en-US "%Ping6: The process of Ip6 Configure %r\r\n"
+#string STR_PING6_IP6_RECEIVE #language en-US "%Ping6: Place the receive token %r\r\n"
+#string STR_PING6_IP6CFG_GETDATA #language en-US "%Ping6: Get data of the interface information %r\r\n"
+#string STR_PING6_SEND_REQUEST #language en-US "Echo request sequence %d fails.\r\n"
+#string STR_PING6_CONFIGD_NIC_NF #language en-US "%Ping6: No configured interfaces were found.\r\n"
+#string STR_PING6_NOSOURCE_INDOMAIN #language en-US "No sources in %s's multicast domain.\r\n"
+#string STR_PING6_START #language en-US "Ping %s %d data bytes\r\n"
+#string STR_PING6_TIMEOUT #language en-US "Echo request sequence %d timeout.\r\n"
+#string STR_PING6_REPLY_INFO #language en-US "%d bytes from %s : icmp_seq=%d ttl=%d time=%d~%dms\r\n"
+#string STR_PING6_STAT #language en-US "\n%d packets transmitted, %d received, %d%% packet loss, time %dms\r\n"
+#string STR_PING6_RTT #language en-US "\nRtt(round trip time) min=%d~%dms max=%d~%dms avg=%d~%dms\r\n"
+
+#string STR_IFCONFIG6_ERR_IP6CFG_GETDATA #language en-US "Get data of the interface information %hr\r\n"
+#string STR_IFCONFIG6_INFO_BREAK #language en-US "-----------------------------------------------------------------"
+#string STR_IFCONFIG6_INFO_COLON #language en-US ":"
+#string STR_IFCONFIG6_INFO_JOINT #language en-US " >> "
+#string STR_IFCONFIG6_INFO_NEWLINE #language en-US "\r\n"
+#string STR_IFCONFIG6_INFO_IF_NAME #language en-US "\n%Hname : %s%N\r\n"
+#string STR_IFCONFIG6_INFO_POLICY_AUTO #language en-US "%Hpolicy : automatic%N\r\n"
+#string STR_IFCONFIG6_INFO_POLICY_MAN #language en-US "%Hpolicy : manual%N\r\n"
+#string STR_IFCONFIG6_INFO_DAD_TRANSMITS #language en-US "%Hdad xmits : %d%N\r\n"
+#string STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD #language en-US "%Hinterface id : %N"
+#string STR_IFCONFIG6_INFO_MAC_ADDR_HEAD #language en-US "%Hmac addr : %N"
+#string STR_IFCONFIG6_INFO_MAC_ADDR_BODY #language en-US "%02x"
+#string STR_IFCONFIG6_INFO_IP_ADDR_HEAD #language en-US "\n%Hhost addr : %N\r\n"
+#string STR_IFCONFIG6_INFO_DNS_ADDR_HEAD #language en-US "\n%Hdns server : %N\r\n"
+#string STR_IFCONFIG6_INFO_IP_ADDR_BODY #language en-US "%02x"
+#string STR_IFCONFIG6_INFO_IP_ADDR_BODY4BIT #language en-US "%x"
+#string STR_IFCONFIG6_INFO_ROUTE_HEAD #language en-US "\n%Hroute table : %N\r\n"
+#string STR_IFCONFIG6_INFO_PREFIX_LEN #language en-US "/%d"
+#string STR_IFCONFIG6_LINE_HELP #language en-US "Displays or modifies the IPv6 configuration"
+#string STR_IFCONFIG6_ERR_LACK_INTERFACE #language en-US "Lack interface name.\r\n"
+ "Usage: IfConfig6 -s <Name> \r\n"
+ "Example: IfConfig6 -s eth0 auto\r\n"
+#string STR_IFCONFIG6_LACK_OPTION #language en-US "Flags lack. Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_CONFLICT_OPTIONS #language en-US "Flags conflict. Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_LACK_COMMAND #language en-US "Lack interface config option.\r\n"
+ "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_INVALID_INTERFACE #language en-US "Invalid interface name.\r\n"
+ "Hint: Use {IfConfig6 -l} to check existing interface names.\r\n"
+#string STR_IFCONFIG6_ERR_INVALID_COMMAND #language en-US "Invalid command. Bad command %H%s%N is skipped.\r\n"
+ "Hint: Incorrect option or arguments. Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_LACK_ARGUMENTS #language en-US "Lack arguments. Bad command %H%s%N is skipped.\r\n"
+ "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_LACK_OPTION #language en-US "Lack options.\r\n"
+ "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_MAN_HOST #language en-US "Manual address configuration failed. Please retry.\r\n"
+
+#string STR_IFCONFIG6_ERR_MAN_GW #language en-US "Gateway address configuration failed. Please check the argument.\r\n"
+
+#string STR_IFCONFIG6_ERR_INVALID_IP_CONFIG #language en-US "The IP address is not configurable when the policy is Ip6ConfigPolicyAutomatic.\r\n"
+
+#string STR_IFCONFIG6_ERR_INVALID_GW_CONFIG #language en-US "The gateway address is not configurable when the policy is Ip6ConfigPolicyAutomatic.\r\n"
+
+#string STR_IFCONFIG6_ERR_INVALID_DNS_CONFIG #language en-US "The DNS server address is not configurable when the policy is Ip6ConfigPolicyAutomatic.\r\n"
+
+#string STR_IFCONFIG6_ERR_DUPLICATE_COMMAND #language en-US "Duplicate commands. Bad command %H%s%N is skipped.\r\n"
+ "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_CONFLICT_COMMAND #language en-US "Conflict commands. Bad command %H%s%N is skipped.\r\n"
+ "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_UNKNOWN_COMMAND #language en-US "Unknown commands. Bad command %H%s%N is skipped.\r\n"
+ "Hint: Please type 'IfConfig6 -?' for help info.\r\n"
+#string STR_IFCONFIG6_ERR_ADDRESS_FAILED #language en-US "Failed to configure IPv6 address: "
+
+
+#string STR_GET_HELP_PING6 #language en-US ""
+".TH ping6 0 "Ping a target machine with UEFI IPv6 network stack."\r\n"
+".SH NAME\r\n"
+"Ping a target machine with UEFI IPv6 network stack.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"Ping6 [-l size] [-n count] [-s SourceIp] TargetIp\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -l size Send buffer size, in bytes(default=16, min=16, max=32768).\r\n"
+" -n count Send request count, (default=10, min=1, max=10000).\r\n"
+" -s SourceIp Source IPv6 address.\r\n"
+" TargetIp Target IPv6 address.\r\n"
+"NOTES:\r\n"
+" 1. When TargetIp is a link local address, SourceIp needs to be specified.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"Examples:\r\n"
+" * To ping the target host by sending 5 request with 1000 bytes from 2002::1\r\n"
+" Shell:\> Ping6 -s 2002::1 2002::2 -l 1000 -n 5\r\n"
+" \r\n"
+" * To ping the target host with 1000 bytes\r\n"
+" Shell:\> Ping6 2002::2 -l 1000\r\n"
+
+#string STR_GET_HELP_IFCONFIG6 #language en-US ""
+".TH ifconfig6 0 "Displays or modifies IPv6 configuration for network interface."\r\n"
+".SH NAME\r\n"
+"Displays or modifies IPv6 configuration for network interface.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"IfConfig6 -r [Name] | -l [Name] \r\n"
+"IfConfig6 -s <Name> [dad <Num>] [auto | [man [id <mac>] [host <IPv6> gw <IPv6>]\r\n"
+" [dns <IPv6>]]]\r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" Name Adapter name, i.e., eth0\r\n"
+" -r [Name] Reconfigure all or specified interface, and set\r\n"
+" automatic policy. If specified interface is already\r\n"
+" set to automatic,then refresh the IPv6 configuration.\r\n"
+" -l [Name] List the configuration of the specified interface.\r\n"
+" -s <Name> dad <Num> Set dad transmits count of the specified interface.\r\n"
+" -s <Name> auto Set automatic policy of the specified interface.\r\n"
+" -s <Name> man id <Mac> Set alternative interface id of the specified \r\n"
+" interface. Must under manual policy.\r\n"
+" -s <Name> man host <IPv6> gw <IPv6>\r\n"
+" Set static host IP and gateway address of the\r\n"
+" specified interface. Must under manual policy.\r\n"
+" -s <Name> man dns <IPv6> Set DNS server IP addresses of the specified\r\n"
+" interface.Must under manual policy.\r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To list the configuration for the interface eth0:\r\n"
+" Shell:\> ifConfig6 -l eth0\r\n"
+" \r\n"
+" * To use automatic configuration to request the IPv6 address configuration\r\n"
+" dynamically for the interface eth0:\r\n"
+" Shell:\> ifconfig6 -s eth0 auto\r\n"
+" \r\n"
+" * To set the dad transmits count for eth0 under automatic policy:\r\n"
+" Shell:\> ifconfig6 -s eth0 auto dad 10\r\n"
+" \r\n"
+" * To set the alternative interface id of eth0 under manual policy:\r\n"
+" Shell:\> ifconfig6 -s eth0 man id ff:dd:aa:88:66:cc\r\n"
+" \r\n"
+" * To use the static IP6 addresses configuration for the interface eth0,\r\n"
+" and this configuration survives the network reload:\r\n"
+" Shell:\> ifconfig6 -s eth0 man host 2002::1/64 2002::2/64 gw 2002::3/64\r\n"