net: add support for dhcp hostname option.
This commit is contained in:
parent
f30fc949ff
commit
534eb960e9
2
ci.sh
2
ci.sh
@ -36,7 +36,7 @@ cargo batch \
|
||||
--- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly,dhcpv4-hostname \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \
|
||||
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \
|
||||
|
@ -33,6 +33,7 @@ udp = ["smoltcp/socket-udp"]
|
||||
tcp = ["smoltcp/socket-tcp"]
|
||||
dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"]
|
||||
dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"]
|
||||
dhcpv4-hostname = ["dhcpv4"]
|
||||
proto-ipv4 = ["smoltcp/proto-ipv4"]
|
||||
proto-ipv6 = ["smoltcp/proto-ipv6"]
|
||||
medium-ethernet = ["smoltcp/medium-ethernet"]
|
||||
|
@ -56,12 +56,22 @@ const LOCAL_PORT_MIN: u16 = 1025;
|
||||
const LOCAL_PORT_MAX: u16 = 65535;
|
||||
#[cfg(feature = "dns")]
|
||||
const MAX_QUERIES: usize = 4;
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
const MAX_HOSTNAME_LEN: usize = 32;
|
||||
|
||||
/// Memory resources needed for a network stack.
|
||||
pub struct StackResources<const SOCK: usize> {
|
||||
sockets: [SocketStorage<'static>; SOCK],
|
||||
#[cfg(feature = "dns")]
|
||||
queries: [Option<dns::DnsQuery>; MAX_QUERIES],
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
hostname: core::cell::UnsafeCell<HostnameResources>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
struct HostnameResources {
|
||||
option: smoltcp::wire::DhcpOption<'static>,
|
||||
data: [u8; MAX_HOSTNAME_LEN],
|
||||
}
|
||||
|
||||
impl<const SOCK: usize> StackResources<SOCK> {
|
||||
@ -73,6 +83,11 @@ impl<const SOCK: usize> StackResources<SOCK> {
|
||||
sockets: [SocketStorage::EMPTY; SOCK],
|
||||
#[cfg(feature = "dns")]
|
||||
queries: [INIT; MAX_QUERIES],
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
hostname: core::cell::UnsafeCell::new(HostnameResources {
|
||||
option: smoltcp::wire::DhcpOption { kind: 0, data: &[] },
|
||||
data: [0; MAX_HOSTNAME_LEN],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,6 +119,7 @@ pub struct StaticConfigV6 {
|
||||
/// DHCP configuration.
|
||||
#[cfg(feature = "dhcpv4")]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub struct DhcpConfig {
|
||||
/// Maximum lease duration.
|
||||
///
|
||||
@ -120,6 +136,9 @@ pub struct DhcpConfig {
|
||||
pub server_port: u16,
|
||||
/// Client port. This is almost always 68. Do not change unless you know what you're doing.
|
||||
pub client_port: u16,
|
||||
/// Our hostname. This will be sent to the DHCP server as Option 12.
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
pub hostname: Option<heapless::String<MAX_HOSTNAME_LEN>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "dhcpv4")]
|
||||
@ -131,6 +150,8 @@ impl Default for DhcpConfig {
|
||||
ignore_naks: Default::default(),
|
||||
server_port: smoltcp::wire::DHCP_SERVER_PORT,
|
||||
client_port: smoltcp::wire::DHCP_CLIENT_PORT,
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
hostname: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -232,6 +253,8 @@ struct Inner<D: Driver> {
|
||||
dns_socket: SocketHandle,
|
||||
#[cfg(feature = "dns")]
|
||||
dns_waker: WakerRegistration,
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
hostname: &'static mut core::cell::UnsafeCell<HostnameResources>,
|
||||
}
|
||||
|
||||
pub(crate) struct SocketStack {
|
||||
@ -307,6 +330,8 @@ impl<D: Driver> Stack<D> {
|
||||
)),
|
||||
#[cfg(feature = "dns")]
|
||||
dns_waker: WakerRegistration::new(),
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
hostname: &mut resources.hostname,
|
||||
};
|
||||
|
||||
#[cfg(feature = "proto-ipv4")]
|
||||
@ -673,6 +698,25 @@ impl<D: Driver> Inner<D> {
|
||||
socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp));
|
||||
socket.set_ports(c.server_port, c.client_port);
|
||||
socket.set_retry_config(c.retry_config);
|
||||
|
||||
socket.set_outgoing_options(&[]);
|
||||
#[cfg(feature = "dhcpv4-hostname")]
|
||||
if let Some(h) = c.hostname {
|
||||
// safety: we just did set_outgoing_options([]) so we know the socket is no longer holding a reference.
|
||||
let hostname = unsafe { &mut *self.hostname.get() };
|
||||
|
||||
// create data
|
||||
// safety: we know the buffer lives forever, new borrows the StackResources for 'static.
|
||||
// also we won't modify it until next call to this function.
|
||||
hostname.data[..h.len()].copy_from_slice(h.as_bytes());
|
||||
let data: &[u8] = &hostname.data[..h.len()];
|
||||
let data: &'static [u8] = unsafe { core::mem::transmute(data) };
|
||||
|
||||
// set the option.
|
||||
hostname.option = smoltcp::wire::DhcpOption { data, kind: 12 };
|
||||
socket.set_outgoing_options(core::slice::from_ref(&hostname.option));
|
||||
}
|
||||
|
||||
socket.reset();
|
||||
}
|
||||
_ => {
|
||||
|
Loading…
Reference in New Issue
Block a user