@@ -33,7 +33,7 @@ use embassy_net_driver::{Driver, LinkState};
3333use  embassy_sync:: waitqueue:: WakerRegistration ; 
3434use  embassy_time:: { Instant ,  Timer } ; 
3535#[ allow( unused_imports) ]  
36- use  heapless:: Vec ; 
36+ use  heapless:: { String ,   Vec } ; 
3737#[ cfg( feature = "dns" ) ]  
3838pub  use  smoltcp:: config:: DNS_MAX_SERVER_COUNT ; 
3939#[ cfg( feature = "igmp" ) ]  
@@ -66,6 +66,10 @@ const LOCAL_PORT_MAX: u16 = 65535;
6666const  MAX_QUERIES :  usize  = 4 ; 
6767#[ cfg( feature = "dhcpv4-hostname" ) ]  
6868const  MAX_HOSTNAME_LEN :  usize  = 32 ; 
69+ #[ cfg( feature = "dhcpv4-domainname" ) ]  
70+ const  MAX_DOMAINNAME_LEN :  usize  = 64 ; 
71+ #[ cfg( all( feature = "dhcpv4-domainname" ,  feature = "dns" ) ) ]  
72+ const  MAX_DNS_QUERY_LEN :  usize  = 128 ; 
6973
7074/// Memory resources needed for a network stack. 
7175pub  struct  StackResources < const  SOCK :  usize >  { 
@@ -146,7 +150,7 @@ pub struct DhcpConfig {
146150pub  client_port :  u16 , 
147151    /// Our hostname. This will be sent to the DHCP server as Option 12. 
148152#[ cfg( feature = "dhcpv4-hostname" ) ]  
149-     pub  hostname :  Option < heapless :: String < MAX_HOSTNAME_LEN > > , 
153+     pub  hostname :  Option < String < MAX_HOSTNAME_LEN > > , 
150154} 
151155
152156#[ cfg( feature = "dhcpv4" ) ]  
@@ -263,6 +267,8 @@ struct Inner<D: Driver> {
263267    dns_waker :  WakerRegistration , 
264268    #[ cfg( feature = "dhcpv4-hostname" ) ]  
265269    hostname :  & ' static  mut  core:: cell:: UnsafeCell < HostnameResources > , 
270+     #[ cfg( feature = "dhcpv4-domainname" ) ]  
271+     domainname :  String < MAX_DOMAINNAME_LEN > , 
266272} 
267273
268274pub ( crate )  struct  SocketStack  { 
@@ -345,6 +351,8 @@ impl<D: Driver> Stack<D> {
345351            dns_waker :  WakerRegistration :: new ( ) , 
346352            #[ cfg( feature = "dhcpv4-hostname" ) ]  
347353            hostname :  & mut  resources. hostname , 
354+             #[ cfg( feature = "dhcpv4-domainname" ) ]  
355+             domainname :  String :: new ( ) , 
348356        } ; 
349357
350358        #[ cfg( feature = "proto-ipv4" ) ]  
@@ -527,6 +535,20 @@ impl<D: Driver> Stack<D> {
527535            _ => { } 
528536        } 
529537
538+         // Form name together with domain name. 
539+         #[ cfg( feature = "dhcpv4-domainname" ) ]  
540+         let  name = & { 
541+             use  core:: str:: FromStr ; 
542+ 
543+             let  domainname = & self . inner . borrow ( ) . domainname ; 
544+             let  mut  name = String :: < MAX_DNS_QUERY_LEN > :: from_str ( name) . map_err ( |_| dns:: Error :: NameTooLong ) ?; 
545+             if  !domainname. is_empty ( )  { 
546+                 name. push ( '.' ) . map_err ( |_| dns:: Error :: NameTooLong ) ?; 
547+                 name. push_str ( domainname) . map_err ( |_| dns:: Error :: NameTooLong ) ?; 
548+             } 
549+             name
550+         } ; 
551+ 
530552        let  query = poll_fn ( |cx| { 
531553            self . with_mut ( |s,  i| { 
532554                let  socket = s. sockets . get_mut :: < dns:: Socket > ( i. dns_socket ) ; 
@@ -746,6 +768,12 @@ impl<D: Driver> Inner<D> {
746768                    socket. set_outgoing_options ( core:: slice:: from_ref ( & hostname. option ) ) ; 
747769                } 
748770
771+                 // The domain-search (119) option specifies a list of domains to use when looking up bare 
772+                 // hostnames, and is specified in resolv.conf with the search keyword. If this option 
773+                 // isn't provided it defaults to the single domain provided by domain-name (15). 
774+                 #[ cfg( feature = "dhcpv4-domainname" ) ]  
775+                 socket. set_parameter_request_list ( & [ 1 ,  3 ,  6 ,  15 ,  119 ] ) ; 
776+ 
749777                socket. reset ( ) ; 
750778            } 
751779            _ => { 
@@ -904,6 +932,21 @@ impl<D: Driver> Inner<D> {
904932                            dns_servers :  config. dns_servers , 
905933                        } ) ; 
906934                        apply_config = true ; 
935+ 
936+                         #[ cfg( feature = "dhcpv4-domainname" ) ]  
937+                         if  let  Some ( packet)  = config. packet  { 
938+                             if  let  Some ( domainname)  = packet. options ( ) . find ( |o| o. kind  == 15 )  { 
939+                                 self . domainname . clear ( ) ; 
940+                                 if  let  Ok ( name)  = core:: str:: from_utf8 ( domainname. data )  { 
941+                                     if  self . domainname . push_str ( name) . is_err ( )  { 
942+                                         warn ! ( "Domain name is too long, skipping" ) ; 
943+                                     }  else  { 
944+                                         debug ! ( "DHCP: Got domain name" ) ; 
945+                                         debug ! ( "   Domain name: '{}'" ,  self . domainname) ; 
946+                                     } 
947+                                 } 
948+                             } 
949+                         } 
907950                    } 
908951                } 
909952            }  else  if  old_link_up { 
0 commit comments