Skip to content

Commit 6debd27

Browse files
committed
Add support for domain name to generate FQDNs
1 parent b55726c commit 6debd27

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

embassy-net/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"]
4848
dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"]
4949
## Enable DHCPv4 support with hostname
5050
dhcpv4-hostname = ["dhcpv4"]
51+
## Enable DHCP option 15 (domain-name) for use in DNS queries
52+
dhcpv4-domainname = ["dhcpv4"]
5153
## Enable IPv4 support
5254
proto-ipv4 = ["smoltcp/proto-ipv4"]
5355
## Enable IPv6 support
@@ -66,7 +68,7 @@ igmp = ["smoltcp/proto-igmp"]
6668
defmt = { version = "0.3", optional = true }
6769
log = { version = "0.4.14", optional = true }
6870

69-
smoltcp = { version = "0.11.0", default-features = false, features = [
71+
smoltcp = { git = "https://github.com/korken89/smoltcp.git", branch = "dhcp-option-15", default-features = false, features = [
7072
"socket",
7173
"async",
7274
] }
@@ -80,3 +82,4 @@ managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
8082
heapless = { version = "0.8", default-features = false }
8183
embedded-nal-async = { version = "0.7.1" }
8284
document-features = "0.2.7"
85+

embassy-net/src/device.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ where
7474
{
7575
fn consume<R, F>(self, f: F) -> R
7676
where
77-
F: FnOnce(&mut [u8]) -> R,
77+
F: FnOnce(&[u8]) -> R,
7878
{
7979
self.0.consume(|buf| {
8080
#[cfg(feature = "packet-trace")]

embassy-net/src/lib.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use embassy_net_driver::{Driver, LinkState};
3333
use embassy_sync::waitqueue::WakerRegistration;
3434
use embassy_time::{Instant, Timer};
3535
#[allow(unused_imports)]
36-
use heapless::Vec;
36+
use heapless::{String, Vec};
3737
#[cfg(feature = "dns")]
3838
pub use smoltcp::config::DNS_MAX_SERVER_COUNT;
3939
#[cfg(feature = "igmp")]
@@ -66,6 +66,8 @@ const LOCAL_PORT_MAX: u16 = 65535;
6666
const MAX_QUERIES: usize = 4;
6767
#[cfg(feature = "dhcpv4-hostname")]
6868
const MAX_HOSTNAME_LEN: usize = 32;
69+
#[cfg(all(feature = "dhcpv4-domainname", feature = "dns"))]
70+
const MAX_DNS_QUERY_LEN: usize = 128;
6971

7072
/// Memory resources needed for a network stack.
7173
pub struct StackResources<const SOCK: usize> {
@@ -110,6 +112,9 @@ pub struct StaticConfigV4 {
110112
pub gateway: Option<Ipv4Address>,
111113
/// DNS servers.
112114
pub dns_servers: Vec<Ipv4Address, 3>,
115+
/// Domain name.
116+
#[cfg(feature = "dhcpv4-domainname")]
117+
pub domain_name: Option<String<{ smoltcp::config::DHCP_MAX_DOMAIN_NAME_SIZE }>>,
113118
}
114119

115120
/// Static IPv6 address configuration
@@ -146,7 +151,7 @@ pub struct DhcpConfig {
146151
pub client_port: u16,
147152
/// Our hostname. This will be sent to the DHCP server as Option 12.
148153
#[cfg(feature = "dhcpv4-hostname")]
149-
pub hostname: Option<heapless::String<MAX_HOSTNAME_LEN>>,
154+
pub hostname: Option<String<MAX_HOSTNAME_LEN>>,
150155
}
151156

152157
#[cfg(feature = "dhcpv4")]
@@ -527,6 +532,14 @@ impl<D: Driver> Stack<D> {
527532
_ => {}
528533
}
529534

535+
#[cfg(feature = "dhcpv4-domainname")]
536+
let name = if name.contains(".") {
537+
// Already a FQDN.
538+
name
539+
} else {
540+
&self.create_fqdn(name)?
541+
};
542+
530543
let query = poll_fn(|cx| {
531544
self.with_mut(|s, i| {
532545
let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket);
@@ -602,6 +615,23 @@ impl<D: Driver> Stack<D> {
602615

603616
res
604617
}
618+
619+
#[cfg(feature = "dhcpv4-domainname")]
620+
fn create_fqdn(&self, name: &str) -> Result<String<MAX_DNS_QUERY_LEN>, dns::Error> {
621+
use core::str::FromStr;
622+
623+
// Form name together with domain name.
624+
let mut name = String::<MAX_DNS_QUERY_LEN>::from_str(name).map_err(|_| dns::Error::NameTooLong)?;
625+
626+
if let Some(Some(domain_name)) = &self.inner.borrow().static_v4.as_ref().map(|c| &c.domain_name) {
627+
if !domain_name.is_empty() {
628+
name.push('.').map_err(|_| dns::Error::NameTooLong)?;
629+
name.push_str(&domain_name).map_err(|_| dns::Error::NameTooLong)?;
630+
}
631+
}
632+
633+
Ok(name)
634+
}
605635
}
606636

607637
#[cfg(feature = "igmp")]
@@ -902,6 +932,8 @@ impl<D: Driver> Inner<D> {
902932
address: config.address,
903933
gateway: config.router,
904934
dns_servers: config.dns_servers,
935+
#[cfg(feature = "dhcpv4-domainname")]
936+
domain_name: config.domain_name,
905937
});
906938
apply_config = true;
907939
}

0 commit comments

Comments
 (0)