| Crates.io | leasehund |
| lib.rs | leasehund |
| version | 0.2.0 |
| created_at | 2025-07-01 15:08:21.074573+00 |
| updated_at | 2025-07-01 16:08:24.445763+00 |
| description | A lightweight, embedded-friendly DHCP server implementation for Rust no_std environments |
| homepage | https://github.com/rttfd/leasehund |
| repository | https://github.com/rttfd/leasehund |
| max_upload_size | |
| id | 1733303 |
| size | 66,276 |

A lightweight, embedded-friendly DHCP server implementation for Rust no_std environments.
Leasehund provides a minimal DHCP server implementation designed for embedded systems and resource-constrained environments. Built on top of the Embassy async runtime, it supports the core DHCP functionality needed for automatic IP address assignment in local networks.
Add this to your Cargo.toml:
[dependencies]
leasehund = "0.2.0"
#![no_std]
#![no_main]
use core::net::Ipv4Addr;
use leasehund::DhcpServer;
use embassy_net::Stack;
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
// Initialize your embassy network stack here
let stack = /* ... your network stack initialization ... */;
// Create DHCP server with explicit const generics
let mut dhcp_server: DhcpServer<32, 4> = DhcpServer::new_with_dns(
Ipv4Addr::new(192, 168, 1, 1), // Server IP
Ipv4Addr::new(255, 255, 255, 0), // Subnet mask
Ipv4Addr::new(192, 168, 1, 1), // Router/Gateway
Ipv4Addr::new(8, 8, 8, 8), // DNS server
Ipv4Addr::new(192, 168, 1, 100), // IP pool start
Ipv4Addr::new(192, 168, 1, 200), // IP pool end
);
// Run the DHCP server (this will loop forever)
dhcp_server.run(stack).await;
}
The DHCP server requires the following configuration parameters:
| Parameter | Description | Example |
|---|---|---|
server_ip |
IP address of the DHCP server | 192.168.1.1 |
subnet_mask |
Network subnet mask | 255.255.255.0 |
router |
Default gateway IP address | 192.168.1.1 |
dns_server |
DNS server IP address | 8.8.8.8 |
ip_pool_start |
First IP in the assignable range | 192.168.1.100 |
ip_pool_end |
Last IP in the assignable range | 192.168.1.200 |
You can use the builder API to customize all key DHCP server parameters at runtime (const generics for sizing):
use core::net::Ipv4Addr;
use leasehund::{DhcpConfigBuilder, DhcpServer};
let config: leasehund::DhcpConfig<4> = DhcpConfigBuilder::<4>::new()
.server_ip(Ipv4Addr::new(10, 0, 1, 1))
.subnet_mask(Ipv4Addr::new(255, 255, 0, 0))
.router(Ipv4Addr::new(10, 0, 1, 1))
.add_dns_server(Ipv4Addr::new(1, 1, 1, 1))
.add_dns_server(Ipv4Addr::new(1, 0, 0, 1))
.ip_pool(Ipv4Addr::new(10, 0, 100, 1), Ipv4Addr::new(10, 0, 199, 254))
.lease_time(7200) // 2 hours
.socket_buffer_size(2048)
.build();
let server: DhcpServer<32, 4> = DhcpServer::with_config(config);
Note: The maximum number of concurrent leases and DNS servers are now compile-time constants set via const generics (e.g., DhcpServer::<32, 4>).
| Message Type | Description | Server Response |
|---|---|---|
| DISCOVER | Client broadcast to find DHCP servers | OFFER with available IP |
| REQUEST | Client request for specific IP address | ACK confirming lease |
| RELEASE | Client releasing IP address | Lease removal (no response) |
The server automatically includes these standard DHCP options in responses:
Option 1: Subnet Mask
Option 3: Router (Default Gateway)
Option 6: Domain Name Server (DNS)
Option 51: IP Address Lease Time
Option 53: DHCP Message Type
Option 54: Server Identifier
Leasehund is compliant with RFC 2131 and RFC 2132. All DHCP packets include and check the required DHCP magic cookie (0x63825363, see RFC 2132 section 2) for strict standards compliance.
The server uses fixed-size data structures to ensure predictable memory usage:
FnvIndexMap with maximum number of entries set by the const generic parameter (e.g., DhcpServer::<32, 4>, compile-time fixed)let dhcp_server: DhcpServer<32, 4> = DhcpServer::new_with_dns(
Ipv4Addr::new(192, 168, 1, 1), // Router IP
Ipv4Addr::new(255, 255, 255, 0), // /24 network
Ipv4Addr::new(192, 168, 1, 1), // Gateway
Ipv4Addr::new(1, 1, 1, 1), // Cloudflare DNS
Ipv4Addr::new(192, 168, 1, 100), // Pool start
Ipv4Addr::new(192, 168, 1, 199), // Pool end (100 addresses)
);
let dhcp_server: DhcpServer<32, 4> = DhcpServer::new_with_dns(
Ipv4Addr::new(10, 0, 1, 1), // Server IP
Ipv4Addr::new(255, 255, 0, 0), // /16 network
Ipv4Addr::new(10, 0, 1, 1), // Gateway
Ipv4Addr::new(10, 0, 1, 2), // Internal DNS
Ipv4Addr::new(10, 0, 100, 1), // Large pool start
Ipv4Addr::new(10, 0, 199, 254), // Large pool end
);
DhcpConfig/DhcpConfigBuilder (default 24 hours)DhcpServer::<32, 4>)DhcpServer::<32, 4>)Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
git clone https://github.com/rttfd/leasehund.git
cd leasehund
cargo build
cargo test
This project is licensed under the MIT License - see the LICENSE file for details.
Leasehund - Because every good network needs a reliable dog to fetch IP addresses! 🐕🦺