diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-10-06 20:47:31 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-10-07 01:33:21 +0200 |
| commit | 534eb960e9f7c9bb28cbd6ffe10b6cc43fd55ff7 (patch) | |
| tree | 16dff322979e05e9da47c95e3131a3ac49e9b1e4 /embassy-net | |
| parent | f30fc949ff34683bd9b9330d09583da4a35428ea (diff) | |
net: add support for dhcp hostname option.
Diffstat (limited to 'embassy-net')
| -rw-r--r-- | embassy-net/Cargo.toml | 1 | ||||
| -rw-r--r-- | embassy-net/src/lib.rs | 44 |
2 files changed, 45 insertions, 0 deletions
diff --git a/embassy-net/Cargo.toml b/embassy-net/Cargo.toml index 89582deee..c2fffba84 100644 --- a/embassy-net/Cargo.toml +++ b/embassy-net/Cargo.toml | |||
| @@ -33,6 +33,7 @@ udp = ["smoltcp/socket-udp"] | |||
| 33 | tcp = ["smoltcp/socket-tcp"] | 33 | tcp = ["smoltcp/socket-tcp"] |
| 34 | dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"] | 34 | dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"] |
| 35 | dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"] | 35 | dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"] |
| 36 | dhcpv4-hostname = ["dhcpv4"] | ||
| 36 | proto-ipv4 = ["smoltcp/proto-ipv4"] | 37 | proto-ipv4 = ["smoltcp/proto-ipv4"] |
| 37 | proto-ipv6 = ["smoltcp/proto-ipv6"] | 38 | proto-ipv6 = ["smoltcp/proto-ipv6"] |
| 38 | medium-ethernet = ["smoltcp/medium-ethernet"] | 39 | medium-ethernet = ["smoltcp/medium-ethernet"] |
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 297f04679..ef67935e1 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs | |||
| @@ -56,12 +56,22 @@ const LOCAL_PORT_MIN: u16 = 1025; | |||
| 56 | const LOCAL_PORT_MAX: u16 = 65535; | 56 | const LOCAL_PORT_MAX: u16 = 65535; |
| 57 | #[cfg(feature = "dns")] | 57 | #[cfg(feature = "dns")] |
| 58 | const MAX_QUERIES: usize = 4; | 58 | const MAX_QUERIES: usize = 4; |
| 59 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 60 | const MAX_HOSTNAME_LEN: usize = 32; | ||
| 59 | 61 | ||
| 60 | /// Memory resources needed for a network stack. | 62 | /// Memory resources needed for a network stack. |
| 61 | pub struct StackResources<const SOCK: usize> { | 63 | pub struct StackResources<const SOCK: usize> { |
| 62 | sockets: [SocketStorage<'static>; SOCK], | 64 | sockets: [SocketStorage<'static>; SOCK], |
| 63 | #[cfg(feature = "dns")] | 65 | #[cfg(feature = "dns")] |
| 64 | queries: [Option<dns::DnsQuery>; MAX_QUERIES], | 66 | queries: [Option<dns::DnsQuery>; MAX_QUERIES], |
| 67 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 68 | hostname: core::cell::UnsafeCell<HostnameResources>, | ||
| 69 | } | ||
| 70 | |||
| 71 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 72 | struct HostnameResources { | ||
| 73 | option: smoltcp::wire::DhcpOption<'static>, | ||
| 74 | data: [u8; MAX_HOSTNAME_LEN], | ||
| 65 | } | 75 | } |
| 66 | 76 | ||
| 67 | impl<const SOCK: usize> StackResources<SOCK> { | 77 | impl<const SOCK: usize> StackResources<SOCK> { |
| @@ -73,6 +83,11 @@ impl<const SOCK: usize> StackResources<SOCK> { | |||
| 73 | sockets: [SocketStorage::EMPTY; SOCK], | 83 | sockets: [SocketStorage::EMPTY; SOCK], |
| 74 | #[cfg(feature = "dns")] | 84 | #[cfg(feature = "dns")] |
| 75 | queries: [INIT; MAX_QUERIES], | 85 | queries: [INIT; MAX_QUERIES], |
| 86 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 87 | hostname: core::cell::UnsafeCell::new(HostnameResources { | ||
| 88 | option: smoltcp::wire::DhcpOption { kind: 0, data: &[] }, | ||
| 89 | data: [0; MAX_HOSTNAME_LEN], | ||
| 90 | }), | ||
| 76 | } | 91 | } |
| 77 | } | 92 | } |
| 78 | } | 93 | } |
| @@ -104,6 +119,7 @@ pub struct StaticConfigV6 { | |||
| 104 | /// DHCP configuration. | 119 | /// DHCP configuration. |
| 105 | #[cfg(feature = "dhcpv4")] | 120 | #[cfg(feature = "dhcpv4")] |
| 106 | #[derive(Debug, Clone, PartialEq, Eq)] | 121 | #[derive(Debug, Clone, PartialEq, Eq)] |
| 122 | #[non_exhaustive] | ||
| 107 | pub struct DhcpConfig { | 123 | pub struct DhcpConfig { |
| 108 | /// Maximum lease duration. | 124 | /// Maximum lease duration. |
| 109 | /// | 125 | /// |
| @@ -120,6 +136,9 @@ pub struct DhcpConfig { | |||
| 120 | pub server_port: u16, | 136 | pub server_port: u16, |
| 121 | /// Client port. This is almost always 68. Do not change unless you know what you're doing. | 137 | /// Client port. This is almost always 68. Do not change unless you know what you're doing. |
| 122 | pub client_port: u16, | 138 | pub client_port: u16, |
| 139 | /// Our hostname. This will be sent to the DHCP server as Option 12. | ||
| 140 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 141 | pub hostname: Option<heapless::String<MAX_HOSTNAME_LEN>>, | ||
| 123 | } | 142 | } |
| 124 | 143 | ||
| 125 | #[cfg(feature = "dhcpv4")] | 144 | #[cfg(feature = "dhcpv4")] |
| @@ -131,6 +150,8 @@ impl Default for DhcpConfig { | |||
| 131 | ignore_naks: Default::default(), | 150 | ignore_naks: Default::default(), |
| 132 | server_port: smoltcp::wire::DHCP_SERVER_PORT, | 151 | server_port: smoltcp::wire::DHCP_SERVER_PORT, |
| 133 | client_port: smoltcp::wire::DHCP_CLIENT_PORT, | 152 | client_port: smoltcp::wire::DHCP_CLIENT_PORT, |
| 153 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 154 | hostname: None, | ||
| 134 | } | 155 | } |
| 135 | } | 156 | } |
| 136 | } | 157 | } |
| @@ -232,6 +253,8 @@ struct Inner<D: Driver> { | |||
| 232 | dns_socket: SocketHandle, | 253 | dns_socket: SocketHandle, |
| 233 | #[cfg(feature = "dns")] | 254 | #[cfg(feature = "dns")] |
| 234 | dns_waker: WakerRegistration, | 255 | dns_waker: WakerRegistration, |
| 256 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 257 | hostname: &'static mut core::cell::UnsafeCell<HostnameResources>, | ||
| 235 | } | 258 | } |
| 236 | 259 | ||
| 237 | pub(crate) struct SocketStack { | 260 | pub(crate) struct SocketStack { |
| @@ -307,6 +330,8 @@ impl<D: Driver> Stack<D> { | |||
| 307 | )), | 330 | )), |
| 308 | #[cfg(feature = "dns")] | 331 | #[cfg(feature = "dns")] |
| 309 | dns_waker: WakerRegistration::new(), | 332 | dns_waker: WakerRegistration::new(), |
| 333 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 334 | hostname: &mut resources.hostname, | ||
| 310 | }; | 335 | }; |
| 311 | 336 | ||
| 312 | #[cfg(feature = "proto-ipv4")] | 337 | #[cfg(feature = "proto-ipv4")] |
| @@ -673,6 +698,25 @@ impl<D: Driver> Inner<D> { | |||
| 673 | socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp)); | 698 | socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp)); |
| 674 | socket.set_ports(c.server_port, c.client_port); | 699 | socket.set_ports(c.server_port, c.client_port); |
| 675 | socket.set_retry_config(c.retry_config); | 700 | socket.set_retry_config(c.retry_config); |
| 701 | |||
| 702 | socket.set_outgoing_options(&[]); | ||
| 703 | #[cfg(feature = "dhcpv4-hostname")] | ||
| 704 | if let Some(h) = c.hostname { | ||
| 705 | // safety: we just did set_outgoing_options([]) so we know the socket is no longer holding a reference. | ||
| 706 | let hostname = unsafe { &mut *self.hostname.get() }; | ||
| 707 | |||
| 708 | // create data | ||
| 709 | // safety: we know the buffer lives forever, new borrows the StackResources for 'static. | ||
| 710 | // also we won't modify it until next call to this function. | ||
| 711 | hostname.data[..h.len()].copy_from_slice(h.as_bytes()); | ||
| 712 | let data: &[u8] = &hostname.data[..h.len()]; | ||
| 713 | let data: &'static [u8] = unsafe { core::mem::transmute(data) }; | ||
| 714 | |||
| 715 | // set the option. | ||
| 716 | hostname.option = smoltcp::wire::DhcpOption { data, kind: 12 }; | ||
| 717 | socket.set_outgoing_options(core::slice::from_ref(&hostname.option)); | ||
| 718 | } | ||
| 719 | |||
| 676 | socket.reset(); | 720 | socket.reset(); |
| 677 | } | 721 | } |
| 678 | _ => { | 722 | _ => { |
