Skip to content

Commit ae882f3

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

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-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: 37 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,15 @@ 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+
debug!("Performing DNS lookup of: {}", name);
543+
530544
let query = poll_fn(|cx| {
531545
self.with_mut(|s, i| {
532546
let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket);
@@ -602,6 +616,23 @@ impl<D: Driver> Stack<D> {
602616

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

607638
#[cfg(feature = "igmp")]
@@ -788,6 +819,8 @@ impl<D: Driver> Inner<D> {
788819
debug!(" DNS server: {:?}", s);
789820
unwrap!(dns_servers.push(s.clone().into()).ok());
790821
}
822+
#[cfg(feature = "dhcpv4-domainname")]
823+
debug!(" Domain name: {:?}", config.domain_name);
791824
} else {
792825
info!("IPv4: DOWN");
793826
}
@@ -902,6 +935,8 @@ impl<D: Driver> Inner<D> {
902935
address: config.address,
903936
gateway: config.router,
904937
dns_servers: config.dns_servers,
938+
#[cfg(feature = "dhcpv4-domainname")]
939+
domain_name: config.domain_name,
905940
});
906941
apply_config = true;
907942
}

0 commit comments

Comments
 (0)