dhcp works! (without rapid commit)
This commit is contained in:
parent
6f5ebbd752
commit
e16dee3b9b
175
src/main.rs
175
src/main.rs
@ -7,7 +7,7 @@
|
||||
use core::net::Ipv4Addr;
|
||||
use core::slice;
|
||||
use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi};
|
||||
use dhcparse::dhcpv4::{DhcpOption, Encode as _};
|
||||
use dhcparse::dhcpv4::{DhcpOption, Encode as _, MessageType as DhcpMsgType};
|
||||
use dhcparse::{dhcpv4, v4_options};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::udp::{PacketMetadata, UdpMetadata, UdpSocket};
|
||||
@ -173,7 +173,6 @@ async fn main(spawner: Spawner) {
|
||||
let mut tx_meta = [PacketMetadata::EMPTY; 16];
|
||||
let mut buf = [0; 4096];
|
||||
let mut res_buf = Vec::<u8, 4096>::new();
|
||||
let mut res_head = Vec::<u8, 2048>::new();
|
||||
loop {
|
||||
let mut socket = UdpSocket::new(
|
||||
stack,
|
||||
@ -185,28 +184,14 @@ async fn main(spawner: Spawner) {
|
||||
unwrap(socket.bind(67)).await;
|
||||
|
||||
loop {
|
||||
// loop {
|
||||
// if socket.may_recv() {
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// info!("may recv");
|
||||
// Timer::after_secs(0).await;
|
||||
info!("receiving");
|
||||
let (n, ep) = unwrap(socket.recv_from(&mut buf).await).await;
|
||||
info!("received");
|
||||
Timer::after_secs(0).await;
|
||||
|
||||
// if let Ok(s) = core::str::from_utf8(&buf[..n]) {
|
||||
// info!("rxd str from {}: {}", ep, s);
|
||||
// } else {
|
||||
// info!("rxd not str from {}: {:?}", ep, &buf[..n]);
|
||||
// }
|
||||
// Timer::after_secs(0).await;
|
||||
|
||||
let msg = unwrap(dhcpv4::Message::new(&buf[..n])).await;
|
||||
|
||||
let opts = unwrap(v4_options!(msg; MessageType required)).await;
|
||||
let msg_type = unwrap(v4_options!(msg; MessageType required)).await;
|
||||
for o in unwrap(msg.options()).await {
|
||||
info!(
|
||||
"{:?}",
|
||||
@ -216,11 +201,11 @@ async fn main(spawner: Spawner) {
|
||||
}
|
||||
);
|
||||
}
|
||||
info!("{:?}", opts);
|
||||
info!("{:?}", msg_type);
|
||||
Timer::after_secs(0).await;
|
||||
|
||||
match opts {
|
||||
dhcpv4::MessageType::DISCOVER => {
|
||||
match msg_type {
|
||||
DhcpMsgType::DISCOVER | DhcpMsgType::REQUEST => {
|
||||
res_buf.clear();
|
||||
res_buf.push(2).unwrap(); // op
|
||||
res_buf.push(1).unwrap(); // htype
|
||||
@ -229,7 +214,7 @@ async fn main(spawner: Spawner) {
|
||||
res_buf.extend_from_slice(&buf[4..8]).unwrap(); // xid
|
||||
res_buf.extend_from_slice(&[0; 2]).unwrap(); // secs
|
||||
res_buf.extend_from_slice(&[0x80, 0x00]).unwrap(); // flags
|
||||
res_buf.extend_from_slice(&[0; 4]).unwrap(); // ciaddr
|
||||
res_buf.extend_from_slice(&buf[12..16]).unwrap(); // ciaddr
|
||||
res_buf.extend_from_slice(&[192, 254, 0, 12]).unwrap(); // yiaddr
|
||||
res_buf.extend_from_slice(&[0; 4]).unwrap(); // siaddr
|
||||
res_buf.extend_from_slice(&buf[24..28]).unwrap(); // giaddr
|
||||
@ -237,80 +222,34 @@ async fn main(spawner: Spawner) {
|
||||
res_buf.extend_from_slice(&[0; 192]).unwrap(); // sname/file
|
||||
res_buf.extend_from_slice(&[99, 130, 83, 99]).unwrap(); // magic cookie
|
||||
|
||||
res_buf.extend_from_slice(&[0; 4]).unwrap();
|
||||
info!("{}", res_buf.len());
|
||||
Timer::after_secs(0).await;
|
||||
|
||||
// let mut res_opts = Vec::<DhcpOption, 255>::new();
|
||||
for o in unwrap(v4_options!(msg; ParameterRequestList))
|
||||
res_buf
|
||||
.extend_from_slice(&[
|
||||
53,
|
||||
1,
|
||||
match msg_type {
|
||||
DhcpMsgType::DISCOVER => 2,
|
||||
DhcpMsgType::REQUEST => 5,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
])
|
||||
.unwrap(); // opt message type
|
||||
unwrap(
|
||||
write_dhcp_opts(
|
||||
&mut res_buf,
|
||||
match msg_type {
|
||||
DhcpMsgType::DISCOVER => {
|
||||
unwrap(v4_options!(msg; ParameterRequestList))
|
||||
.await
|
||||
.unwrap_or(&[])
|
||||
{
|
||||
let (opt_len, opt): (u8, &[u8]) = match o {
|
||||
1 => (4, &[255, 255, 255, 0]), // DhcpOption::SubnetMask(&dhcpv4::Addr([255, 255, 255, 0])),
|
||||
2 => (4, &3600_i32.to_be_bytes()), // DhcpOption::TimeOffset(3600),
|
||||
3 => (4, &[192, 254, 0, 2]), // DhcpOption::Router(&[dhcpv4::Addr([192, 254, 0, 2])]),
|
||||
6 => (4, &[0, 0, 0, 0]), // DhcpOption::DomainNameServer(&[dhcpv4::Addr([0, 0, 0, 0])]),
|
||||
12 => (4, b"blue"), // DhcpOption::HostName(b"blue"),
|
||||
15 => (11, b"LocalDomain"), // DhcpOption::DomainName(b"LocalDomain"),
|
||||
26 => (2, &1514_u16.to_be_bytes()), // DhcpOption::Unknown(26, &[0x5, 0xEA]), // mtu
|
||||
28 => (4, &[192, 254, 0, 255]), // DhcpOption::Unknown(28, &[192, 254, 0, 255]), // broadcast
|
||||
51 => (4, &700_u32.to_be_bytes()), // DhcpOption::AddressLeaseTime(700),
|
||||
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
|
||||
_ => {
|
||||
info!("Unhandled requested option : {}", o);
|
||||
Timer::after_secs(0).await;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
res_buf.push(*o).unwrap();
|
||||
res_buf.push(opt_len).unwrap();
|
||||
res_buf.extend_from_slice(opt).unwrap();
|
||||
}
|
||||
DhcpMsgType::REQUEST => &[1, 3, 51, 6, 54],
|
||||
_ => unreachable!(),
|
||||
},
|
||||
)
|
||||
.await,
|
||||
)
|
||||
.await;
|
||||
res_buf.push(255).unwrap(); // end option
|
||||
// unwrap(res_opts.push(DhcpOption::End)).await;
|
||||
|
||||
// res_buf.clear();
|
||||
// unwrap(
|
||||
// dhcpv4::Encoder
|
||||
// .append_options(res_opts)
|
||||
// .encode(&unwrap(dhcpv4::Message::new(&res_head)).await, &mut res_buf),
|
||||
// )
|
||||
// .await;
|
||||
|
||||
// // options
|
||||
// res_buf.extend_from_slice(&[53, 1, 2]).unwrap(); // message type
|
||||
// res_buf
|
||||
// .extend_from_slice(&[1, 4, 255, 255, 255, 0])
|
||||
// .unwrap(); // subnet mask
|
||||
// res_buf.extend_from_slice(&[3, 4, 192, 254, 0, 2]).unwrap(); // router
|
||||
// res_buf.extend_from_slice(&[6, 4, 0, 0, 0, 0]).unwrap(); // dns
|
||||
// res_buf.extend_from_slice(&[15, 1, 0]).unwrap(); // domain name
|
||||
// res_buf.extend_from_slice(&[26, 2, 0x5, 0xEA]).unwrap(); // mtu
|
||||
// res_buf
|
||||
// .extend_from_slice(&[28, 4, 192, 254, 0, 255])
|
||||
// .unwrap(); // domain name
|
||||
// res_buf
|
||||
// .extend_from_slice(&[51, 4, 0, 0, 0x2, 0xBC])
|
||||
// .unwrap(); // address lease time = 700s
|
||||
// res_buf
|
||||
// .extend_from_slice(&[58, 4, 0, 0, 0x2, 0x58])
|
||||
// .unwrap(); // renewal time = 600s
|
||||
// res_buf
|
||||
// .extend_from_slice(&[59, 4, 0, 0, 0x2, 0x58])
|
||||
// .unwrap(); // rebinding time = 600s
|
||||
// res_buf.extend_from_slice(&[43, 1, 0]).unwrap(); // vendor specific
|
||||
// let captive_portal_uri = "http://192.254.0.2:80/";
|
||||
// res_buf
|
||||
// .extend_from_slice(&[114, captive_portal_uri.len() as u8])
|
||||
// .unwrap(); // captive portal
|
||||
// res_buf
|
||||
// .extend_from_slice(captive_portal_uri.as_bytes())
|
||||
// .unwrap();
|
||||
// res_buf.extend_from_slice(&[108, 4, 0, 0, 0, 0]).unwrap(); // ipv6 only
|
||||
// res_buf.push(255).unwrap(); // end mark
|
||||
|
||||
for o in unwrap(unwrap(dhcpv4::Message::new(&res_buf)).await.options()).await {
|
||||
info!(
|
||||
@ -322,32 +261,6 @@ async fn main(spawner: Spawner) {
|
||||
);
|
||||
Timer::after_secs(0).await;
|
||||
}
|
||||
// let mut mac = [0; 6];
|
||||
// mac.clone_from_slice(&buf[28..34]);
|
||||
// info!("mac : {:?}", mac);
|
||||
// Timer::after_secs(0).await;
|
||||
// let mut stack_inner = unwrap(stack.inner.try_borrow_mut()).await;
|
||||
// let now = stack_inner.iface.inner.now;
|
||||
// stack_inner.iface.inner.neighbor_cache.fill(
|
||||
// Ipv4Addr::new(192, 254, 0, 12).into(),
|
||||
// HardwareAddress::Ethernet(EthernetAddress(mac)),
|
||||
// now,
|
||||
// );
|
||||
// info!("neighbor cache filled");
|
||||
// Timer::after_secs(0).await;
|
||||
|
||||
// unwrap(
|
||||
// stack_inner
|
||||
// .iface
|
||||
// .inner
|
||||
// .ip_addrs
|
||||
// .push(Ipv4Cidr::new(Ipv4Addr::new(192, 254, 0, 12), 24).into()),
|
||||
// )
|
||||
// .await;
|
||||
// info!("ip addr added");
|
||||
// Timer::after_secs(0).await;
|
||||
|
||||
// drop(stack_inner);
|
||||
|
||||
unwrap(
|
||||
socket
|
||||
@ -386,3 +299,31 @@ struct WifiConnectConf<'a> {
|
||||
password: &'a str,
|
||||
ip: Option<Ipv4Addr>,
|
||||
}
|
||||
|
||||
async fn write_dhcp_opts<const N: usize>(buf: &mut Vec<u8, N>, op_codes: &[u8]) -> Result<(), ()> {
|
||||
for o in op_codes {
|
||||
let (opt_len, opt): (u8, &[u8]) = match o {
|
||||
1 => (4, &[255, 255, 255, 0]), // DhcpOption::SubnetMask(&dhcpv4::Addr([255, 255, 255, 0])),
|
||||
2 => (4, &3600_i32.to_be_bytes()), // DhcpOption::TimeOffset(3600),
|
||||
3 => (4, &[192, 254, 0, 2]), // DhcpOption::Router(&[dhcpv4::Addr([192, 254, 0, 2])]),
|
||||
6 => (4, &[0, 0, 0, 0]), // DhcpOption::DomainNameServer(&[dhcpv4::Addr([0, 0, 0, 0])]),
|
||||
12 => (4, b"blue"), // DhcpOption::HostName(b"blue"),
|
||||
15 => (11, b"LocalDomain"), // DhcpOption::DomainName(b"LocalDomain"),
|
||||
26 => (2, &1514_u16.to_be_bytes()), // DhcpOption::Unknown(26, &[0x5, 0xEA]), // mtu
|
||||
28 => (4, &[192, 254, 0, 255]), // DhcpOption::Unknown(28, &[192, 254, 0, 255]), // broadcast
|
||||
51 => (4, &700_u32.to_be_bytes()), // DhcpOption::AddressLeaseTime(700),
|
||||
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
|
||||
_ => {
|
||||
info!("Unhandled requested option : {}", o);
|
||||
Timer::after_secs(0).await;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
buf.push(*o).map_err(|_| ())?;
|
||||
buf.push(opt_len).map_err(|_| ())?;
|
||||
buf.extend_from_slice(opt)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user