The copyright change to ShellLibHiiGuid.h needs to be corrected. It should be updated to 2011 - 2016, not replace 2011 with 2016.
If you fix that, then: Reviewed-By: Jaben Carsey <jaben.car...@intel.com> SideNote and I am not sure if this is reason enough to reject a patch. This would be much cleaner to review/understand as a series of patches. My thought is this would be a clean order. Patch 1 - add the GUID to the ShellLibHiiGuid.h and ShellPkg.DEC Patch 2 - add the new NULL library instance Patch 3 - update DSC file. -Jaben > -----Original Message----- > From: Zhang, Lubo > Sent: Tuesday, March 01, 2016 6:14 PM > To: edk2-devel@lists.01.org > Cc: Carsey, Jaben <jaben.car...@intel.com>; Wu, Jiaxin > <jiaxin...@intel.com>; Ye, Ting <ting...@intel.com>; Fu, Siyuan > <siyuan...@intel.com> > Subject: [patch] ShellPkg: Merge Ping6 and Ifconfig6 tools to Shell command. > Importance: High > > According to the new Shell spec, we add Network2 profile and > merge Ping6 and Ifconfig6 tools to Shell command. > > Cc: Carsey Jaben <jaben.car...@intel.com> > Cc: Wu Jiaxin <jiaxin...@intel.com> > Cc: Ye Ting <ting...@intel.com> > Cc: Fu Siyuan <siyuan...@intel.com> > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Zhang Lubo <lubo.zh...@intel.com> > --- > ShellPkg/Include/Guid/ShellLibHiiGuid.h | 9 +- > .../UefiShellNetwork2CommandsLib/Ifconfig6.c | 1839 > ++++++++++++++++++++ > .../Library/UefiShellNetwork2CommandsLib/Ping6.c | 1247 +++++++++++++ > .../UefiShellNetwork2CommandsLib.c | 91 + > .../UefiShellNetwork2CommandsLib.h | 72 + > .../UefiShellNetwork2CommandsLib.inf | 63 + > .../UefiShellNetwork2CommandsLib.uni | 151 ++ > ShellPkg/ShellPkg.dec | 4 +- > ShellPkg/ShellPkg.dsc | 8 +- > 9 files changed, 3479 insertions(+), 5 deletions(-) > create mode 100644 > ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c > create mode 100644 > ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c > create mode 100644 > ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma > ndsLib.c > create mode 100644 > ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma > ndsLib.h > create mode 100644 > ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma > ndsLib.inf > create mode 100644 > ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma > ndsLib.uni > > diff --git a/ShellPkg/Include/Guid/ShellLibHiiGuid.h > b/ShellPkg/Include/Guid/ShellLibHiiGuid.h > index 62c2e72..edbfd7c 100644 > --- a/ShellPkg/Include/Guid/ShellLibHiiGuid.h > +++ b/ShellPkg/Include/Guid/ShellLibHiiGuid.h > @@ -1,9 +1,9 @@ > /** @file > GUIDs for HII package list installed by Shell libraries. > > - Copyright (c) 2011, Intel Corporation. All rights reserved.<BR> > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> > This program and the accompanying materials > are licensed and made available under the terms and conditions of the BSD > License > which accompanies this distribution. The full text of the license may be > found at > http://opensource.org/licenses/bsd-license.php > > @@ -52,10 +52,16 @@ > > #define SHELL_NETWORK1_HII_GUID \ > { \ > 0xf3d301bb, 0xf4a5, 0x45a8, { 0xb0, 0xb7, 0xfa, 0x99, 0x9c, 0x62, 0x37, > 0xae } \ > } > + > +#define SHELL_NETWORK2_HII_GUID \ > + { \ > + 0x174b2b5, 0xf505, 0x4b12, { 0xaa, 0x60, 0x59, 0xdf, 0xf8, 0xd6, 0xea, > 0x37 } \ > + } > + > #define SHELL_TFTP_HII_GUID \ > { \ > 0x738a9314, 0x82c1, 0x4592, { 0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, > 0xd4 } \ > } > > @@ -71,9 +77,10 @@ extern EFI_GUID gShellDriver1HiiGuid; > extern EFI_GUID gShellInstall1HiiGuid; > extern EFI_GUID gShellLevel1HiiGuid; > extern EFI_GUID gShellLevel2HiiGuid; > extern EFI_GUID gShellLevel3HiiGuid; > extern EFI_GUID gShellNetwork1HiiGuid; > +extern EFI_GUID gShellNetwork2HiiGuid; > extern EFI_GUID gShellTftpHiiGuid; > extern EFI_GUID gShellBcfgHiiGuid; > > #endif > diff --git a/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c > new file mode 100644 > index 0000000..b1592e6 > --- /dev/null > +++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ifconfig6.c > @@ -0,0 +1,1839 @@ > +/** @file > + The implementation for Shell command IfConfig6. > + > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD > License > + which accompanies this distribution. The full text of the license may be > found at > + http://opensource.org/licenses/bsd-license.php. > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > +#include "UefiShellNetwork2CommandsLib.h" > + > +typedef 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 > + }, > +}; > + > +/** > + 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); > + ASSERT (Str != NULL); > + ArgStr = Str; > + > + // > + // init a node for the list head. > + // > + ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST)); > + ASSERT (ArgNode != NULL); > + ArgList = ArgNode; > + > + // > + // Split the local copy and save in the list node. > + // > + while (*Str != L'\0') { > + if (*Str == Separator) { > + *Str = L'\0'; > + ArgNode->Arg = ArgStr; > + ArgStr = Str + 1; > + ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST)); > + ASSERT (ArgNode->Next != NULL); > + ArgNode = ArgNode->Next; > + } > + > + Str++; > + } > + > + ArgNode->Arg = ArgStr; > + ArgNode->Next = NULL; > + > + return ArgList; > +} > + > +/** > + Check the correctness of input Args with '-s' option. > + > + @param[in] CheckList The pointer of VAR_CHECK_ITEM array. > + @param[in] Name The pointer of input arg. > + @param[in] Init The switch to execute the check. > + > + @return The value of VAR_CHECK_CODE. > + > +**/ > +VAR_CHECK_CODE > +IfConfig6RetriveCheckListByName( > + IN VAR_CHECK_ITEM *CheckList, > + IN CHAR16 *Name, > + IN BOOLEAN Init > +) > +{ > + STATIC UINT32 CheckDuplicate; > + STATIC UINT32 CheckConflict; > + VAR_CHECK_CODE RtCode; > + UINT32 Index; > + VAR_CHECK_ITEM Arg; > + > + if (Init) { > + CheckDuplicate = 0; > + CheckConflict = 0; > + return VarCheckOk; > + } > + > + RtCode = VarCheckOk; > + Index = 0; > + Arg = CheckList[Index]; > + > + // > + // Check the Duplicated/Conflicted/Unknown input Args. > + // > + while (Arg.FlagStr != NULL) { > + if (StrCmp (Arg.FlagStr, Name) == 0) { > + > + if (CheckDuplicate & Arg.FlagID) { > + RtCode = VarCheckDuplicate; > + break; > + } > + > + if (CheckConflict & Arg.ConflictMask) { > + RtCode = VarCheckConflict; > + break; > + } > + > + CheckDuplicate |= Arg.FlagID; > + CheckConflict |= Arg.ConflictMask; > + break; > + } > + > + Arg = CheckList[++Index]; > + } > + > + if (Arg.FlagStr == NULL) { > + RtCode = VarCheckUnknown; > + } > + > + return RtCode; > +} > + > +/** > + The notify function of create event when performing a manual config. > + > + @param[in] 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 ((Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0) && (Index < > PREFIXMAXLEN)) { > + Index = Index + 2; > + if (Index > PREFIXMAXLEN - 2) { > + break; > + } > + } > + > + Short = TRUE; > + > + if (Index == PREFIXMAXLEN) { > + // > + // :: is at the end of the address. > + // > + break; > + } > + } > + > + if (Index < PREFIXMAXLEN - 1) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_IFCONFIG6_INFO_IP_ADDR_BODY), 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); > + > + return SHELL_SUCCESS; > +} > + > +/** > + The clean process of the IfConfig6 application. > + > + @param[in] IfList The pointer of IfList(interface list). > + > + @retval SHELL_SUCCESS The IfConfig6 clean processed successfully. > + @retval others The IfConfig6 clean process failed. > + > +**/ > +SHELL_STATUS > +IfConfig6ClearInterfaceInfo ( > + IN LIST_ENTRY *IfList > + ) > +{ > + EFI_STATUS Status; > + SHELL_STATUS ShellStatus; > + LIST_ENTRY *Entry; > + IFCONFIG6_INTERFACE_CB *IfCb; > + EFI_IP6_CONFIG_POLICY Policy; > + > + Policy = Ip6ConfigPolicyAutomatic; > + 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. > + // > + while (Entry != IfList) { > + > + IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link); > + > + Status = IfCb->IfCfg->SetData ( > + IfCb->IfCfg, > + Ip6ConfigDataTypePolicy, > + sizeof (EFI_IP6_CONFIG_POLICY), > + &Policy > + ); > + > + if (EFI_ERROR (Status)) { > + 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; > + > + } 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 > + ); > + } > + } > + > + } 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; > + 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); > + 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; > + ARG_LIST *ArgNode; > + ARG_LIST *ArgHead; > + > + ASSERT (Private != NULL); > + > + // > + // Clean the list which save the set config Args. > + // > + if (Private->VarArg != NULL) { > + ArgHead = Private->VarArg; > + > + while (ArgHead->Next != NULL) { > + ArgNode = ArgHead->Next; > + FreePool (ArgHead); > + ArgHead = ArgNode; > + } > + > + FreePool (ArgHead); > + } > + > + if (Private->IfName != NULL) > + FreePool (Private->IfName); > + > + > + // > + // Clean the IFCONFIG6_INTERFACE_CB list. > + // > + Entry = Private->IfList.ForwardLink; > + NextEntry = Entry->ForwardLink; > + > + while (Entry != &Private->IfList) { > + > + IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link); > + > + RemoveEntryList (&IfCb->Link); > + > + if (IfCb->IfId != NULL) { > + > + FreePool (IfCb->IfId); > + } > + > + if (IfCb->IfInfo != NULL) { > + > + FreePool (IfCb->IfInfo); > + } > + > + FreePool (IfCb); > + > + Entry = NextEntry; > + NextEntry = Entry->ForwardLink; > + } > + > + FreePool (Private); > +} > + > +/** > + 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); > + ASSERT (Str != NULL); > + 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); > + ASSERT (Str != NULL); > + 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' '); > + ASSERT (ArgList != NULL); > + > + Private->OpCode = IfConfig6OpSet; > + Private->IfName = ArgList->Arg; > + > + Private->VarArg = ArgList->Next; > + > + if (Private->IfName == NULL || Private->VarArg == NULL) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_IFCONFIG6_ERR_LACK_COMMAND), 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 > new file mode 100644 > index 0000000..af7d08f > --- /dev/null > +++ b/ShellPkg/Library/UefiShellNetwork2CommandsLib/Ping6.c > @@ -0,0 +1,1247 @@ > +/** @file > + The implementation for Ping6 application. > + > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the BSD > License > + which accompanies this distribution. The full text of the license may be > found at > + http://opensource.org/licenses/bsd-license.php. > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include "UefiShellNetwork2CommandsLib.h" > + > +#define PING6_DEFAULT_TIMEOUT 5000 > +#define PING6_MAX_SEND_NUMBER 10000 > +#define PING6_MAX_BUFFER_SIZE 32768 > +#define PING6_ONE_SECOND 10000000 > + > +// > +// A similar amount of time that passes in femtoseconds > +// for each increment of TimerValue. It is for NT32 only. > +// > +#define NTTIMERPERIOD 358049 > + > +#pragma pack(1) > + > +typedef struct _ICMP6_ECHO_REQUEST_REPLY { > + UINT8 Type; > + UINT8 Code; > + UINT16 Checksum; > + UINT16 Identifier; > + UINT16 SequenceNum; > + UINT64 TimeStamp; > + UINT8 Data[1]; > +} ICMP6_ECHO_REQUEST_REPLY; > + > +#pragma pack() > + > +typedef struct _PING6_ICMP6_TX_INFO { > + LIST_ENTRY Link; > + UINT16 SequenceNum; > + UINT64 TimeStamp; > + EFI_IP6_COMPLETION_TOKEN *Token; > +} PING6_ICMP6_TX_INFO; > + > +typedef struct _PING6_PRIVATE_DATA { > + EFI_HANDLE ImageHandle; > + EFI_HANDLE NicHandle; > + EFI_HANDLE Ip6ChildHandle; > + EFI_IP6_PROTOCOL *Ip6; > + EFI_EVENT Timer; > + > + EFI_STATUS Status; > + LIST_ENTRY TxList; > + EFI_IP6_COMPLETION_TOKEN RxToken; > + UINT16 RxCount; > + UINT16 TxCount; > + 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; > +UINT64 mFrequency = 0; > +UINT64 mIp6CurrentTick = 0; > +EFI_CPU_ARCH_PROTOCOL *Cpu = NULL; > + > + > + > +/** > + Reads and returns the current value of the Time. > + > + @return The current tick value. > + > +**/ > +UINT64 > +Ping6ReadTime () > +{ > + UINT64 TimerPeriod; > + EFI_STATUS Status; > + > + ASSERT (Cpu != NULL); > + > + Status = Cpu->GetTimerValue (Cpu, 0, &mIp6CurrentTick, &TimerPeriod); > + if (EFI_ERROR (Status)) { > + // > + // The WinntGetTimerValue will return EFI_UNSUPPORTED. Set the > + // TimerPeriod by ourselves. > + // > + mIp6CurrentTick += 1000000; > + } > + > + return mIp6CurrentTick; > +} > + > +/** > + Get and calculate the frequency in tick/ms. > + The result is saved in the globle variable mFrequency > + > + @retval EFI_SUCCESS Calculated the frequency successfully. > + @retval Others Failed to calculate the frequency. > + > +**/ > +EFI_STATUS > +Ping6GetFrequency ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINT64 CurrentTick; > + UINT64 TimerPeriod; > + > + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) > &Cpu); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTick, &TimerPeriod); > + > + if (EFI_ERROR (Status)) { > + // > + // For NT32 Simulator only. 358049 is a similar value to keep timer > granularity. > + // Set the timer period by ourselves. > + // > + TimerPeriod = (UINT64) NTTIMERPERIOD; > + } > + // > + // The timer period is in femtosecond (1 femtosecond is 1e-15 second). > + // So 1e+12 is divided by timer period to produce the freq in tick/ms. > + // > + mFrequency = DivU64x64Remainder (1000000000000ULL, TimerPeriod, > NULL); > + > + return EFI_SUCCESS; > +} > + > +/** > + Get and calculate the duration in ms. > + > + @param[in] Begin The start point of time. > + @param[in] End The end point of time. > + > + @return The duration in ms. > + > +**/ > +UINT64 > +Ping6CalculateTick ( > + IN UINT64 Begin, > + IN UINT64 End > + ) > +{ > + ASSERT (End > Begin); > + return DivU64x64Remainder (End - Begin, mFrequency, NULL); > +} > + > +/** > + 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 rountine. > + > + @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; > + UINT64 Rtt; > + CHAR8 Near; > + > + Private = (PING6_PRIVATE_DATA *) Context; > + > + if (Private->Status == EFI_ABORTED) { > + return; > + } > + > + RxToken = &Private->RxToken; > + RxData = RxToken->Packet.RxData; > + Reply = RxData->FragmentTable[0].FragmentBuffer; > + PayLoad = RxData->DataLength; > + > + if (RxData->Header->NextHeader != IP6_ICMP) { > + goto ON_EXIT; > + } > + > + if (!IP6_IS_MULTICAST (&Private->DstAddress) && > + !EFI_IP6_EQUAL (&RxData->Header->SourceAddress, &Private- > >DstAddress)) { > + goto ON_EXIT; > + } > + > + if ((Reply->Type != ICMP_V6_ECHO_REPLY) || (Reply->Code != 0)) { > + goto ON_EXIT; > + } > + > + if (PayLoad != Private->BufferSize) { > + goto ON_EXIT; > + } > + // > + // Check whether the reply matches the sent request before. > + // > + Status = Ping6OnMatchEchoReply (Private, Reply); > + if (EFI_ERROR(Status)) { > + goto ON_EXIT; > + } > + // > + // Display statistics on this icmp6 echo reply packet. > + // > + Rtt = Ping6CalculateTick (Reply->TimeStamp, Ping6ReadTime ()); > + if (Rtt != 0) { > + Near = (CHAR8) '='; > + } else { > + Near = (CHAR8) '<'; > + } > + > + Private->RttSum += Rtt; > + Private->RttMin = Private->RttMin > Rtt ? Rtt : Private->RttMin; > + Private->RttMax = Private->RttMax < Rtt ? Rtt : Private->RttMax; > + > + ShellPrintHiiEx ( > + -1, > + -1, > + NULL, > + STRING_TOKEN (STR_PING6_REPLY_INFO), > + gShellNetwork2HiiHandle, > + PayLoad, > + mIp6DstString, > + Reply->SequenceNum, > + RxData->Header->HopLimit, > + Near, > + Rtt > + ); > + > +ON_EXIT: > + > + if (Private->RxCount < Private->SendNum) { > + // > + // Continue to receive icmp6 echo reply packets. > + // > + RxToken->Status = EFI_ABORTED; > + > + Status = Private->Ip6->Receive (Private->Ip6, RxToken); > + > + if (EFI_ERROR (Status)) { > + Private->Status = EFI_ABORTED; > + } > + } else { > + // > + // All reply have already been received from the dest host. > + // > + Private->Status = EFI_SUCCESS; > + } > + // > + // Singal to recycle the each rxdata here, not at the end of process. > + // > + gBS->SignalEvent (RxData->RecycleSignal); > +} > + > +/** > + Initial EFI_IP6_COMPLETION_TOKEN. > + > + @param[in] Private The pointer of PING6_PRIVATE_DATA. > + @param[in] TimeStamp The TimeStamp of request. > + @param[in] SequenceNum The SequenceNum of request. > + > + @return The pointer of EFI_IP6_COMPLETION_TOKEN. > + > +**/ > +EFI_IP6_COMPLETION_TOKEN * > +Ping6GenerateToken ( > + IN PING6_PRIVATE_DATA *Private, > + IN UINT64 TimeStamp, > + IN UINT16 SequenceNum > + ) > +{ > + EFI_STATUS Status; > + EFI_IP6_COMPLETION_TOKEN *Token; > + EFI_IP6_TRANSMIT_DATA *TxData; > + ICMP6_ECHO_REQUEST_REPLY *Request; > + > + Request = AllocateZeroPool (Private->BufferSize); > + > + if (Request == NULL) { > + return NULL; > + } > + // > + // Assembly icmp6 echo request packet. > + // > + Request->Type = ICMP_V6_ECHO_REQUEST; > + Request->Code = 0; > + Request->SequenceNum = SequenceNum; > + Request->TimeStamp = TimeStamp; > + Request->Identifier = 0; > + // > + // Leave check sum to ip6 layer, since it has no idea of source address > + // selection. > + // > + Request->Checksum = 0; > + > + TxData = AllocateZeroPool (sizeof (EFI_IP6_TRANSMIT_DATA)); > + > + if (TxData == NULL) { > + FreePool (Request); > + return NULL; > + } > + // > + // Assembly ipv6 token for transmit. > + // > + TxData->OverrideData = 0; > + TxData->ExtHdrsLength = 0; > + TxData->ExtHdrs = NULL; > + TxData->DataLength = Private->BufferSize; > + TxData->FragmentCount = 1; > + TxData->FragmentTable[0].FragmentBuffer = (VOID *) Request; > + TxData->FragmentTable[0].FragmentLength = Private->BufferSize; > + > + Token = AllocateZeroPool (sizeof (EFI_IP6_COMPLETION_TOKEN)); > + > + if (Token == NULL) { > + FreePool (Request); > + FreePool (TxData); > + return NULL; > + } > + > + Token->Status = EFI_ABORTED; > + Token->Packet.TxData = TxData; > + > + Status = gBS->CreateEvent ( > + EVT_NOTIFY_SIGNAL, > + TPL_CALLBACK, > + 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 (); > + 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; > + > + return Private->Ip6->Receive (Private->Ip6, &Private->RxToken); > +} > + > +/** > + Remove the timeout request from the list. > + > + @param[in] Event A EFI_EVENT type event. > + @param[in] Context The pointer to Context. > + > +**/ > +VOID > +EFIAPI > +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 (TxInfo->TimeStamp, Ping6ReadTime ()); > + > + // > + // 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; > + EFI_SERVICE_BINDING_PROTOCOL *Ip6Sb; > + EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; > + EFI_IP6_CONFIG_DATA Ip6Config; > + EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo; > + UINTN IfInfoSize; > + EFI_IPv6_ADDRESS *Addr; > + UINTN AddrIndex; > + > + HandleBuffer = NULL; > + Ip6Sb = NULL; > + IfInfo = NULL; > + IfInfoSize = 0; > + > + // > + // Locate all the handles with ip6 service binding protocol. > + // > + Status = gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiIp6ServiceBindingProtocolGuid, > + NULL, > + &HandleNum, > + &HandleBuffer > + ); > + if (EFI_ERROR (Status) || (HandleNum == 0)) { > + return EFI_ABORTED; > + } > + // > + // Source address is required when pinging a link-local address on multi- > + // interfaces host. > + // > + if (NetIp6IsLinkLocalAddr (&Private->DstAddress) && > + NetIp6IsUnspecifiedAddr (&Private->SrcAddress) && > + (HandleNum > 1)) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_PING6_INVALID_SOURCE), 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; > + > + Status = gBS->HandleProtocol ( > + HandleBuffer[HandleIndex], > + &gEfiIp6ServiceBindingProtocolGuid, > + (VOID **) &Ip6Sb > + ); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + if (NetIp6IsUnspecifiedAddr (&Private->SrcAddress)) { > + // > + // No need to match interface address. > + // > + break; > + } else { > + // > + // Ip6config protocol and ip6 service binding protocol are installed > + // on the same handle. > + // > + Status = gBS->HandleProtocol ( > + HandleBuffer[HandleIndex], > + &gEfiIp6ConfigProtocolGuid, > + (VOID **) &Ip6Cfg > + ); > + > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + // > + // Get the interface information size. > + // > + Status = Ip6Cfg->GetData ( > + Ip6Cfg, > + Ip6ConfigDataTypeInterfaceInfo, > + &IfInfoSize, > + NULL > + ); > + > + if (Status != EFI_BUFFER_TOO_SMALL) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_PING6_IP6CFG_GETDATA), 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 (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) { > + // > + // Match a certain interface address. > + // > + break; > + } > + } > + > + if (AddrIndex < IfInfo->AddressInfoCount) { > + // > + // Found a nic handle with right interface address. > + // > + break; > + } > + } > + > + FreePool (IfInfo); > + IfInfo = NULL; > + } > + // > + // No exact interface address matched. > + // > + > + if (HandleIndex == HandleNum) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_PING6_SOURCE_NOT_FOUND), gShellNetwork2HiiHandle, > mIp6SrcString); > + Status = EFI_NOT_FOUND; > + goto ON_ERROR; > + } > + > + Private->NicHandle = HandleBuffer[HandleIndex]; > + > + ASSERT (Ip6Sb != NULL); > + Status = Ip6Sb->CreateChild (Ip6Sb, &Private->Ip6ChildHandle); > + > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + Status = gBS->OpenProtocol ( > + Private->Ip6ChildHandle, > + &gEfiIp6ProtocolGuid, > + (VOID **) &Private->Ip6, > + Private->ImageHandle, > + Private->Ip6ChildHandle, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + ZeroMem (&Ip6Config, sizeof (EFI_IP6_CONFIG_DATA)); > + > + // > + // Configure the ip6 instance for icmp6 packet exchange. > + // > + Ip6Config.DefaultProtocol = 58; > + Ip6Config.AcceptAnyProtocol = FALSE; > + Ip6Config.AcceptIcmpErrors = TRUE; > + Ip6Config.AcceptPromiscuous = FALSE; > + Ip6Config.TrafficClass = 0; > + Ip6Config.HopLimit = 128; > + Ip6Config.FlowLabel = 0; > + Ip6Config.ReceiveTimeout = 0; > + Ip6Config.TransmitTimeout = 0; > + > + IP6_COPY_ADDRESS (&Ip6Config.StationAddress, &Private->SrcAddress); > + > + IP6_COPY_ADDRESS (&Ip6Config.DestinationAddress, &Private- > >DstAddress); > + > + Status = Private->Ip6->Configure (Private->Ip6, &Ip6Config); > + > + if (EFI_ERROR (Status)) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_CONFIG), > 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)); > + > + ASSERT (Private != NULL); > + > + 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; > + } > + // > + // 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->RttMax, > + DivU64x64Remainder (Private->RttSum, Private->RxCount, NULL) > + ); > + } > + > +ON_EXIT: > + > + if (Private != NULL) { > + Private->Status = EFI_ABORTED; > + > + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) { > + TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link); > + > + Status = Private->Ip6->Cancel (Private->Ip6, TxInfo->Token); > + > + RemoveEntryList (&TxInfo->Link); > + Ping6DestroyTxInfo (TxInfo); > + } > + > + if (Private->Timer != NULL) { > + gBS->CloseEvent (Private->Timer); > + } > + > + if (Private->Ip6 != NULL) { > + Status = Private->Ip6->Cancel (Private->Ip6, &Private->RxToken); > + } > + > + if (Private->RxToken.Event != NULL) { > + gBS->CloseEvent (Private->RxToken.Event); > + } > + > + if (Private->Ip6ChildHandle != NULL) { > + 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 paramter of count number. > + // > + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-n"); > + ValueStrPtr = ValueStr; > + if (ValueStr != NULL) { > + SendNumber = ShellStrToUintn (ValueStrPtr); > + > + // > + // ShellStrToUintn will return 0 when input is 0 or an invalid input > string. > + // > + if ((SendNumber == 0) || (SendNumber > PING6_MAX_SEND_NUMBER)) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_PING6_INVALID_SEND_NUMBER), gShellNetwork2HiiHandle, ValueStr); > + ShellStatus = SHELL_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + } > + // > + // Parse the paramter of buffer size. > + // > + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l"); > + ValueStrPtr = ValueStr; > + if (ValueStr != NULL) { > + BufferSize = ShellStrToUintn (ValueStrPtr); > + > + // > + // ShellStrToUintn will return 0 when input is 0 or an invalid input > string. > + // > + if ((BufferSize < 16) || (BufferSize > PING6_MAX_BUFFER_SIZE)) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN > (STR_PING6_INVALID_BUFFER_SIZE), gShellNetwork2HiiHandle, ValueStr); > + ShellStatus = SHELL_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + } > + > + ZeroMem (&SrcAddress, sizeof (EFI_IPv6_ADDRESS)); > + ZeroMem (&DstAddress, sizeof (EFI_IPv6_ADDRESS)); > + > + // > + // Parse the paramter of source ip address. > + // > + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s"); > + ValueStrPtr = ValueStr; > + if (ValueStr != NULL) { > + mIp6SrcString = ValueStr; > + Status = NetLibStrToIp6 (ValueStrPtr, &SrcAddress); > + if (EFI_ERROR (Status)) { > + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP), > gShellNetwork2HiiHandle, ValueStr); > + ShellStatus = SHELL_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + } > + // > + // Parse the paramter 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; > + } > + } > + // > + // Get frequency to calculate the time from ticks. > + // > + Status = Ping6GetFrequency (); > + > + if (EFI_ERROR(Status)) { > + ShellStatus = SHELL_ACCESS_DENIED; > + 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/UefiShellNetwork2Comm > andsLib.c > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.c > new file mode 100644 > index 0000000..6837b3a > --- /dev/null > +++ > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.c > @@ -0,0 +1,91 @@ > +/** @file > + Main file for NULL named library for network2 shell command functions. > + > + Copyright (c) 2016, Intel Corporation. All rights reserved. <BR> > + This program and the accompanying materials are licensed and made > available under > + the terms and conditions of the BSD License which accompanies this > distribution. > + The full text of the license may be found at > http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > +#include "UefiShellNetwork2CommandsLib.h" > + > +CONST CHAR16 gShellNetwork2FileName[] = L"ShellCommands"; > +EFI_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 > sucessfully. > + @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",ShellCommandRunIfconfig > 6 , 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/UefiShellNetwork2Comm > andsLib.h > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.h > new file mode 100644 > index 0000000..138cc8c > --- /dev/null > +++ > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.h > @@ -0,0 +1,72 @@ > +/** @file > + Main file for NULL named library for network2 shell command functions. > + > + Copyright (c) 2016, Intel Corporation. All rights reserved. <BR> > + This program and the accompanying materials are licensed and made > available under > + the terms and conditions of the BSD License which accompanies this > distribution. > + The full text of the license may be found at > http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#ifndef _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_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/UefiShellNetwork2Comm > andsLib.inf > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.inf > new file mode 100644 > index 0000000..426efcc > --- /dev/null > +++ > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.inf > @@ -0,0 +1,63 @@ > +## @file > +# Provides shell network2 functions > +# > +# Copyright (c) 2016, Intel Corporation. All rights reserved. <BR> > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license may be > found at > +# http://opensource.org/licenses/bsd-license.php > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +# > +# > +## > + > +[Defines] > + INF_VERSION = 0x00010006 > + BASE_NAME = 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 > + > +[LibraryClasses] > + MemoryAllocationLib > + BaseLib > + BaseMemoryLib > + DebugLib > + ShellCommandLib > + ShellLib > + UefiLib > + UefiRuntimeServicesTableLib > + UefiBootServicesTableLib > + PcdLib > + HiiLib > + FileHandleLib > + NetLib > + > +[Pcd] > + gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES > + > +[Protocols] > + gEfiCpuArchProtocolGuid ## CONSUMES > + gEfiIp6ProtocolGuid ## SOMETIMES_CONSUMES > + gEfiIp6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES > + gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES > + > +[Guids] > + gShellNetwork2HiiGuid ## SOMETIMES_CONSUMES ## HII > diff --git > a/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.uni > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.uni > new file mode 100644 > index 0000000..fb2bfab > --- /dev/null > +++ > b/ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comm > andsLib.uni > @@ -0,0 +1,151 @@ > +/** @file > + > + String definitions for UEFI Shell network 2 commands > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions > + of the BSD License which accompanies this distribution. The full > + text of the license may be found at<BR> > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + Module Name: > + > + UefiShellNetwork2CommandsLib.uni > + > + Abstract: > + > + String definitions for UEFI Shell 2.0 network 2 commands > +**/ > + > +#langdef en-US "english" > + > +#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_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_SOURCE_NOT_FOUND #language en-US "Source %s > not 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%c%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=%dms max=%dms avg=%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_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 "It > failed to set .\r\n" > + > + > +#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" > +".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" > diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec > index 76a2b7d..39f8012 100644 > --- a/ShellPkg/ShellPkg.dec > +++ b/ShellPkg/ShellPkg.dec > @@ -1,10 +1,10 @@ > ## @file ShellPkg.dec > # This Package provides all definitions for EFI and UEFI Shell > # > # (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.<BR> > -# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR> > +# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> > # > # This program and the accompanying materials are licensed and made > available under > # the terms and conditions of the BSD License which accompanies this > distribution. > # The full text of the license may be found at > # http://opensource.org/licenses/bsd-license.php > @@ -51,10 +51,11 @@ > gShellInstall1HiiGuid = {0x7d574d54, 0xd364, 0x4d4a, {0x95, 0xe3, > 0x49, 0x45, 0xdb, 0x7a, 0xd3, 0xee}} > gShellLevel1HiiGuid = {0xdec5daa4, 0x6781, 0x4820, {0x9c, 0x63, > 0xa7, 0xb0, 0xe4, 0xf1, 0xdb, 0x31}} > gShellLevel2HiiGuid = {0xf95a7ccc, 0x4c55, 0x4426, {0xa7, 0xb4, > 0xdc, 0x89, 0x61, 0x95, 0xb, 0xae}} > gShellLevel3HiiGuid = {0x4344558d, 0x4ef9, 0x4725, {0xb1, 0xe4, > 0x33, 0x76, 0xe8, 0xd6, 0x97, 0x4f}} > gShellNetwork1HiiGuid = {0xf3d301bb, 0xf4a5, 0x45a8, {0xb0, 0xb7, > 0xfa, 0x99, 0x9c, 0x62, 0x37, 0xae}} > + gShellNetwork2HiiGuid = {0x174b2b5, 0xf505, 0x4b12, {0xaa, 0x60, > 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37}} > gShellTftpHiiGuid = {0x738a9314, 0x82c1, 0x4592, {0x8f, > 0xf7, 0xc1, > 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}} > gShellBcfgHiiGuid = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, > 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6}} > > [Protocols] > gEfiShellProtocolGuid = {0x6302d008, 0x7f9b, 0x4f30, {0x87, > 0xac, > 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e}} > @@ -92,10 +93,11 @@ > # don't forget to update the text file if you change this. > # bit 0 = Drivers1 > # bit 1 = Debug1 > # bit 2 = Install1 > # bit 3 = Network1 > + # bit 4 = Network2 > gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask|0xFF|UINT8|0x0000000D > > ## This is the character count for allocation for consistent mappings > > gEfiShellPkgTokenSpaceGuid.PcdShellMapNameLength|50|UINT8|0x0000000 > 9 > > diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc > index 7e07cfb..31fe499 100644 > --- a/ShellPkg/ShellPkg.dsc > +++ b/ShellPkg/ShellPkg.dsc > @@ -1,9 +1,9 @@ > ## @file > # Shell Package > # > -# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR> > +# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR> > # > # This program and the accompanying materials > # are licensed and made available under the terms and conditions of the > BSD License > # which accompanies this distribution. The full text of the license may be > found at > # http://opensource.org/licenses/bsd-license.php > @@ -26,11 +26,11 @@ > [LibraryClasses.common] > > UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiAp > plicationEntryPoint.inf > > UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo > tServicesTableLib.inf > > DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptiona > lDevicePathProtocol.inf > DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf > - > DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Base > DebugPrintErrorLevelLib.inf > + > DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Base > DebugPrintErrorLevelLib.inf > PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf > > MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemor > yAllocationLib.inf > UefiLib|MdePkg/Library/UefiLib/UefiLib.inf > BaseLib|MdePkg/Library/BaseLib/BaseLib.inf > BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf > @@ -44,11 +44,11 @@ > > ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf > > ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommand > Lib.inf > ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf > > HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLi > b.inf > - > + > > PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePe > CoffGetEntryPointLib.inf > > BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgC > ommandLib.inf > IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf > > [LibraryClasses.ARM] > @@ -86,10 +86,11 @@ > > ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib. > inf > > ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLi > b.inf > > ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib > .inf > > ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLi > b.inf > > ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Comma > ndsLib.inf > + > ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Comma > ndsLib.inf > ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf > > ShellPkg/Library/UefiDpLib/UefiDpLib.inf { > <LibraryClasses> > > TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTempl > ate.inf > @@ -105,10 +106,11 @@ > !ifndef $(NO_SHELL_PROFILES) > > NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Comm > andsLib.inf > > NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Comma > ndsLib.inf > > NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comm > andsLib.inf > > NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1C > ommandsLib.inf > + > NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2C > ommandsLib.inf > !ifdef $(INCLUDE_DP) > NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf > !endif #$(INCLUDE_DP) > !ifdef $(INCLUDE_TFTP_COMMAND) > > NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.i > nf > -- > 1.9.5.msysgit.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel