#include "dhcp.h" #include #include "w6300.h" namespace dhcp_opt { constexpr uint8_t message_type = 53; constexpr uint8_t param_request = 55; constexpr uint8_t end = 255; constexpr uint8_t discover = 1; constexpr uint8_t subnet_mask = 1; } struct __attribute__((packed)) dhcp_discover { uint8_t op = 1; uint8_t htype = 1; uint8_t hlen = 6; uint8_t hops = 0; uint32_t xid = __builtin_bswap32(0x12345678); uint16_t secs = 0; uint16_t flags = __builtin_bswap16(0x8000); std::array ciaddr = {}; std::array yiaddr = {}; std::array siaddr = {}; std::array giaddr = {}; std::array chaddr = {}; std::array sname = {}; std::array file = {}; std::array magic = {99, 130, 83, 99}; uint8_t opt_msg_type[3] = {dhcp_opt::message_type, 1, dhcp_opt::discover}; uint8_t opt_params[3] = {dhcp_opt::param_request, 1, dhcp_opt::subnet_mask}; uint8_t opt_end = dhcp_opt::end; }; static_assert(sizeof(dhcp_discover) == 247); static void send_discover(timer_queue& timers, const std::array& mac) { auto sn = w6300::socket_id{0}; w6300::open_socket(sn, w6300::protocol::udp, w6300::port_num{68}, w6300::sock_flag::none); dhcp_discover pkt; std::copy(mac.begin(), mac.end(), pkt.chaddr.begin()); w6300::ip_address broadcast = {}; broadcast.ip = {255, 255, 255, 255}; broadcast.len = 4; w6300::sendto(sn, std::span{reinterpret_cast(&pkt), sizeof(pkt)}, broadcast, w6300::port_num{67}); timers.schedule_ms(5000, [&timers, mac]() { send_discover(timers, mac); }); } void dhcp_start(timer_queue& timers, const std::array& mac) { send_discover(timers, mac); }