Add IGMP, prepend_buffer/parse_buffer, split UDP header, discovery tests, test all

This commit is contained in:
Ian Gulliver
2026-04-11 09:04:55 +09:00
parent e486f6501a
commit a6225faa2b
17 changed files with 582 additions and 183 deletions

View File

@@ -1,4 +1,6 @@
#include "arp.h"
#include "parse_buffer.h"
#include "prepend_buffer.h"
namespace arp {
@@ -10,32 +12,31 @@ static constexpr uint16_t ARP_OP_REPLY = __builtin_bswap16(2);
void handle(std::span<const uint8_t> frame, span_writer& tx,
eth::mac_addr our_mac, ipv4::ip4_addr our_ip,
std::function<void(std::span<const uint8_t>)> send_raw) {
if (frame.size() < sizeof(packet)) return;
auto& pkt = *reinterpret_cast<const packet*>(frame.data());
parse_buffer pb(frame);
pb.consume<eth::header>();
auto* arp_hdr = pb.consume<header>();
if (!arp_hdr) return;
if (pkt.htype != ARP_HTYPE_ETH) return;
if (pkt.ptype != ARP_PTYPE_IPV4) return;
if (pkt.hlen != 6 || pkt.plen != 4) return;
if (pkt.oper != ARP_OP_REQUEST) return;
if (pkt.tpa != our_ip) return;
if (sizeof(packet) > tx.capacity()) return;
if (arp_hdr->htype != ARP_HTYPE_ETH) return;
if (arp_hdr->ptype != ARP_PTYPE_IPV4) return;
if (arp_hdr->hlen != 6 || arp_hdr->plen != 4) return;
if (arp_hdr->oper != ARP_OP_REQUEST) return;
if (arp_hdr->tpa != our_ip) return;
auto& reply = *reinterpret_cast<packet*>(tx.data());
reply = {};
reply.eth.dst = pkt.eth.src;
reply.eth.src = our_mac;
reply.eth.ethertype = eth::ETH_ARP;
reply.htype = ARP_HTYPE_ETH;
reply.ptype = ARP_PTYPE_IPV4;
reply.hlen = 6;
reply.plen = 4;
reply.oper = ARP_OP_REPLY;
reply.sha = our_mac;
reply.spa = our_ip;
reply.tha = pkt.sha;
reply.tpa = pkt.spa;
prepend_buffer<128> buf;
auto* reply = buf.template prepend<header>();
reply->htype = ARP_HTYPE_ETH;
reply->ptype = ARP_PTYPE_IPV4;
reply->hlen = 6;
reply->plen = 4;
reply->oper = ARP_OP_REPLY;
reply->sha = our_mac;
reply->spa = our_ip;
reply->tha = arp_hdr->sha;
reply->tpa = arp_hdr->spa;
eth::prepend(buf, arp_hdr->sha, our_mac, eth::ETH_ARP);
send_raw({tx.data(), sizeof(packet)});
send_raw(buf.span());
}
} // namespace arp