Add IGMP, prepend_buffer/parse_buffer, split UDP header, discovery tests, test all
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user