Ping6.c revision a3bcde70e6dc69000f85cc5deee98101d2ae200a
1a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** @file 2a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian The implementation for Ping6 application. 3a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 4a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> 5a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 6a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian This program and the accompanying materials 7a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian are licensed and made available under the terms and conditions of the BSD License 8a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian which accompanies this distribution. The full text of the license may be found at 9a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian http://opensource.org/licenses/bsd-license.php. 10a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 11a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 14a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 15a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 16a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/ShellLib.h> 17a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/BaseMemoryLib.h> 18a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/BaseLib.h> 19a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/MemoryAllocationLib.h> 20a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/DebugLib.h> 21a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/UefiBootServicesTableLib.h> 22a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/HiiLib.h> 23a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Library/NetLib.h> 24a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 25a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Protocol/Cpu.h> 26a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Protocol/ServiceBinding.h> 27a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Protocol/Ip6.h> 28a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include <Protocol/Ip6Config.h> 29a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 30a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian#include "Ping6.h" 31a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 32a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianSHELL_PARAM_ITEM Ping6ParamList[] = { 33a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian { 34a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian L"-l", 35a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TypeValue 36a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian }, 37a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian { 38a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian L"-n", 39a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TypeValue 40a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian }, 41a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian { 42a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian L"-s", 43a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TypeValue 44a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian }, 45a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian { 46a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian L"-?", 47a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TypeFlag 48a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian }, 49a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian { 50a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NULL, 51a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TypeMax 52a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian }, 53a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian}; 54a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 55a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian// 56a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian// Global Variables in Ping6 application. 57a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian// 58a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_HII_HANDLE mHiiHandle; 59a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianCONST CHAR16 *mIp6DstString; 60a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianCONST CHAR16 *mIp6SrcString; 61a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_GUID mEfiPing6Guid = EFI_PING6_GUID; 62a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianUINT32 mFrequency = 0; 63a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 64a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Get and caculate the frequency in tick/ms. 65a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian The result is saved in the globle variable mFrequency 66a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 67a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS Caculated the frequency successfully. 68a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval Others Failed to caculate the frequency. 69a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 70a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 71a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 72a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6GetFrequency ( 73a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian VOID 74a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 75a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 76a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 77a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_CPU_ARCH_PROTOCOL *Cpu; 78a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINT64 CurrentTick; 79a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINT32 TimerPeriod; 80a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 81a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &Cpu); 82a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 83a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 84a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Status; 85a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 86a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 87a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTick, (UINT64 *) &TimerPeriod); 88a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 89a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 90a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 91a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // For NT32 Simulator only. 358049 is a similar value to keep timer granularity. 92a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Set the timer period by ourselves. 93a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 94a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TimerPeriod = NTTIMERPERIOD; 95a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 96a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 97a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // The timer period is in femtosecond (1 femtosecond is 1e-15 second). 98a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // So 1e+12 is divided by timer period to produce the freq in tick/ms. 99a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 100a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mFrequency = (UINT32) DivU64x32 (1000000000000ULL, TimerPeriod); 101a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 102a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_SUCCESS; 103a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 104a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 105a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 106a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Get and caculate the duration in ms. 107a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 108a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Begin The start point of time. 109a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] End The end point of time. 110a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 111a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @return The duration in ms. 112a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 113a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 114a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianUINT32 115a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6CalculateTick ( 116a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT64 Begin, 117a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT64 End 118a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 119a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 120a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ASSERT (End > Begin); 121a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return (UINT32) DivU64x32 (End - Begin, mFrequency); 122a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 123a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 124a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 125a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Destroy IPING6_ICMP6_TX_INFO, and recollect the memory. 126a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 127a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] TxInfo The pointer to PING6_ICMP6_TX_INFO. 128a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 129a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 130a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianVOID 131a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6DestroyTxInfo ( 132a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN PING6_ICMP6_TX_INFO *TxInfo 133a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 134a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 135a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_TRANSMIT_DATA *TxData; 136a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_FRAGMENT_DATA *FragData; 137a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINTN Index; 138a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 139a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ASSERT (TxInfo != NULL); 140a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 141a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxInfo->Token != NULL) { 142a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 143a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxInfo->Token->Event != NULL) { 144a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian gBS->CloseEvent (TxInfo->Token->Event); 145a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 146a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 147a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData = TxInfo->Token->Packet.TxData; 148a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxData != NULL) { 149a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 150a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxData->OverrideData != NULL) { 151a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (TxData->OverrideData); 152a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 153a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 154a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxData->ExtHdrs != NULL) { 155a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (TxData->ExtHdrs); 156a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 157a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 158a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian for (Index = 0; Index < TxData->FragmentCount; Index++) { 159a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FragData = TxData->FragmentTable[Index].FragmentBuffer; 160a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (FragData != NULL) { 161a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (FragData); 162a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 163a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 164a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 165a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 166a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (TxInfo->Token); 167a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 168a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 169a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (TxInfo); 170a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 171a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 172a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 173a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Match the request, and reply with SequenceNum/TimeStamp. 174a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 175a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Private The pointer to PING6_PRIVATE_DATA. 176a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Packet The pointer to ICMP6_ECHO_REQUEST_REPLY. 177a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 178a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS The match is successful. 179a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_NOT_FOUND The reply can't be matched with any request. 180a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 181a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 182a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 183a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6MatchEchoReply ( 184a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN PING6_PRIVATE_DATA *Private, 185a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN ICMP6_ECHO_REQUEST_REPLY *Packet 186a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 187a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 188a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_ICMP6_TX_INFO *TxInfo; 189a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian LIST_ENTRY *Entry; 190a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian LIST_ENTRY *NextEntry; 191a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 192a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) { 193a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link); 194a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 195a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if ((TxInfo->SequenceNum == Packet->SequenceNum) && (TxInfo->TimeStamp == Packet->TimeStamp)) { 196a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RxCount++; 197a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian RemoveEntryList (&TxInfo->Link); 198a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6DestroyTxInfo (TxInfo); 199a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_SUCCESS; 200a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 201a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 202a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 203a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_NOT_FOUND; 204a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 205a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 206a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 207a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian The original intention is to send a request. 208a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Currently, the application retransmits an icmp6 echo request packet 209a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian per second in sendnumber times that is specified by the user. 210a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Because nothing can be done here, all things move to the timer rountine. 211a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 212a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Event A EFI_EVENT type event. 213a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Context The pointer to Context. 214a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 215a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 216a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianVOID 217a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFIAPI 218a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6OnEchoRequestSent ( 219a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_EVENT Event, 220a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN VOID *Context 221a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 222a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 223a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 224a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 225a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 226a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian receive reply, match and print reply infomation. 227a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 228a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Event A EFI_EVENT type event. 229a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Context The pointer to context. 230a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 231a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 232a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianVOID 233a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFIAPI 234a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6OnEchoReplyReceived ( 235a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_EVENT Event, 236a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN VOID *Context 237a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 238a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 239a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 240a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_PRIVATE_DATA *Private; 241a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_COMPLETION_TOKEN *RxToken; 242a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_RECEIVE_DATA *RxData; 243a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ICMP6_ECHO_REQUEST_REPLY *Reply; 244a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINT32 PayLoad; 245a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINT32 Rtt; 246a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian CHAR8 Near; 247a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 248a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private = (PING6_PRIVATE_DATA *) Context; 249a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 250a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->Status == EFI_ABORTED) { 251a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return; 252a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 253a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 254a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian RxToken = &Private->RxToken; 255a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian RxData = RxToken->Packet.RxData; 256a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Reply = RxData->FragmentTable[0].FragmentBuffer; 257a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PayLoad = RxData->DataLength; 258a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 259a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (RxData->Header->NextHeader != IP6_ICMP) { 260a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 261a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 262a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 263a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (!IP6_IS_MULTICAST (&Private->DstAddress) && 264a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian !EFI_IP6_EQUAL (&RxData->Header->SourceAddress, &Private->DstAddress)) { 265a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 266a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 267a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 268a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if ((Reply->Type != ICMP_V6_ECHO_REPLY) || (Reply->Code != 0)) { 269a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 270a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 271a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 272a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (PayLoad != Private->BufferSize) { 273a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 274a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 275a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 276a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Check whether the reply matches the sent request before. 277a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 278a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ping6MatchEchoReply (Private, Reply); 279a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR(Status)) { 280a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 281a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 282a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 283a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Display statistics on this icmp6 echo reply packet. 284a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 285a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Rtt = Ping6CalculateTick (Reply->TimeStamp, ReadTime ()); 286a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Rtt != 0) { 287a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Near = (CHAR8) '='; 288a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } else { 289a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Near = (CHAR8) '<'; 290a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 291a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 292a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttSum += Rtt; 293a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttMin = Private->RttMin > Rtt ? Rtt : Private->RttMin; 294a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttMax = Private->RttMax < Rtt ? Rtt : Private->RttMax; 295a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 296a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx ( 297a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian -1, 298a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian -1, 299a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NULL, 300a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian STRING_TOKEN (STR_PING6_REPLY_INFO), 301a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mHiiHandle, 302a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PayLoad, 303a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mIp6DstString, 304a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Reply->SequenceNum, 305a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian RxData->Header->HopLimit, 306a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Near, 307a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Rtt 308a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 309a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 310a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianON_EXIT: 311a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 312a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->RxCount < Private->SendNum) { 313a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 314a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Continue to receive icmp6 echo reply packets. 315a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 316a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian RxToken->Status = EFI_ABORTED; 317a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 318a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Private->Ip6->Receive (Private->Ip6, RxToken); 319a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 320a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 321a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Status = EFI_ABORTED; 322a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 323a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } else { 324a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 325a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // All reply have already been received from the dest host. 326a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 327a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Status = EFI_SUCCESS; 328a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 329a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 330a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Singal to recycle the each rxdata here, not at the end of process. 331a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 332a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian gBS->SignalEvent (RxData->RecycleSignal); 333a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 334a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 335a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 336a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Initial EFI_IP6_COMPLETION_TOKEN. 337a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 338a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Private The pointer of PING6_PRIVATE_DATA. 339a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] TimeStamp The TimeStamp of request. 340a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] SequenceNum The SequenceNum of request. 341a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 342a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @return The pointer of EFI_IP6_COMPLETION_TOKEN. 343a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 344a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 345a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_IP6_COMPLETION_TOKEN * 346a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6GenerateToken ( 347a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN PING6_PRIVATE_DATA *Private, 348a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT64 TimeStamp, 349a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT16 SequenceNum 350a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 351a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 352a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 353a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_COMPLETION_TOKEN *Token; 354a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_TRANSMIT_DATA *TxData; 355a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ICMP6_ECHO_REQUEST_REPLY *Request; 356a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 357a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Request = AllocateZeroPool (Private->BufferSize); 358a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 359a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Request == NULL) { 360a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return NULL; 361a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 362a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 363a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Assembly icmp6 echo request packet. 364a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 365a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Request->Type = ICMP_V6_ECHO_REQUEST; 366a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Request->Code = 0; 367a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Request->SequenceNum = SequenceNum; 368a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Request->TimeStamp = TimeStamp; 369a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Request->Identifier = 0; 370a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 371a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Leave check sum to ip6 layer, since it has no idea of source address 372a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // selection. 373a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 374a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Request->Checksum = 0; 375a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 376a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData = AllocateZeroPool (sizeof (EFI_IP6_TRANSMIT_DATA)); 377a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 378a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxData == NULL) { 379a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (Request); 380a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return NULL; 381a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 382a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 383a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Assembly ipv6 token for transmit. 384a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 385a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData->OverrideData = 0; 386a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData->ExtHdrsLength = 0; 387a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData->ExtHdrs = NULL; 388a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData->DataLength = Private->BufferSize; 389a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData->FragmentCount = 1; 390a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData->FragmentTable[0].FragmentBuffer = (VOID *) Request; 391a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxData->FragmentTable[0].FragmentLength = Private->BufferSize; 392a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 393a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Token = AllocateZeroPool (sizeof (EFI_IP6_COMPLETION_TOKEN)); 394a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 395a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Token == NULL) { 396a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (Request); 397a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (TxData); 398a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return NULL; 399a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 400a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 401a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Token->Status = EFI_ABORTED; 402a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Token->Packet.TxData = TxData; 403a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 404a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->CreateEvent ( 405a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EVT_NOTIFY_SIGNAL, 406a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TPL_CALLBACK, 407a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6OnEchoRequestSent, 408a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private, 409a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &Token->Event 410a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 411a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 412a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 413a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (Request); 414a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (TxData); 415a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (Token); 416a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return NULL; 417a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 418a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 419a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Token; 420a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 421a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 422a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 423a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Transmit the EFI_IP6_COMPLETION_TOKEN. 424a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 425a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Private The pointer of PING6_PRIVATE_DATA. 426a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 427a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS Transmitted successfully. 428a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_OUT_OF_RESOURCES No memory is available on the platform. 429a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval others Transmitted unsuccessfully. 430a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 431a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 432a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 433a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6SendEchoRequest ( 434a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN PING6_PRIVATE_DATA *Private 435a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 436a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 437a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 438a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_ICMP6_TX_INFO *TxInfo; 439a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 440a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo = AllocateZeroPool (sizeof (PING6_ICMP6_TX_INFO)); 441a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 442a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxInfo == NULL) { 443a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_OUT_OF_RESOURCES; 444a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 445a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 446a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo->TimeStamp = ReadTime (); 447a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo->SequenceNum = (UINT16) (Private->TxCount + 1); 448a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 449a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo->Token = Ping6GenerateToken ( 450a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private, 451a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo->TimeStamp, 452a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo->SequenceNum 453a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 454a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 455a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (TxInfo->Token == NULL) { 456a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6DestroyTxInfo (TxInfo); 457a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_OUT_OF_RESOURCES; 458a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 459a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 460a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Private->Ip6->Transmit (Private->Ip6, TxInfo->Token); 461a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 462a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 463a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6DestroyTxInfo (TxInfo); 464a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Status; 465a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 466a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 467a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian InsertTailList (&Private->TxList, &TxInfo->Link); 468a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->TxCount++; 469a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 470a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_SUCCESS; 471a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 472a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 473a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 474a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Place a completion token into the receive packet queue to receive the echo reply. 475a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 476a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Private The pointer of PING6_PRIVATE_DATA. 477a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 478a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS Put the token into the receive packet queue successfully. 479a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval others Put the token into the receive packet queue unsuccessfully. 480a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 481a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 482a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 483a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6ReceiveEchoReply ( 484a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN PING6_PRIVATE_DATA *Private 485a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 486a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 487a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 488a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 489a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ZeroMem (&Private->RxToken, sizeof (EFI_IP6_COMPLETION_TOKEN)); 490a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 491a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->CreateEvent ( 492a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EVT_NOTIFY_SIGNAL, 493a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TPL_CALLBACK, 494a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6OnEchoReplyReceived, 495a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private, 496a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &Private->RxToken.Event 497a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 498a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 499a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 500a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Status; 501a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 502a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 503a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RxToken.Status = EFI_NOT_READY; 504a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 505a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Private->Ip6->Receive (Private->Ip6, &Private->RxToken); 506a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 507a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 508a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 509a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Remove the timeout request from the list. 510a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 511a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Event A EFI_EVENT type event. 512a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Context The pointer to Context. 513a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 514a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 515a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianVOID 516a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFIAPI 517a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6OnTimerRoutine ( 518a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_EVENT Event, 519a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN VOID *Context 520a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 521a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 522a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 523a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_PRIVATE_DATA *Private; 524a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_ICMP6_TX_INFO *TxInfo; 525a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian LIST_ENTRY *Entry; 526a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian LIST_ENTRY *NextEntry; 527a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINT32 Time; 528a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 529a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private = (PING6_PRIVATE_DATA *) Context; 530a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 531a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 532a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Retransmit icmp6 echo request packets per second in sendnumber times. 533a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 534a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->TxCount < Private->SendNum) { 535a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 536a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ping6SendEchoRequest (Private); 537a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->TxCount != 0){ 538a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 539a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_SEND_REQUEST), mHiiHandle, Private->TxCount + 1); 540a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 541a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 542a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 543a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 544a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Check whether any icmp6 echo request in the list timeout. 545a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 546a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) { 547a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link); 548a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Time = Ping6CalculateTick (TxInfo->TimeStamp, ReadTime ()); 549a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 550a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 551a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Remove the timeout echo request from txlist. 552a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 553a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Time > PING6_DEFAULT_TIMEOUT) { 554a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 555a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (TxInfo->Token->Status)) { 556a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Ip6->Cancel (Private->Ip6, TxInfo->Token); 557a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 558a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 559a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Remove the timeout icmp6 echo request from list. 560a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 561a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_TIMEOUT), mHiiHandle, TxInfo->SequenceNum); 562a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 563a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian RemoveEntryList (&TxInfo->Link); 564a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6DestroyTxInfo (TxInfo); 565a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 566a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (IsListEmpty (&Private->TxList) && (Private->TxCount == Private->SendNum)) { 567a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 568a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // All the left icmp6 echo request in the list timeout. 569a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 570a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Status = EFI_TIMEOUT; 571a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 572a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 573a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 574a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 575a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 576a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 577a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Create a valid IP6 instance. 578a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 579a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Private The pointer of PING6_PRIVATE_DATA. 580a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 581a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS Create a valid IP6 instance successfully. 582a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_ABORTED Locate handle with ip6 service binding protocol unsuccessfully. 583a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_INVALID_PARAMETER The source address is unspecified when the destination address is a link -ocal address. 584a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_OUT_OF_RESOURCES No memory is available on the platform. 585a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_NOT_FOUND The source address is not found. 586a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 587a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 588a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6CreateIp6Instance ( 589a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN PING6_PRIVATE_DATA *Private 590a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 591a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 592a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 593a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINTN HandleIndex; 594a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINTN HandleNum; 595a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_HANDLE *HandleBuffer; 596a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_SERVICE_BINDING_PROTOCOL *Ip6Sb; 597a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; 598a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_CONFIG_DATA Ip6Config; 599a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo; 600a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINTN IfInfoSize; 601a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IPv6_ADDRESS *Addr; 602a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINTN AddrIndex; 603a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 604a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian HandleBuffer = NULL; 605a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Sb = NULL; 606a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IfInfo = NULL; 607a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IfInfoSize = 0; 608a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 609a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 610a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Locate all the handles with ip6 service binding protocol. 611a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 612a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->LocateHandleBuffer ( 613a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ByProtocol, 614a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &gEfiIp6ServiceBindingProtocolGuid, 615a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NULL, 616a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &HandleNum, 617a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &HandleBuffer 618a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 619a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status) || (HandleNum == 0)) { 620a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_ABORTED; 621a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 622a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 623a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Source address is required when pinging a link-local address on multi- 624a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // interfaces host. 625a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 626a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (NetIp6IsLinkLocalAddr (&Private->DstAddress) && 627a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NetIp6IsUnspecifiedAddr (&Private->SrcAddress) && 628a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (HandleNum > 1)) { 629a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SOURCE), mHiiHandle); 630a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_INVALID_PARAMETER; 631a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 632a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 633a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 634a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // For each ip6 protocol, check interface addresses list. 635a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 636a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) { 637a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 638a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Sb = NULL; 639a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IfInfo = NULL; 640a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IfInfoSize = 0; 641a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 642a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->HandleProtocol ( 643a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian HandleBuffer[HandleIndex], 644a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &gEfiIp6ServiceBindingProtocolGuid, 645a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (VOID **) &Ip6Sb 646a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 647a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 648a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 649a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 650a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 651a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (NetIp6IsUnspecifiedAddr (&Private->SrcAddress)) { 652a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 653a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // No need to match interface address. 654a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 655a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian break; 656a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } else { 657a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 658a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Ip6config protocol and ip6 service binding protocol are installed 659a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // on the same handle. 660a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 661a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->HandleProtocol ( 662a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian HandleBuffer[HandleIndex], 663a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &gEfiIp6ConfigProtocolGuid, 664a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (VOID **) &Ip6Cfg 665a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 666a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 667a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 668a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 669a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 670a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 671a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Get the interface information size. 672a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 673a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ip6Cfg->GetData ( 674a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Cfg, 675a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6ConfigDataTypeInterfaceInfo, 676a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &IfInfoSize, 677a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NULL 678a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 679a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 680a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Status != EFI_BUFFER_TOO_SMALL) { 681a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6CFG_GETDATA), mHiiHandle, Status); 682a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 683a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 684a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 685a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IfInfo = AllocateZeroPool (IfInfoSize); 686a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 687a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (IfInfo == NULL) { 688a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_OUT_OF_RESOURCES; 689a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 690a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 691a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 692a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Get the interface info. 693a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 694a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ip6Cfg->GetData ( 695a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Cfg, 696a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6ConfigDataTypeInterfaceInfo, 697a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &IfInfoSize, 698a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IfInfo 699a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 700a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 701a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 702a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6CFG_GETDATA), mHiiHandle, Status); 703a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 704a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 705a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 706a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Check whether the source address is one of the interface addresses. 707a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 708a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian for (AddrIndex = 0; AddrIndex < IfInfo->AddressInfoCount; AddrIndex++) { 709a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 710a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Addr = &(IfInfo->AddressInfo[AddrIndex].Address); 711a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) { 712a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 713a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Match a certain interface address. 714a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 715a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian break; 716a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 717a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 718a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 719a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (AddrIndex < IfInfo->AddressInfoCount) { 720a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 721a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Found a nic handle with right interface address. 722a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 723a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian break; 724a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 725a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 726a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 727a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (IfInfo); 728a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IfInfo = NULL; 729a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 730a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 731a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // No exact interface address matched. 732a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 733a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 734a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (HandleIndex == HandleNum) { 735a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_SOURCE_NOT_FOUND), mHiiHandle, mIp6SrcString); 736a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_NOT_FOUND; 737a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 738a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 739a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 740a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->NicHandle = HandleBuffer[HandleIndex]; 741a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 742a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ASSERT (Ip6Sb != NULL); 743a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ip6Sb->CreateChild (Ip6Sb, &Private->Ip6ChildHandle); 744a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 745a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 746a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 747a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 748a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 749a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->OpenProtocol ( 750a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Ip6ChildHandle, 751a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &gEfiIp6ProtocolGuid, 752a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (VOID **) &Private->Ip6, 753a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->ImageHandle, 754a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Ip6ChildHandle, 755a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_OPEN_PROTOCOL_GET_PROTOCOL 756a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 757a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 758a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 759a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 760a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 761a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ZeroMem (&Ip6Config, sizeof (EFI_IP6_CONFIG_DATA)); 762a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 763a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 764a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Configure the ip6 instance for icmp6 packet exchange. 765a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 766a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.DefaultProtocol = 58; 767a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.AcceptAnyProtocol = FALSE; 768a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.AcceptIcmpErrors = TRUE; 769a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.AcceptPromiscuous = FALSE; 770a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.TrafficClass = 0; 771a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.HopLimit = 128; 772a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.FlowLabel = 0; 773a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.ReceiveTimeout = 0; 774a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Config.TransmitTimeout = 0; 775a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 776a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IP6_COPY_ADDRESS (&Ip6Config.StationAddress, &Private->SrcAddress); 777a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 778a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IP6_COPY_ADDRESS (&Ip6Config.DestinationAddress, &Private->DstAddress); 779a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 780a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Private->Ip6->Configure (Private->Ip6, &Ip6Config); 781a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 782a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 783a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_IP6_CONFIG), mHiiHandle, Status); 784a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_ERROR; 785a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 786a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 787a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return EFI_SUCCESS; 788a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 789a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianON_ERROR: 790a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (HandleBuffer != NULL) { 791a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (HandleBuffer); 792a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 793a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 794a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (IfInfo != NULL) { 795a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (IfInfo); 796a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 797a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 798a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if ((Ip6Sb != NULL) && (Private->Ip6ChildHandle != NULL)) { 799a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle); 800a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 801a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 802a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Status; 803a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 804a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 805a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 806a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Destory the IP6 instance. 807a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 808a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] Private The pointer of PING6_PRIVATE_DATA. 809a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 810a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 811a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianVOID 812a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6DestoryIp6Instance ( 813a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN PING6_PRIVATE_DATA *Private 814a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 815a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 816a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 817a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_SERVICE_BINDING_PROTOCOL *Ip6Sb; 818a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 819a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian gBS->CloseProtocol ( 820a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Ip6ChildHandle, 821a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &gEfiIp6ProtocolGuid, 822a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->ImageHandle, 823a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Ip6ChildHandle 824a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 825a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 826a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->HandleProtocol ( 827a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->NicHandle, 828a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &gEfiIp6ServiceBindingProtocolGuid, 829a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (VOID **) &Ip6Sb 830a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 831a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 832a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (!EFI_ERROR(Status)) { 833a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle); 834a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 835a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 836a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 837a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 838a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian The Ping6 Process. 839a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 840a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] ImageHandle The firmware allocated handle for the UEFI image. 841a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] SendNumber The send request count. 842a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] BufferSize The send buffer size. 843a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] SrcAddress The source IPv6 address. 844a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] DstAddress The destination IPv6 address. 845a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 846a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS The ping6 processed successfullly. 847a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval others The ping6 processed unsuccessfully. 848a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 849a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 850a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 851a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianPing6 ( 852a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_HANDLE ImageHandle, 853a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT32 SendNumber, 854a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN UINT32 BufferSize, 855a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_IPv6_ADDRESS *SrcAddress, 856a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_IPv6_ADDRESS *DstAddress 857a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 858a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 859a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 860a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_INPUT_KEY Key; 861a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_PRIVATE_DATA *Private; 862a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_ICMP6_TX_INFO *TxInfo; 863a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian LIST_ENTRY *Entry; 864a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian LIST_ENTRY *NextEntry; 865a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 866a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private = AllocateZeroPool (sizeof (PING6_PRIVATE_DATA)); 867a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 868a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ASSERT (Private != NULL); 869a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 870a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->ImageHandle = ImageHandle; 871a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->SendNum = SendNumber; 872a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->BufferSize = BufferSize; 873a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttMin = 0xFFFF; 874a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Status = EFI_NOT_READY; 875a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 876a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian InitializeListHead (&Private->TxList); 877a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 878a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IP6_COPY_ADDRESS (&Private->SrcAddress, SrcAddress); 879a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IP6_COPY_ADDRESS (&Private->DstAddress, DstAddress); 880a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 881a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 882a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Open and configure a ip6 instance for ping6. 883a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 884a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ping6CreateIp6Instance (Private); 885a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 886a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 887a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 888a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 889a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 890a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Print the command line itself. 891a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 892a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_START), mHiiHandle, mIp6DstString, Private->BufferSize); 893a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 894a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Create a ipv6 token to receive the first icmp6 echo reply packet. 895a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 896a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ping6ReceiveEchoReply (Private); 897a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 898a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 899a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 900a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 901a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 902a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Create and start timer to send icmp6 echo request packet per second. 903a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 904a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->CreateEvent ( 905a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EVT_TIMER | EVT_NOTIFY_SIGNAL, 906a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TPL_CALLBACK, 907a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6OnTimerRoutine, 908a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private, 909a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &Private->Timer 910a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 911a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 912a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 913a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 914a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 915a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 916a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Create a ipv6 token to send the first icmp6 echo request packet. 917a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 918a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ping6SendEchoRequest (Private); 919a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 920a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // EFI_NOT_READY for IPsec is enable and IKE is not established. 921a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 922a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) { 923a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if(Status == EFI_NOT_FOUND) { 924a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_NOSOURCE_INDOMAIN), mHiiHandle, mIp6DstString); 925a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 926a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 927a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 928a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 929a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 930a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gBS->SetTimer ( 931a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Timer, 932a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TimerPeriodic, 933a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian PING6_ONE_SECOND 934a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 935a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 936a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 937a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 938a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 939a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 940a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Control the ping6 process by two factors: 941a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1. Hot key 942a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 2. Private->Status 943a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 2.1. success means all icmp6 echo request packets get reply packets. 944a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 2.2. timeout means the last icmp6 echo reply request timeout to get reply. 945a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 2.3. noready means ping6 process is on-the-go. 946a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 947a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian while (Private->Status == EFI_NOT_READY) { 948a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Ip6->Poll (Private->Ip6); 949a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 950a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 951a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Terminate the ping6 process by 'esc' or 'ctl-c'. 952a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 953a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); 954a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 955a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (!EFI_ERROR(Status)) { 956a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if ((Key.UnicodeChar == 0x1b) || (Key.UnicodeChar == 0x03) || 957a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_ESC))) { 958a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_STAT; 959a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 960a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 961a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 962a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 963a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianON_STAT: 964a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 965a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Display the statistics in all. 966a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 967a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian gBS->SetTimer (Private->Timer, TimerCancel, 0); 968a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 969a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->TxCount != 0) { 970a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx ( 971a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian -1, 972a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian -1, 973a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NULL, 974a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian STRING_TOKEN (STR_PING6_STAT), 975a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mHiiHandle, 976a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->TxCount, 977a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RxCount, 978a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (100 * (Private->TxCount - Private->RxCount)) / Private->TxCount, 979a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttSum 980a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 981a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 982a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 983a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->RxCount != 0) { 984a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx ( 985a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian -1, 986a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian -1, 987a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NULL, 988a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian STRING_TOKEN (STR_PING6_RTT), 989a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mHiiHandle, 990a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttMin, 991a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttMax, 992a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->RttSum / Private->RxCount 993a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 994a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 995a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 996a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianON_EXIT: 997a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 998a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private != NULL) { 999a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Private->Status = EFI_ABORTED; 1000a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1001a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) { 1002a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian TxInfo = BASE_CR (Entry, PING6_ICMP6_TX_INFO, Link); 1003a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1004a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Private->Ip6->Cancel (Private->Ip6, TxInfo->Token); 1005a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1006a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian RemoveEntryList (&TxInfo->Link); 1007a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6DestroyTxInfo (TxInfo); 1008a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1009a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1010a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->Timer != NULL) { 1011a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian gBS->CloseEvent (Private->Timer); 1012a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1013a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1014a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->Ip6 != NULL) { 1015a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Private->Ip6->Cancel (Private->Ip6, &Private->RxToken); 1016a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1017a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1018a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->RxToken.Event != NULL) { 1019a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian gBS->CloseEvent (Private->RxToken.Event); 1020a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1021a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1022a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (Private->Ip6ChildHandle != NULL) { 1023a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Ping6DestoryIp6Instance (Private); 1024a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1025a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1026a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian FreePool (Private); 1027a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1028a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1029a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Status; 1030a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 1031a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1032a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian/** 1033a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian This is the declaration of an EFI image entry point. This entry point is 1034a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including 1035a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian both device drivers and bus drivers. 1036a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1037a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian The entry point for the Ping6 application that parses the command line input and calls the Ping6 process. 1038a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1039a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] ImageHandle The firmware allocated handle for the UEFI image. 1040a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @param[in] SystemTable A pointer to the EFI System Table. 1041a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1042a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_SUCCESS The operation completed successfully. 1043a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval EFI_INVALID_PARAMETETR Input parameters combination is invalid. 1044a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian @retval Others Some errors occur. 1045a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1046a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian**/ 1047a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFI_STATUS 1048a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianEFIAPI 1049a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianInitializePing6 ( 1050a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_HANDLE ImageHandle, 1051a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian IN EFI_SYSTEM_TABLE *SystemTable 1052a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ) 1053a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian{ 1054a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_STATUS Status; 1055a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IPv6_ADDRESS DstAddress; 1056a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian EFI_IPv6_ADDRESS SrcAddress; 1057a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINT64 BufferSize; 1058a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINTN SendNumber; 1059a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian LIST_ENTRY *ParamPackage; 1060a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian CONST CHAR16 *ValueStr; 1061a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian CONST CHAR16 *ValueStrPtr; 1062a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian UINTN NonOptionCount; 1063a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1064a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1065a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Register our string package with HII and return the handle to it. 1066a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1067a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, Ping6Strings, NULL); 1068a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ASSERT (mHiiHandle != NULL); 1069a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1070a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = ShellCommandLineParseEx (Ping6ParamList, &ParamPackage, NULL, TRUE, FALSE); 1071a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR(Status)) { 1072a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), mHiiHandle); 1073a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1074a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1075a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1076a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (ShellCommandLineGetFlag (ParamPackage, L"-?")) { 1077a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_HELP), mHiiHandle); 1078a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1079a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1080a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1081a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian SendNumber = 10; 1082a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian BufferSize = 16; 1083a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1084a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1085a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Parse the paramter of count number. 1086a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1087a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStr = ShellCommandLineGetValue (ParamPackage, L"-n"); 1088a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStrPtr = ValueStr; 1089a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (ValueStr != NULL) { 1090a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian SendNumber = ShellStrToUintn (ValueStrPtr); 1091a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1092a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1093a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // ShellStrToUintn will return 0 when input is 0 or an invalid input string. 1094a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1095a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if ((SendNumber == 0) || (SendNumber > PING6_MAX_SEND_NUMBER)) { 1096a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_SEND_NUMBER), mHiiHandle, ValueStr); 1097a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_INVALID_PARAMETER; 1098a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1099a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1100a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1101a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1102a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Parse the paramter of buffer size. 1103a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1104a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l"); 1105a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStrPtr = ValueStr; 1106a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (ValueStr != NULL) { 1107a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian BufferSize = ShellStrToUintn (ValueStrPtr); 1108a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1109a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1110a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // ShellStrToUintn will return 0 when input is 0 or an invalid input string. 1111a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1112a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if ((BufferSize < 16) || (BufferSize > PING6_MAX_BUFFER_SIZE)) { 1113a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_BUFFER_SIZE), mHiiHandle, ValueStr); 1114a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_INVALID_PARAMETER; 1115a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1116a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1117a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1118a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1119a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ZeroMem (&SrcAddress, sizeof (EFI_IPv6_ADDRESS)); 1120a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ZeroMem (&DstAddress, sizeof (EFI_IPv6_ADDRESS)); 1121a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1122a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1123a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Parse the paramter of source ip address. 1124a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1125a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s"); 1126a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStrPtr = ValueStr; 1127a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (ValueStr != NULL) { 1128a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mIp6SrcString = ValueStr; 1129a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = NetLibStrToIp6 (ValueStrPtr, &SrcAddress); 1130a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 1131a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP), mHiiHandle, ValueStr); 1132a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_INVALID_PARAMETER; 1133a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1134a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1135a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1136a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1137a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Parse the paramter of destination ip address. 1138a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1139a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian NonOptionCount = ShellCommandLineGetCount(); 1140a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32)(NonOptionCount-1)); 1141a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (NonOptionCount != 2) { 1142a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_INPUT), mHiiHandle); 1143a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_INVALID_PARAMETER; 1144a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1145a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1146a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ValueStrPtr = ValueStr; 1147a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (ValueStr != NULL) { 1148a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian mIp6DstString = ValueStr; 1149a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = NetLibStrToIp6 (ValueStrPtr, &DstAddress); 1150a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR (Status)) { 1151a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PING6_INVALID_IP), mHiiHandle, ValueStr); 1152a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = EFI_INVALID_PARAMETER; 1153a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1154a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1155a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1156a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1157a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Get frequency to calculate the time from ticks. 1158a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1159a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ping6GetFrequency (); 1160a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1161a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian if (EFI_ERROR(Status)) { 1162a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian goto ON_EXIT; 1163a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian } 1164a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1165a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // Enter into ping6 process. 1166a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian // 1167a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian Status = Ping6 ( 1168a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ImageHandle, 1169a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (UINT32)SendNumber, 1170a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian (UINT32)BufferSize, 1171a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &SrcAddress, 1172a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian &DstAddress 1173a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ); 1174a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian 1175a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtianON_EXIT: 1176a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian ShellCommandLineFreeVarList (ParamPackage); 1177a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian HiiRemovePackages (mHiiHandle); 1178a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian return Status; 1179a3bcde70e6dc69000f85cc5deee98101d2ae200ahhtian} 1180