From 71502147da8de0d0b0dc6820b985f6963fa1e097 Mon Sep 17 00:00:00 2001 From: Arkitu Date: Sat, 26 Apr 2025 16:28:11 +0200 Subject: [PATCH] save --- src/dhcp.rs | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/dhcp.rs b/src/dhcp.rs index 7a778e8..cc935b3 100644 --- a/src/dhcp.rs +++ b/src/dhcp.rs @@ -1,7 +1,7 @@ use core::net::Ipv4Addr; use dhcparse::{ - dhcpv4::{self, MessageType as DhcpMsgType}, + dhcpv4::{self, DhcpOption, MessageType as DhcpMsgType}, v4_options, }; use embassy_net::{ @@ -21,6 +21,7 @@ pub async fn dhcp_server(stack: Stack<'static>) { let mut tx_meta = [PacketMetadata::EMPTY; 16]; let mut buf = [0; 4096]; let mut res_buf = Vec::::new(); + let mut opts = Vec::::new(); loop { let mut socket = UdpSocket::new( stack, @@ -40,14 +41,20 @@ pub async fn dhcp_server(stack: Stack<'static>) { let msg = unwrap(dhcpv4::Message::new(&buf[..n])).await; let msg_type = unwrap(v4_options!(msg; MessageType required)).await; + let mut rapid_commit = false; for o in unwrap(msg.options()).await { - info!( - "{:?}", - match o { - Err(_) => break, - Ok(o) => o, + match o { + Err(_) => break, + Ok(o) => { + if let DhcpOption::Unknown(80, _) = o.0 { + if msg_type != DhcpMsgType::DISCOVER { + info!("ERROR : rapid commit option on {:?} message", msg_type); + } + rapid_commit = true; + } + info!("{:?}", o); } - ); + } } info!("{:?}", msg_type); Timer::after_secs(0).await; @@ -74,23 +81,34 @@ pub async fn dhcp_server(stack: Stack<'static>) { .extend_from_slice(&[ 53, 1, - match msg_type { - DhcpMsgType::DISCOVER => 2, // DHCP_OFFER - DhcpMsgType::REQUEST => 5, // DHCP_ACK - _ => unreachable!(), + match (msg_type, rapid_commit) { + (DhcpMsgType::DISCOVER, false) => 2, // DHCP_OFFER + _ => 5, // DHCP_ACK }, ]) .unwrap(); // opt message type + unwrap( write_dhcp_opts( &mut res_buf, - match msg_type { - DhcpMsgType::DISCOVER => { + match (msg_type, rapid_commit) { + (DhcpMsgType::DISCOVER, false) => { unwrap(v4_options!(msg; ParameterRequestList)) .await .unwrap_or(&[]) } - DhcpMsgType::REQUEST => &[1, 3, 51, 6, 54], + (DhcpMsgType::DISCOVER, true) => { + opts.clear(); + opts.extend_from_slice( + unwrap(v4_options!(msg; ParameterRequestList)) + .await + .unwrap_or(&[]), + ) + .unwrap(); + opts.push(80).unwrap(); + &opts + } + (DhcpMsgType::REQUEST, false) => &[1, 3, 51, 6, 54], _ => unreachable!(), }, ) @@ -126,7 +144,7 @@ pub async fn dhcp_server(stack: Stack<'static>) { .await, ) .await; - info!("offer sent"); + info!("offer/ack sent"); Timer::after_secs(0).await; } _ => {} @@ -152,6 +170,7 @@ async fn write_dhcp_opts(buf: &mut Vec, op_codes: &[u8]) 54 => (4, &[192, 254, 0, 2]), // DhcpOption::ServerIdentifier(&dhcpv4::Addr([192, 254, 0, 2])), 58 => (4, &500_u32.to_be_bytes()), // DhcpOption::Unknown(58, &[0, 0, 0x1, 0xF4]), // renewal time = 500s 59 => (4, &600_u32.to_be_bytes()), // DhcpOption::Unknown(59, &[0, 0, 0x2, 0x58]), // rebinding time = 600s + 80 => (0, &[]), _ => { info!("Unhandled requested option : {}", o); Timer::after_secs(0).await;