3 releases (breaking)

0.2.0 Feb 1, 2024
0.1.0 Jan 27, 2024
0.0.0 Nov 22, 2023

#1412 in Embedded development

Download history 11/week @ 2024-01-24 17/week @ 2024-01-31 7/week @ 2024-02-14 27/week @ 2024-02-21 10/week @ 2024-02-28 10/week @ 2024-03-13 30/week @ 2024-03-27 33/week @ 2024-04-03

73 downloads per month
Used in edge-net

MIT/Apache

85KB
2K SLoC

edge-dhcp

CI crates.io Documentation

Async + no_std + no-alloc implementation of the DHCP protocol.

For other protocols, look at the edge-net aggregator crate documentation.

Examples

DHCP client

/// NOTE: Run this example with `sudo` to be able to bind to the interface, as it uses raw sockets which require root privileges.
use edge_raw::io::Udp2RawStack;

use edge_dhcp::client::Client;
use edge_dhcp::io::{self, client::Lease, client::DEFAULT_CLIENT_PORT};

use embedded_nal_async::{Ipv4Addr, SocketAddrV4};

use log::info;

fn main() {
    env_logger::init_from_env(
        env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
    );

    futures_lite::future::block_on(run(
        2, // The interface index of the interface (e.g. eno0) to use; run `ip addr` to see it
        [0x4c, 0xcc, 0x6a, 0xa2, 0x23, 0xf5], // Your MAC addr here; run `ip addr` to see it
    ))
    .unwrap();
}

async fn run(if_index: u32, if_mac: [u8; 6]) -> Result<(), anyhow::Error> {
    let mut client = Client::new(rand::thread_rng(), if_mac);

    let stack: Udp2RawStack<_> = Udp2RawStack::new(edge_std_nal_async::Stack::new(), if_index);
    let mut buf = [0; 1500];

    loop {
        let mut socket = io::bind(
            &stack,
            SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, DEFAULT_CLIENT_PORT),
        )
        .await?;

        let (mut lease, options) = Lease::new(&mut client, &mut socket, &mut buf).await?;

        info!("Got lease {lease:?} with options {options:?}");

        info!("Entering an endless loop to keep the lease...");

        lease.keep(&mut client, &mut socket, &mut buf).await?;
    }
}

DHCP server

/// NOTE: Run this example with `sudo` to be able to bind to the interface, as it uses raw sockets which require root privileges.
use edge_raw::io::Udp2RawStack;

use edge_dhcp::io::{self, DEFAULT_SERVER_PORT};
use edge_dhcp::server::{Server, ServerOptions};

use embedded_nal_async::{Ipv4Addr, SocketAddrV4};

fn main() {
    env_logger::init_from_env(
        env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
    );

    futures_lite::future::block_on(run(
        0, // The interface index of the interface (e.g. eno0) to use; run `ip addr` to see it
    ))
    .unwrap();
}

async fn run(if_index: u32) -> Result<(), anyhow::Error> {
    let stack: Udp2RawStack<_> = Udp2RawStack::new(edge_std_nal_async::Stack::new(), if_index);

    let mut buf = [0; 1500];

    let ip = Ipv4Addr::new(192, 168, 0, 1);

    let mut socket = io::bind(&stack, SocketAddrV4::new(ip, DEFAULT_SERVER_PORT)).await?;

    let mut gw_buf = [Ipv4Addr::UNSPECIFIED];

    io::server::run(
        &mut Server::<64>::new(ip), // Will give IP addresses in the range 192.168.0.50 - 192.168.0.200, subnet 255.255.255.0
        &ServerOptions::new(ip, Some(&mut gw_buf)),
        &mut socket,
        &mut buf,
    )
    .await?;

    Ok(())
}

Dependencies

~2–2.7MB
~54K SLoC