diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellNetwork2CommandsLib')
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" |
