mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2025-01-13 16:16:31 +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 "Utilities/BST"
|
||||||
#include "Protocols/UDP/MakeUDP"
|
#include "Protocols/UDP/MakeUDP"
|
||||||
#include "Protocols/DNS"
|
#include "Protocols/DNS"
|
||||||
|
#include "Utilities/Ping"
|
||||||
|
|
||||||
#include "Protocols/TCP/MakeTCP"
|
#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)
|
U16 ICMPChecksum(U8 *buf, I64 size)
|
||||||
{
|
{
|
||||||
U64 i, sum = 0;
|
U64 i, sum = 0;
|
||||||
|
@ -73,14 +86,12 @@ U0 ICMPReplySend(U32 destination_ip_address,
|
||||||
U0 ICMPRequestSend(U32 destination_ip_address,
|
U0 ICMPRequestSend(U32 destination_ip_address,
|
||||||
U16 identifier,
|
U16 identifier,
|
||||||
U16 sequence_number,
|
U16 sequence_number,
|
||||||
U16 request_checksum,
|
|
||||||
U8 *payload,
|
U8 *payload,
|
||||||
I64 length)
|
I64 length)
|
||||||
{
|
{
|
||||||
U8 *icmp_frame;
|
U8 *icmp_frame;
|
||||||
I64 de_index;
|
I64 de_index;
|
||||||
CICMPHeader *header;
|
CICMPHeader *header;
|
||||||
no_warn request_checksum; // TODO: needed? remove arg?
|
|
||||||
|
|
||||||
de_index = IPV4PacketAllocate(&icmp_frame,
|
de_index = IPV4PacketAllocate(&icmp_frame,
|
||||||
IP_PROTOCOL_ICMP,
|
IP_PROTOCOL_ICMP,
|
||||||
|
@ -131,10 +142,16 @@ I64 ICMPHandler(CIPV4Packet *packet)
|
||||||
packet->data + sizeof(CICMPHeader), // Data payload at IPV4Packet data location after the ICMP header
|
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.
|
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
|
else
|
||||||
NetWarn("ICMP HANDLER: Unhandled ICMP packet. type, code: 0x%X, 0x%X", header->type, header->code);
|
NetWarn("ICMP HANDLER: Unhandled ICMP packet. type, code: 0x%X, 0x%X", header->type, header->code);
|
||||||
|
|
||||||
NetLog("ICMP HANDLER: Exiting.");
|
NetLog("ICMP HANDLER: Exiting.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICMPInit;
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
Cd(__DIR__);;
|
Cd(__DIR__);;
|
||||||
#include "Load"
|
#include "Load"
|
||||||
NetConfigure;
|
NetConfigure;
|
||||||
|
|
|
@ -7,7 +7,7 @@ U0 ICMPTest()
|
||||||
for (i = 0; i < 64; i++)
|
for (i = 0; i < 64; i++)
|
||||||
b[i] = RandU8;
|
b[i] = RandU8;
|
||||||
|
|
||||||
ICMPRequestSend(a, 0, 0, 0, b, 64);
|
ICMPRequestSend(a, 0, 0, b, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
ICMPTest;
|
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