12#define PING6_DEFAULT_TIMEOUT 5000
13#define PING6_MAX_SEND_NUMBER 10000
14#define PING6_MAX_BUFFER_SIZE 32768
15#define PING6_ONE_SECOND 10000000
16#define STALL_1_MILLI_SECOND 1000
92CONST CHAR16 *mIp6DstString;
93CONST CHAR16 *mIp6SrcString;
110 UINT32 *RttTimerTick;
112 RttTimerTick = (UINT32 *)Context;
139 Status =
gBS->CreateEvent (
140 EVT_TIMER | EVT_NOTIFY_SIGNAL,
146 if (EFI_ERROR (Status)) {
150 OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
151 Status =
gBS->SetTimer (
156 if (EFI_ERROR (Status)) {
157 gBS->CloseEvent (TimerEvent);
161 while (RttTimerTick < 10) {
162 gBS->Stall (STALL_1_MILLI_SECOND);
166 gBS->RestoreTPL (OldTpl);
169 gBS->CloseEvent (TimerEvent);
171 return StallCounter / RttTimerTick;
191 if (Private->TimerPeriod == 0) {
195 Private->RttTimerTick = 0;
196 Status =
gBS->CreateEvent (
197 EVT_TIMER | EVT_NOTIFY_SIGNAL,
200 &Private->RttTimerTick,
203 if (EFI_ERROR (Status)) {
207 Status =
gBS->SetTimer (
212 if (EFI_ERROR (Status)) {
213 gBS->CloseEvent (Private->RttTimer);
231 if (Private->RttTimer !=
NULL) {
233 gBS->CloseEvent (Private->RttTimer);
249 return Private->RttTimerTick;
273 return (End - Begin) * Private->TimerPeriod;
291 ASSERT (TxInfo !=
NULL);
293 if (TxInfo->Token !=
NULL) {
294 if (TxInfo->Token->Event !=
NULL) {
295 gBS->CloseEvent (TxInfo->Token->Event);
298 TxData = TxInfo->Token->Packet.TxData;
299 if (TxData !=
NULL) {
310 if (FragData !=
NULL) {
342 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
345 if ((TxInfo->SequenceNum == Packet->SequenceNum) && (TxInfo->TimeStamp == Packet->TimeStamp)) {
353 return EFI_NOT_FOUND;
399 if (Private->Status == EFI_ABORTED) {
403 RxToken = &Private->RxToken;
404 RxData = RxToken->Packet.
RxData;
408 if (RxData->
Header->NextHeader != IP6_ICMP) {
412 if (!IP6_IS_MULTICAST (&Private->DstAddress) &&
413 !EFI_IP6_EQUAL (&RxData->
Header->SourceAddress, &Private->DstAddress))
418 if ((Reply->Type != ICMP_V6_ECHO_REPLY) || (Reply->Code != 0)) {
422 if (PayLoad != Private->BufferSize) {
430 if (EFI_ERROR (Status)) {
439 Private->RttSum += Rtt;
440 Private->RttMin = Private->RttMin > Rtt ? Rtt : Private->RttMin;
441 Private->RttMax = Private->RttMax < Rtt ? Rtt : Private->RttMax;
448 gShellNetwork2HiiHandle,
454 Rtt + Private->TimerPeriod
459 if (Private->RxCount < Private->SendNum) {
463 RxToken->
Status = EFI_ABORTED;
465 Status = Private->Ip6->Receive (Private->Ip6, RxToken);
467 if (EFI_ERROR (Status)) {
469 Private->Status = EFI_ABORTED;
498 IN UINT16 SequenceNum
508 if (Request ==
NULL) {
517 Request->SequenceNum = SequenceNum;
518 Request->TimeStamp = TimeStamp;
519 Request->Identifier = 0;
524 Request->Checksum = 0;
528 if (TxData ==
NULL) {
552 Token->
Status = EFI_ABORTED;
553 Token->Packet.
TxData = TxData;
555 Status =
gBS->CreateEvent (
563 if (EFI_ERROR (Status)) {
593 if (TxInfo ==
NULL) {
594 return EFI_OUT_OF_RESOURCES;
598 TxInfo->SequenceNum = (UINT16)(Private->TxCount + 1);
606 if (TxInfo->Token ==
NULL) {
608 return EFI_OUT_OF_RESOURCES;
611 Status = Private->Ip6->Transmit (Private->Ip6, TxInfo->Token);
613 if (EFI_ERROR (Status)) {
642 Status =
gBS->CreateEvent (
647 &Private->RxToken.Event
650 if (EFI_ERROR (Status)) {
654 Private->RxToken.Status = EFI_NOT_READY;
656 Status = Private->Ip6->Receive (Private->Ip6, &Private->RxToken);
657 if (EFI_ERROR (Status)) {
690 if (Private->TxCount < Private->SendNum) {
692 if (Private->TxCount != 0) {
693 if (EFI_ERROR (Status)) {
702 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
709 if (Time > PING6_DEFAULT_TIMEOUT) {
710 if (EFI_ERROR (TxInfo->Token->
Status)) {
711 Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);
722 if (
IsListEmpty (&Private->TxList) && (Private->TxCount == Private->SendNum)) {
726 Private->Status = EFI_TIMEOUT;
752 BOOLEAN UnspecifiedSrc;
763 UnspecifiedSrc =
FALSE;
772 Status =
gBS->LocateHandleBuffer (
774 &gEfiIp6ServiceBindingProtocolGuid,
779 if (EFI_ERROR (Status) || (HandleNum == 0)) {
787 UnspecifiedSrc =
TRUE;
795 Status = EFI_INVALID_PARAMETER;
802 for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {
807 if (UnspecifiedSrc) {
820 Status =
gBS->HandleProtocol (
821 HandleBuffer[HandleIndex],
822 &gEfiIp6ServiceBindingProtocolGuid,
825 if (EFI_ERROR (Status)) {
833 Status =
gBS->HandleProtocol (
834 HandleBuffer[HandleIndex],
835 &gEfiIp6ConfigProtocolGuid,
839 if (EFI_ERROR (Status)) {
846 Status = Ip6Cfg->GetData (
853 if (Status != EFI_BUFFER_TOO_SMALL) {
860 if (IfInfo ==
NULL) {
861 Status = EFI_OUT_OF_RESOURCES;
868 Status = Ip6Cfg->GetData (
875 if (EFI_ERROR (Status)) {
886 if (UnspecifiedSrc) {
891 CopyMem (&Private->SrcAddress, Addr, sizeof (Private->SrcAddress));
894 }
else if (EFI_IP6_EQUAL (&Private->SrcAddress, Addr)) {
902 if (AddrIndex < IfInfo->AddressInfoCount) {
917 if (HandleIndex == HandleNum) {
919 Status = EFI_NOT_FOUND;
923 Private->NicHandle = HandleBuffer[HandleIndex];
925 ASSERT (Ip6Sb !=
NULL);
926 Status = Ip6Sb->CreateChild (Ip6Sb, &Private->Ip6ChildHandle);
928 if (EFI_ERROR (Status)) {
932 Status =
gBS->OpenProtocol (
933 Private->Ip6ChildHandle,
934 &gEfiIp6ProtocolGuid,
935 (VOID **)&Private->Ip6,
936 Private->ImageHandle,
937 Private->Ip6ChildHandle,
938 EFI_OPEN_PROTOCOL_GET_PROTOCOL
940 if (EFI_ERROR (Status)) {
959 IP6_COPY_ADDRESS (&Ip6Config.
StationAddress, &Private->SrcAddress);
963 Status = Private->Ip6->Configure (Private->Ip6, &Ip6Config);
965 if (EFI_ERROR (Status)) {
973 if (HandleBuffer !=
NULL) {
977 if (IfInfo !=
NULL) {
981 if ((Ip6Sb !=
NULL) && (Private->Ip6ChildHandle !=
NULL)) {
982 Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);
1002 gBS->CloseProtocol (
1003 Private->Ip6ChildHandle,
1004 &gEfiIp6ProtocolGuid,
1005 Private->ImageHandle,
1006 Private->Ip6ChildHandle
1009 Status =
gBS->HandleProtocol (
1011 &gEfiIp6ServiceBindingProtocolGuid,
1015 if (!EFI_ERROR (Status)) {
1016 Ip6Sb->DestroyChild (Ip6Sb, Private->Ip6ChildHandle);
1036 IN UINT32 SendNumber,
1037 IN UINT32 BufferSize,
1053 if (Private ==
NULL) {
1059 Private->ImageHandle = ImageHandle;
1060 Private->SendNum = SendNumber;
1061 Private->BufferSize = BufferSize;
1062 Private->RttMin = ~((UINT64)(0x0));
1063 Private->Status = EFI_NOT_READY;
1067 IP6_COPY_ADDRESS (&Private->SrcAddress, SrcAddress);
1068 IP6_COPY_ADDRESS (&Private->DstAddress, DstAddress);
1075 if (EFI_ERROR (Status)) {
1089 if (EFI_ERROR (Status)) {
1097 Status =
gBS->CreateEvent (
1098 EVT_TIMER | EVT_NOTIFY_SIGNAL,
1105 if (EFI_ERROR (Status)) {
1114 if (EFI_ERROR (Status)) {
1126 if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
1128 if (Status == EFI_NOT_FOUND) {
1135 Status =
gBS->SetTimer (
1141 if (EFI_ERROR (Status)) {
1154 while (Private->Status == EFI_NOT_READY) {
1155 Private->Ip6->Poll (Private->Ip6);
1162 if (!EFI_ERROR (Status)) {
1163 if ((Key.UnicodeChar == 0x1b) || (Key.UnicodeChar == 0x03) ||
1164 ((Key.UnicodeChar == 0) && (Key.ScanCode == SCAN_ESC)))
1177 if (Private->TxCount != 0) {
1183 gShellNetwork2HiiHandle,
1186 (100 * (Private->TxCount - Private->RxCount)) / Private->TxCount,
1191 if (Private->RxCount != 0) {
1197 gShellNetwork2HiiHandle,
1199 Private->RttMin + Private->TimerPeriod,
1201 Private->RttMax + Private->TimerPeriod,
1209 if (Private !=
NULL) {
1210 Private->Status = EFI_ABORTED;
1212 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->TxList) {
1215 Status = Private->Ip6->Cancel (Private->Ip6, TxInfo->Token);
1223 if (Private->Timer !=
NULL) {
1224 gBS->CloseEvent (Private->Timer);
1227 if (Private->Ip6 !=
NULL) {
1228 Status = Private->Ip6->Cancel (Private->Ip6, &Private->RxToken);
1232 gBS->CloseEvent (Private->RxToken.
Event);
1235 if (Private->Ip6ChildHandle !=
NULL) {
1269 CONST CHAR16 *ValueStr;
1270 CONST CHAR16 *ValueStrPtr;
1271 UINTN NonOptionCount;
1272 CHAR16 *ProblemParam;
1274 ProblemParam =
NULL;
1278 if (EFI_ERROR (Status)) {
1291 ValueStrPtr = ValueStr;
1292 if (ValueStr !=
NULL) {
1298 if ((SendNumber == 0) || (SendNumber > PING6_MAX_SEND_NUMBER)) {
1309 ValueStrPtr = ValueStr;
1310 if (ValueStr !=
NULL) {
1316 if ((BufferSize < 16) || (BufferSize > PING6_MAX_BUFFER_SIZE)) {
1330 ValueStrPtr = ValueStr;
1331 if (ValueStr !=
NULL) {
1332 mIp6SrcString = ValueStr;
1334 if (EFI_ERROR (Status)) {
1346 if (NonOptionCount != 2) {
1352 ValueStrPtr = ValueStr;
1353 if (ValueStr !=
NULL) {
1354 mIp6DstString = ValueStr;
1356 if (EFI_ERROR (Status)) {
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ICMP_V6_ECHO_REQUEST
@ Ip6ConfigDataTypeInterfaceInfo
#define BASE_CR(Record, TYPE, Field)
@ SHELL_INVALID_PARAMETER
BOOLEAN EFIAPI NetIp6IsLinkLocalAddr(IN EFI_IPv6_ADDRESS *Ip6)
BOOLEAN EFIAPI NetIp6IsUnspecifiedAddr(IN EFI_IPv6_ADDRESS *Ip6)
EFI_STATUS EFIAPI NetLibDetectMediaWaitTimeout(IN EFI_HANDLE ServiceHandle, IN UINT64 Timeout, OUT EFI_STATUS *MediaState)
EFI_STATUS EFIAPI NetLibStrToIp6(IN CONST CHAR16 *String, OUT EFI_IPv6_ADDRESS *Ip6Address)
VOID Ping6DestroyTxInfo(IN PING6_ICMP6_TX_INFO *TxInfo)
UINT32 Ping6CalculateTick(IN PING6_PRIVATE_DATA *Private, IN UINT32 Begin, IN UINT32 End)
UINT32 Ping6GetTimerPeriod(VOID)
VOID Ping6DestroyIpInstance(IN PING6_PRIVATE_DATA *Private)
EFI_STATUS Ping6OnReceiveEchoReply(IN PING6_PRIVATE_DATA *Private)
EFI_IP6_COMPLETION_TOKEN * Ping6GenerateToken(IN PING6_PRIVATE_DATA *Private, IN UINT32 TimeStamp, IN UINT16 SequenceNum)
EFI_STATUS Ping6InitRttTimer(IN PING6_PRIVATE_DATA *Private)
EFI_STATUS Ping6CreateIpInstance(IN PING6_PRIVATE_DATA *Private)
VOID Ping6FreeRttTimer(IN PING6_PRIVATE_DATA *Private)
EFI_STATUS Ping6SendEchoRequest(IN PING6_PRIVATE_DATA *Private)
SHELL_STATUS ShellPing6(IN EFI_HANDLE ImageHandle, IN UINT32 SendNumber, IN UINT32 BufferSize, IN EFI_IPv6_ADDRESS *SrcAddress, IN EFI_IPv6_ADDRESS *DstAddress)
UINT32 Ping6ReadTime(IN PING6_PRIVATE_DATA *Private)
EFI_STATUS Ping6OnMatchEchoReply(IN PING6_PRIVATE_DATA *Private, IN ICMP6_ECHO_REQUEST_REPLY *Packet)
SHELL_STATUS EFIAPI ShellCommandRunPing6(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID EFIAPI Ping6OnEchoReplyReceived6(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI Ping6OnEchoRequestSent6(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI Ping6RttTimerTickRoutine(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI Ping6OnTimerRoutine6(IN EFI_EVENT Event, IN VOID *Context)
CONST CHAR16 *EFIAPI ShellCommandLineGetValue(IN CONST LIST_ENTRY *CheckPackage, IN CHAR16 *KeyString)
UINTN EFIAPI ShellStrToUintn(IN CONST CHAR16 *String)
EFI_STATUS EFIAPI ShellPrintHiiEx(IN INT32 Col OPTIONAL, IN INT32 Row OPTIONAL, IN CONST CHAR8 *Language OPTIONAL, IN CONST EFI_STRING_ID HiiFormatStringId, IN CONST EFI_HII_HANDLE HiiFormatHandle,...)
@ TypeValue
A flag that has some data following it with a space (IE "-a 1").
@ TypeFlag
A flag that is present or not present only (IE "-a").
EFI_STATUS EFIAPI ShellCommandLineParseEx(IN CONST SHELL_PARAM_ITEM *CheckList, OUT LIST_ENTRY **CheckPackage, OUT CHAR16 **ProblemParam OPTIONAL, IN BOOLEAN AutoPageBreak, IN BOOLEAN AlwaysAllowNumbers)
VOID EFIAPI ShellCommandLineFreeVarList(IN LIST_ENTRY *CheckPackage)
CONST CHAR16 *EFIAPI ShellCommandLineGetRawValue(IN CONST LIST_ENTRY *CONST CheckPackage, IN UINTN Position)
UINTN EFIAPI ShellCommandLineGetCount(IN CONST LIST_ENTRY *CheckPackage)
VOID * FragmentBuffer
Pointer to fragment data. This field may not be set to NULL.
UINT32 FragmentLength
Length of fragment data. This field may not be set to zero.
EFI_IP6_FRAGMENT_DATA FragmentTable[1]
EFI_IP6_FRAGMENT_DATA FragmentTable[1]
EFI_IP6_OVERRIDE_DATA * OverrideData
EFI_IPv6_ADDRESS Address
The IPv6 address.
EFI_IP6_RECEIVE_DATA * RxData
EFI_IP6_TRANSMIT_DATA * TxData
BOOLEAN AcceptAnyProtocol
EFI_IPv6_ADDRESS DestinationAddress
EFI_IPv6_ADDRESS StationAddress
BOOLEAN AcceptPromiscuous
EFI_IP6_ADDRESS_INFO * AddressInfo
EFI_SIMPLE_TEXT_INPUT_PROTOCOL * ConIn