Skip to content
choco-technologiesPublic

About

DHCP module

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

dmdhcp

License CI

dmdhcp DMOD library module.

Description

dmdhcp is a DHCP client (RFC 2131/2132) for the DMOD network stack. It does not implement a DHCP server.

One dmdhcp_lease_t represents the whole lease lifecycle (DISCOVER/OFFER/ REQUEST/ACK, renewal, rebinding, release) for one interface. On acquiring or renewing a lease, dmdhcp applies it to the interface itself (address/netmask/broadcast plus a default route) and reverts that on release/expiry - a caller does not need to configure the interface by hand. Address-conflict detection (RFC 2131 §4.4.1, an ARP probe before committing an address) is included.

dmdhcp keeps no thread of its own: inbound messages are processed inline on whatever thread is already pumping the interface (via dmudp_bind()), and time-driven behavior (retransmission backoff, the conflict probe, lease timers) runs on dmosi_timer_t callbacks. See docs/dmdhcp.md for the full architecture.

Building

Using CMake

mkdir -p build
cd build
cmake ..
cmake --build .

Pass -DDMOD_DIR=/path/to/local/dmod to build against a local dmod checkout instead of fetching develop from GitHub.

Using Make

make DMOD_MODE=DMOD_MODULE DMOD_DIR=/path/to/dmod

Testing

Tests are built automatically alongside the module (see tests/). Once built, run them with ctest:

cd build
ctest --output-on-failure

ctest installs the test module's dependencies with dmf-get and then runs it through dmod_loader. To run it manually instead:

export DMOD_DMF_DIR=$(pwd)/build/dmf
dmf-get install -d ${DMOD_DMF_DIR}/test_dmdhcp-local.dmd -y
dmod_loader build/dmf/test_dmdhcp.dmf

Usage

#include "dmdhcp.h"

static void on_bound(dmdhcp_lease_t lease, bool is_renewal, void* user_data)
{
    dmdhcp_lease_info_t info;
    dmdhcp_get_lease_info(lease, &info);
    /* info.ip_address / .netmask / .gateway are already applied to the
     * interface at this point - nothing further to configure. */
}

static void on_lost(dmdhcp_lease_t lease, void* user_data)
{
    /* NAK'd or the lease fully expired - the interface has already been
     * de-configured. dmdhcp restarts DISCOVER on its own. */
}

dmdhcp_callbacks_t callbacks = { .on_bound = on_bound, .on_expired_or_lost = on_lost };
dmdhcp_lease_t lease = dmdhcp_start(iface, &callbacks, NULL, NULL);

Tools

  • tools/dhcpc - Starts a lease on one interface by calling dmdhcp_start(), then exits. It's its own Application-type DMOD module (dhcpc), released alongside dmdhcp itself in every tagged release, and is what actually turns "dmdhcp is loaded" into "this interface has an address" - see "Running as a service" below.

Running as a service

dmdhcp is a Library-type module, like dmicmp - it has no main() to spawn on its own, so something still needs to load it. Unlike dmicmp (which starts answering pings the moment it's loaded), loading dmdhcp alone doesn't start acquiring a lease on any interface either - dmdhcp_start(iface, ...) still needs to be called per interface.

tools/dhcpc covers both: it links dmdhcp_if directly, so loading it also loads and enables dmdhcp as its own module dependency (no separate dhcp.ini-style unit needed anywhere in this repo), and it's the thing that actually calls dmdhcp_start(). It ships a per-interface unit template plus a device rule (tools/dhcpc/configs/dhcp@.ini / dhcp.rules) that auto-starts one instance for every interface dmnet's networkd also reacts to - both fire from the same dmnetif device event. See docs/service.md for the full setup.

API

Function Description
dmdhcp_start() Begin acquiring a lease on an interface; keeps renewing/rebinding/restarting automatically.
dmdhcp_set_callbacks() Replace a lease's callbacks/user_data.
dmdhcp_renew() Force an immediate renewal attempt.
dmdhcp_release() Send DHCPRELEASE, de-configure the interface, free the lease.
dmdhcp_stop() De-configure and free the lease without sending DHCPRELEASE.
dmdhcp_get_state() / _get_iface() / _get_user_data() / _get_xid() Simple accessors.
dmdhcp_get_lease_info() Snapshot of the active lease's address/netmask/gateway/server/lease-time.
dmdhcp_get_dns_server_count() / _get_dns_server() The DHCP-offered DNS server list.
dmdns_provide_servers (DIF implementation) Reports the DNS servers of every valid lease to the dmdns resolver - see docs/dmdhcp.md.
dmdhcp_build_message() / _parse_message() DHCP/BOOTP fixed header codec (RFC 2131 §2).
dmdhcp_options_write() / _options_find() / _option_get_*() RFC 2132 TLV options codec.

See include/dmdhcp.h for the full declarations and docs/api-reference.md for the complete reference.

Documentation

See the docs/ directory:

View documentation using dmf-man dmdhcp.

Project Structure

dmdhcp/
├── docs/                      # Documentation (markdown format)
│   ├── README.md
│   ├── api-reference.md
│   ├── dmdhcp.md               # Architecture: threading, locking, state machine
│   └── service.md               # Running DHCP as a dmsystem service
├── include/                   # Public headers
│   └── dmdhcp.h
├── src/
│   ├── dmdhcp_internal.h      # Private struct dmdhcp_lease, constants
│   ├── dmdhcp.c               # dmod_init()/_deinit(), _start()/_stop()/_release()/_renew()
│   ├── dmdhcp_registrations.c # DMOD_ENABLE_REGISTRATION (must stand alone)
│   ├── dmdhcp_lease_table.c   # Lease table CRUD, teardown, simple accessors
│   ├── dmdhcp_wire.c          # DHCP/BOOTP fixed header codec
│   ├── dmdhcp_options.c       # RFC 2132 TLV options codec
│   ├── dmdhcp_output.c        # Message senders + retransmit/probe timer
│   ├── dmdhcp_input.c         # dmudp_bind() registration + dispatch
│   └── dmdhcp_lifecycle.c     # Apply/unapply to interface + lease timer
├── tests/
│   ├── CMakeLists.txt
│   └── dmdhcp_test.c
├── tools/
│   ├── CMakeLists.txt
│   └── dhcpc/          # dhcpc CLI + its unit template/device rule, see tools/dhcpc/README.md
├── CMakeLists.txt
├── Makefile
├── dmdhcp.dmr
└── manifest.dmm

Author

Patryk Kubiak

License

MIT

NTP servers (DHCP option 42)

DISCOVER and REQUEST ask for option 42 in the parameter request list. Valid IPv4 address lists from OFFER/ACK replace the lease's previous NTP configuration. An ACK without option 42 clears it; malformed address lengths are ignored. Discovery restart and lease loss also clear the list.

dmdhcp_get_ntp_server_count() and dmdhcp_get_ntp_server() inspect a lease; dmdhcp_get_ntp_servers(out, capacity) copies a bounded snapshot from currently BOUND/RENEWING/REBINDING leases. The optional dmntp_provide_servers DIF reports those same addresses to dmntp on every sampling call. DHCP does not require or load NTP, and NTP can fall back to explicit/default servers without DHCP. The provider's sink receives four borrowed IPv4 bytes and must not re-enter DHCP.

The NTP discovery consumer and hardware integration probe are in dmntp PR #3.

About

DHCP module

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages