ZealOS/src/Home/Net/ICMP.CC

79 lines
1.8 KiB
HolyC
Raw Normal View History

//#include "IPV4"
#define ICMP_TYPE_ECHO_REPLY 0
#define ICMP_TYPE_ECHO_REQUEST 8
class CICMPHeader // Shrine's use of id and seq indicate this header is for Address Mask Reply/Request
{
U8 type;
U8 code;
U16 checksum;
U16 identifier;
U16 sequence_number;
};
I64 ICMPSendReply(U32 destination_ip_address,
2020-07-28 08:36:21 +01:00
U16 identifier,
U16 sequence_number,
U16 request_checksum,
U8 *payload,
I64 length)
{
U8 *frame;
I64 de_index;
CICMPHeader *header;
de_index = IPV4PacketAllocate(&frame,
2020-07-28 08:36:21 +01:00
IP_PROTOCOL_ICMP,
IPV4GetAddress(),
destination_ip_address,
sizeof(CICMPHeader) + length);
if (de_index < 0)
{
NetErr("ICMP SEND REPLY: Failed to allocate IPV4 packet.");
return de_index;
}
header = frame;
header->type = ICMP_TYPE_ECHO_REPLY;
header->code = 0; // why is 0 okay?
header->checksum = EndianU16(EndianU16(request_checksum) + 0x0800);
header->identifier = identifier;
header->sequence_number = sequence_number;
// TODO: header checksum is awful. Shrine says hack alert.
MemCopy(frame + sizeof(CICMPHeader), payload, length);
IPV4PacketFinish(de_index);
//return IPV4PacketFinish
}
I64 ICMPHandler(CIPV4Packet *packet)
{
CICMPHeader *header;
if (packet->length < sizeof(CICMPHeader))
{
NetErr("ICMP HANDLER: Caught wrong IPV4 length.");
return -1;
}
header = packet->data;
if (header->type == ICMP_TYPE_ECHO_REQUEST && header->code == 0)//why zero? need more #defines in here
{
ARPCachePut(packet->source_ip_address, packet->ethernet_frame->source_address);
ICMPSendReply(packet->source_ip_address,
2020-07-28 08:36:21 +01:00
header->identifier,
header->sequence_number,
header->checksum,
packet->data + sizeof(CICMPHeader),
packet->length - sizeof(CICMPHeader)); // TODO: ??
}
return 0;
}