use core::net::Ipv4Addr;
use edge_nal::{UdpReceive, UdpSend};
use self::dhcp::{Options, Packet};
pub use super::*;
pub async fn run<T, F, const N: usize>(
server: &mut dhcp::server::Server<F, N>,
server_options: &dhcp::server::ServerOptions<'_>,
socket: &mut T,
buf: &mut [u8],
) -> Result<(), Error<T::Error>>
where
T: UdpReceive + UdpSend,
F: FnMut() -> u64,
{
info!(
"Running DHCP server for addresses {}-{} with configuration {:?}",
server.range_start, server.range_end, server_options
);
loop {
let (len, remote) = socket.receive(buf).await.map_err(Error::Io)?;
let packet = &buf[..len];
let request = match Packet::decode(packet) {
Ok(request) => request,
Err(err) => {
warn!("Decoding packet returned error: {:?}", err);
continue;
}
};
let mut opt_buf = Options::buf();
if let Some(reply) = server.handle_request(&mut opt_buf, server_options, &request) {
let remote = if let SocketAddr::V4(socket) = remote {
if request.broadcast || *socket.ip() == Ipv4Addr::UNSPECIFIED {
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::BROADCAST, socket.port()))
} else {
remote
}
} else {
remote
};
socket
.send(remote, reply.encode(buf)?)
.await
.map_err(Error::Io)?;
}
}
}