mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-26 15:26:43 +00:00
Implement Ping network function.
This commit is contained in:
parent
28ab32e893
commit
9857b67377
5 changed files with 102 additions and 4 deletions
|
@ -18,6 +18,7 @@ Cd(__DIR__);;
|
|||
#include "Utilities/BST"
|
||||
#include "Protocols/UDP/MakeUDP"
|
||||
#include "Protocols/DNS"
|
||||
#include "Utilities/Ping"
|
||||
|
||||
#include "Protocols/TCP/MakeTCP"
|
||||
|
||||
|
|
|
@ -13,6 +13,19 @@ class CICMPHeader
|
|||
};
|
||||
|
||||
|
||||
/* global variable containing last reply ICMP header received,
|
||||
Ping() checks this to make ping report.
|
||||
*/
|
||||
CICMPHeader icmp_reply;
|
||||
|
||||
|
||||
U0 ICMPInit()
|
||||
{
|
||||
MemSet(&icmp_reply, 0, sizeof(CICMPHeader));
|
||||
}
|
||||
|
||||
NetQueueInit;
|
||||
|
||||
U16 ICMPChecksum(U8 *buf, I64 size)
|
||||
{
|
||||
U64 i, sum = 0;
|
||||
|
@ -73,14 +86,12 @@ U0 ICMPReplySend(U32 destination_ip_address,
|
|||
U0 ICMPRequestSend(U32 destination_ip_address,
|
||||
U16 identifier,
|
||||
U16 sequence_number,
|
||||
U16 request_checksum,
|
||||
U8 *payload,
|
||||
I64 length)
|
||||
{
|
||||
U8 *icmp_frame;
|
||||
I64 de_index;
|
||||
CICMPHeader *header;
|
||||
no_warn request_checksum; // TODO: needed? remove arg?
|
||||
|
||||
de_index = IPV4PacketAllocate(&icmp_frame,
|
||||
IP_PROTOCOL_ICMP,
|
||||
|
@ -131,6 +142,10 @@ I64 ICMPHandler(CIPV4Packet *packet)
|
|||
packet->data + sizeof(CICMPHeader), // Data payload at IPV4Packet data location after the ICMP header
|
||||
packet->length - sizeof(CICMPHeader));// Payload length is size of packet after dropping header.
|
||||
}
|
||||
else if (header->type == ICMP_TYPE_ECHO_REPLY && header->code == ICMP_CODE_ECHO)
|
||||
{ // save the reply to the global ICMP reply header
|
||||
MemCopy(&icmp_reply, header, sizeof(CICMPHeader));
|
||||
}
|
||||
else
|
||||
NetWarn("ICMP HANDLER: Unhandled ICMP packet. type, code: 0x%X, 0x%X", header->type, header->code);
|
||||
|
||||
|
@ -138,3 +153,5 @@ I64 ICMPHandler(CIPV4Packet *packet)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ICMPInit;
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
Cd(__DIR__);;
|
||||
#include "Load"
|
||||
NetConfigure;
|
||||
|
|
|
@ -7,7 +7,7 @@ U0 ICMPTest()
|
|||
for (i = 0; i < 64; i++)
|
||||
b[i] = RandU8;
|
||||
|
||||
ICMPRequestSend(a, 0, 0, 0, b, 64);
|
||||
ICMPRequestSend(a, 0, 0, b, 64);
|
||||
}
|
||||
|
||||
ICMPTest;
|
79
src/Home/Net/Utilities/Ping.ZC
Executable file
79
src/Home/Net/Utilities/Ping.ZC
Executable file
|
@ -0,0 +1,79 @@
|
|||
I64 Ping(U8 *hostname, I64 timeout=JIFFY_FREQ)
|
||||
{
|
||||
U32 addr;
|
||||
CAddressInfo *current;
|
||||
CAddressInfo *result = NULL;
|
||||
I64 error;
|
||||
I64 i = 0, t, delay, sent = 0, min_delay = I64_MAX, max_delay = I64_MIN, sum_delay = 0;
|
||||
CSocketAddressIPV4 *ipv4_address;
|
||||
U16 sequence_number = 1, identifier = RandU16, count = 0;
|
||||
U8 *payload;
|
||||
|
||||
if (!IPV4AddressParse(hostname, &addr))
|
||||
{
|
||||
error = DNSAddressInfoGet(hostname, NULL, &result);
|
||||
if (error < 0)
|
||||
{
|
||||
NetErr("Ping: Failed at DNS Get Address Info.");
|
||||
return -1;
|
||||
}
|
||||
current = result;
|
||||
while (current)
|
||||
{
|
||||
if (current->family == AF_INET)
|
||||
{
|
||||
ipv4_address = current->address;
|
||||
addr = EndianU32(ipv4_address->address); // why does it need EndianU32
|
||||
break;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (!current)
|
||||
{
|
||||
NetErr("Ping: Failed to resolve address.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (!CharScan)
|
||||
{
|
||||
payload = MAlloc(64);
|
||||
for (i = 0; i < 64; i++)
|
||||
payload[i] = RandU8;
|
||||
|
||||
"Sending Ping request #%d\n", sequence_number;
|
||||
ICMPRequestSend(addr, identifier, EndianU16(sequence_number), payload, 64);
|
||||
sent++;
|
||||
|
||||
t = counts.jiffies;
|
||||
while (counts.jiffies < t + timeout)
|
||||
{
|
||||
if (icmp_reply.identifier == identifier && icmp_reply.sequence_number == EndianU16(sequence_number))
|
||||
{
|
||||
delay = counts.jiffies - t;
|
||||
min_delay = MinI64(min_delay, delay);
|
||||
max_delay = MaxI64(max_delay, delay);
|
||||
sum_delay += delay; // sum up delays, divide through by count during stat report to get average
|
||||
count++;
|
||||
"\tReceived reply, delay: %dms\n", delay;
|
||||
break;
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
while (counts.jiffies < t + JIFFY_FREQ)
|
||||
Sleep(1);
|
||||
|
||||
sequence_number++;
|
||||
Free(payload);
|
||||
}
|
||||
|
||||
"\nPing Statistics:\n";
|
||||
"\tSent: %d, Received: %d, Lost: %d (%0.02f %%)\n", sent, count, sent - count, 100.0 - 100.0 * count / sent;
|
||||
if (min_delay != I64_MAX && max_delay != I64_MIN && sum_delay != 0)
|
||||
"\tMin: %dms, Max: %dms, Avg: %dms\n", min_delay, max_delay, sum_delay / count;
|
||||
"\n";
|
||||
|
||||
return count;
|
||||
|
||||
}
|
Loading…
Reference in a new issue