dns works

This commit is contained in:
Arkitu 2025-04-28 21:10:35 +02:00
parent 937aafb099
commit 6bc4d823b7
5 changed files with 108 additions and 5 deletions

7
Cargo.lock generated
View File

@ -348,6 +348,12 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "dnsparse"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18b5892f4beae62ac9681eb96df926ebcebca009e6f2e23a216acf7d3f5c5a97"
[[package]]
name = "document-features"
version = "0.2.11"
@ -1093,6 +1099,7 @@ dependencies = [
"defmt",
"defmt-rtt",
"dhcparse",
"dnsparse",
"embassy-executor",
"embassy-net",
"embassy-rp",

View File

@ -9,7 +9,8 @@ wifi-connect = [
"dep:serde",
] # you need to add a wifi.conf file for this to work
dhcp = ["dep:dhcparse"]
default = ["dhcp"]
dns = ["dep:dnsparse"]
default = ["dhcp", "dns"]
[dependencies]
embassy-executor = { git = "https://github.com/embassy-rs/embassy", features = [
@ -54,4 +55,5 @@ serde-json-core = { version = "*", optional = true }
serde = { version = "*", optional = true, default-features = false, features = [
"derive",
] }
dhcparse = { version = "*", default-features = false, optional = true }
dhcparse = { version = "*", default-features = false, optional = true }
dnsparse = { version = "*", optional = true }

View File

@ -149,9 +149,9 @@ async fn write_dhcp_opts<const N: usize>(buf: &mut Vec<u8, N>, op_codes: &[u8])
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"),
6 => (4, &[192, 254, 0, 2]), // DhcpOption::DomainNameServer(&[dhcpv4::Addr([0, 0, 0, 0])]),
12 => (4, b"blue"), // DhcpOption::HostName(b"blue"),
15 => (4, b"wifi"), // 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),

88
src/dns.rs Normal file
View File

@ -0,0 +1,88 @@
use dnsparse::{Answer, Header, HeaderKind, Message, OpCode, QueryClass, QueryKind, ResponseCode};
use embassy_net::{
Stack,
udp::{PacketMetadata, UdpSocket},
};
use embassy_time::Timer;
use log::{info, warn};
use pico_website::unwrap;
#[embassy_executor::task(pool_size = 1)]
pub async fn dns_server(stack: Stack<'static>) {
let mut rx_buffer = [0; 4096];
let mut tx_buffer = [0; 4096];
let mut rx_meta = [PacketMetadata::EMPTY; 16];
let mut tx_meta = [PacketMetadata::EMPTY; 16];
let mut buf = [0; 4096];
let mut res_buf = [0; 2048];
loop {
let mut socket = UdpSocket::new(
stack,
&mut rx_meta,
&mut rx_buffer,
&mut tx_meta,
&mut tx_buffer,
);
unwrap(socket.bind(53)).await;
info!("Starting DNS server");
loop {
let (n, meta) = unwrap(socket.recv_from(&mut buf).await).await;
let msg = match dnsparse::Message::parse(&mut buf[..n]) {
Ok(msg) => msg,
Err(e) => {
warn!("Dns: Error while parsing DNS message : {:#?}", e);
continue;
}
};
if msg.header().opcode() != OpCode::Query {
info!(
"Dns: Received unknown dns opcode ({:?}), ignoring",
msg.header().opcode()
);
Timer::after_micros(10).await;
continue;
}
let mut res = Message::builder(&mut res_buf)
.header(
Header::builder()
.id(msg.header().id())
.kind(HeaderKind::Response)
.recursion_available(false)
.recursion_desired(msg.header().recursion_desired())
.response_code(ResponseCode::NoError)
.build(),
)
.build();
for q in msg.questions() {
match q.kind() {
QueryKind::A => {
if q.name() == "ttt.wifi" || q.name() == "www.ttt.wifi" {
res.add_question(&q);
res.add_answer(&Answer {
name: q.name().clone(),
kind: QueryKind::A,
class: QueryClass::IN,
ttl: 60,
rdata: &[192, 254, 0, 2],
});
info!("Dns: Giving {}", q.name());
} else {
info!("Dns: Unknown uri, ignoring ({})", q.name());
}
}
_ => {
continue;
}
};
}
if let Err(e) = socket.send_to(res.as_bytes(), meta).await {
warn!("Dns: Error while sending dns response : {:?}", e);
break;
}
}
}
}

View File

@ -22,6 +22,9 @@ use {defmt_rtt as _, panic_probe as _};
#[cfg(feature = "dhcp")]
mod dhcp;
#[cfg(feature = "dns")]
mod dns;
mod game;
mod socket;
@ -163,6 +166,9 @@ async fn main(spawner: Spawner) {
#[cfg(feature = "dhcp")]
unwrap(spawner.spawn(dhcp::dhcp_server(stack))).await;
#[cfg(feature = "dns")]
unwrap(spawner.spawn(dns::dns_server(stack))).await;
unwrap(spawner.spawn(socket::listen_task(stack, game::Team::Zero, 80))).await;
unwrap(spawner.spawn(socket::listen_task(stack, game::Team::One, 81))).await;
}