Browse Source

SnailNet: port ICMP improvements from obecebo/erythros

v6
minexew 2 years ago
parent
commit
07a9a76108
  1. 1
      Adam/Net/Arp.HC
  2. 2
      Adam/Net/IPv4.HC
  3. 49
      Adam/Net/Icmp.HC

1
Adam/Net/Arp.HC

@ -90,6 +90,7 @@ I64 ArpHandler(CEthFrame* eth_frame) {
if (eth_frame->ethertype != ETHERTYPE_ARP)
return -1;
// FIXME[obecebo]: this blocks responding to ARP_REQUEST? [2019/08/05]
if (eth_frame->length < sizeof(CArpHeader))
return -1;

2
Adam/Net/IPv4.HC

@ -17,6 +17,7 @@ class CIPv4Packet {
U8* data;
I64 length;
I64 ttl;
};
class CIPv4Header {
@ -212,6 +213,7 @@ I64 IPv4ParsePacket(CIPv4Packet* packet_out, CEthFrame* eth_frame) {
packet_out->data = eth_frame->data + header_length;
packet_out->length = total_length - header_length;
packet_out->ttl = hdr->ttl;
return 0;
}

49
Adam/Net/Icmp.HC

@ -9,6 +9,31 @@ class CIcmpHeader {
U16 seq_number;
};
U64 *icmp_reply = CAlloc(sizeof(U64) * 65536);
U16 IcmpComputeChecksum(U8 *buf, I64 size)
{
I64 i;
U64 sum = 0;
for (i=0; i<size; i += 2)
{
sum += *buf(U16*);
buf += 2;
}
if (size - i > 0)
{
sum += *buf;
}
while ((sum>>16) != 0)
{
sum = (sum & 0xFFFF) + (sum >> 16);
}
return ~sum(U16);
}
I64 IcmpSendReply(U32 dest_ip, U16 identifier, U16 seq_number, U16 request_checksum, U8* payload, I64 length) {
U8* frame;
I64 index = IPv4PacketAlloc(&frame, IP_PROTO_ICMP, IPv4GetAddress(), dest_ip, sizeof(CIcmpHeader) + length);
@ -27,6 +52,26 @@ I64 IcmpSendReply(U32 dest_ip, U16 identifier, U16 seq_number, U16 request_check
return IPv4PacketFinish(index);
}
I64 IcmpSendRequest(U32 dest_ip, U16 identifier, U16 seq_number, U16 request_checksum, U8* payload, I64 length) {
U8* frame;
I64 index = IPv4PacketAlloc(&frame, IP_PROTO_ICMP, IPv4GetAddress(), dest_ip, sizeof(CIcmpHeader) + length);
if (index < 0)
return index;
CIcmpHeader* hdr = frame;
hdr->type = ICMP_TYPE_ECHO_REQUEST;
hdr->code = 0;
hdr->checksum = 0;
hdr->identifier = identifier;
hdr->seq_number = seq_number;
hdr->checksum = IcmpComputeChecksum(hdr, sizeof(CIcmpHeader));
MemCpy(frame + sizeof(CIcmpHeader), payload, length);
return IPv4PacketFinish(index);
}
I64 IcmpHandler(CIPv4Packet* packet) {
if (packet->proto != IP_PROTO_ICMP)
return -1;
@ -36,6 +81,10 @@ I64 IcmpHandler(CIPv4Packet* packet) {
CIcmpHeader* hdr = packet->data;
if (hdr->type == ICMP_TYPE_ECHO_REPLY && hdr->code == 0) {
icmp_reply[hdr->identifier] = packet;
}
if (hdr->type == ICMP_TYPE_ECHO_REQUEST && hdr->code == 0) {
// This also makes sure that we don't stall NetHandlerTask
ArpCachePut(packet->source_ip, packet->l2_frame->source_addr);

Loading…
Cancel
Save