#include "arp.h" #include "net.h" #include "parse_buffer.h" #include "prepend_buffer.h" namespace arp { static constexpr uint16_t ARP_HTYPE_ETH = __builtin_bswap16(1); static constexpr uint16_t ARP_PTYPE_IPV4 = __builtin_bswap16(0x0800); static constexpr uint16_t ARP_OP_REQUEST = __builtin_bswap16(1); static constexpr uint16_t ARP_OP_REPLY = __builtin_bswap16(2); void handle(std::span frame, span_writer& tx, eth::mac_addr our_mac, ipv4::ip4_addr our_ip) { parse_buffer pb(frame); pb.consume(); auto* arp_hdr = pb.consume
(); if (!arp_hdr) 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; prepend_buffer<4096> buf; auto* reply = buf.template prepend
(); 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); net_send_raw(buf.span()); } } // namespace arp