58 lines
1.9 KiB
HolyC
58 lines
1.9 KiB
HolyC
I64 @shell_cmd_ping(@shell* sh, I64 argc, U8** argv)
|
|
{
|
|
if (argc < 2) {
|
|
Stdio.WriteLine(sh, "ping: usage error: Destination address required\n");
|
|
return 1;
|
|
}
|
|
U8* host = argv[1];
|
|
if (!host || !StrLen(host)) {
|
|
Stdio.WriteLine(sh, "Invalid host specified\n");
|
|
return PING_ERR_INVALID_HOST;
|
|
}
|
|
I64 count = 4;
|
|
|
|
U32 addr = @dns_query(host);
|
|
if (addr == U32_MAX) {
|
|
Stdio.WriteLine(sh, "Host not found\n");
|
|
return PING_ERR_HOST_NOT_FOUND;
|
|
}
|
|
|
|
U16 iden = (RandU16 * SysTimerRead) & 0xFFFF;
|
|
I64 start_jiffies;
|
|
U32 reply = NULL;
|
|
I64 res = 0;
|
|
U16 seq = 0;
|
|
I64 loss = 0;
|
|
|
|
IcmpRequest* request = CAlloc(sizeof(IcmpRequest), Fs->code_heap);
|
|
|
|
Stdio.WriteLine(sh, "PING %s (%d.%d.%d.%d): %d data bytes\n",
|
|
host, addr.u8[3], addr.u8[2], addr.u8[1], addr.u8[0], PING_PAYLOAD_SIZE);
|
|
|
|
I64 i;
|
|
for (i = 0; i < count && !sh->break; i++) {
|
|
start_jiffies = cnts.jiffies;
|
|
reply = @icmp_echo_request(addr, iden, seq, request, i);
|
|
if (!reply) {
|
|
Stdio.WriteLine(sh, "Request timeout for icmp_seq %d\n", seq);
|
|
++loss;
|
|
res = 1;
|
|
} else {
|
|
Stdio.WriteLine(sh, "%d bytes from %d.%d.%d.%d: icmp_seq=%d ttl=%d time=%d ms\n",
|
|
reply.u16[1], addr.u8[3], addr.u8[2], addr.u8[1], addr.u8[0], seq, reply.u16[0], cnts.jiffies - start_jiffies);
|
|
}
|
|
while (cnts.jiffies < start_jiffies + 1000 && i < (count - 1) && !sh->break)
|
|
Sleep(1);
|
|
++seq;
|
|
}
|
|
|
|
Free(request);
|
|
|
|
Stdio.WriteLine(sh, "--- %d.%d.%d.%d ping statistics ---\n", addr.u8[3], addr.u8[2], addr.u8[1], addr.u8[0]);
|
|
Stdio.WriteLine(sh, "%d packets transmitted, %d packets received, %0f",
|
|
seq, seq - loss, (loss * 1.0 / seq * 1.0) * 100);
|
|
Stdio.WriteLine(sh, "%c", 37);
|
|
Stdio.WriteLine(sh, " packet loss\n");
|
|
|
|
return res;
|
|
}
|