#pragma once #include #include #include #include "callback_list.h" #include "span_writer.h" namespace eth { using mac_addr = std::array; static constexpr mac_addr MAC_BROADCAST = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; static constexpr uint16_t ETH_ARP = __builtin_bswap16(0x0806); static constexpr uint16_t ETH_IPV4 = __builtin_bswap16(0x0800); struct __attribute__((packed)) header { mac_addr dst; mac_addr src; uint16_t ethertype; }; static_assert(sizeof(header) == 14); template void prepend(Buf& buf, const mac_addr& dst, const mac_addr& src, uint16_t ethertype) { auto* h = buf.template prepend
(); h->dst = dst; h->src = src; h->ethertype = ethertype; } using frame_callback = bool (*)(std::span frame); using frame_cb_list = callback_list; using frame_cb_handle = frame_cb_list::node*; using ethertype_handler = void (*)(std::span frame, span_writer& tx); using mac_filter = bool (*)(const mac_addr& dst); bool init(); const mac_addr& get_mac(); frame_cb_handle add_frame_callback(frame_callback cb); void remove_frame_callback(frame_cb_handle h); void poll(std::span tx); void send_raw(std::span data); void register_ethertype(uint16_t ethertype_be, ethertype_handler fn); void register_mac_filter(mac_filter fn); } // namespace eth