net: dhcpv4: Implement DHCPv4 server

Add basic socket-based implementation of DHCPv4 sever.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2024-01-16 17:38:56 +01:00 committed by Fabio Baltieri
parent db80ed3e8d
commit 1e08bbd543
8 changed files with 1630 additions and 0 deletions

View file

@ -0,0 +1,118 @@
/** @file
* @brief DHCPv4 Server API
*/
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_
#define ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_
#include <zephyr/net/net_ip.h>
#include <zephyr/sys_clock.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief DHCPv4 server
* @defgroup dhcpv4_server DHCPv4 server
* @ingroup networking
* @{
*/
/** @cond INTERNAL_HIDDEN */
struct net_if;
#define DHCPV4_CLIENT_ID_MAX_SIZE 20
enum dhcpv4_server_addr_state {
DHCPV4_SERVER_ADDR_FREE,
DHCPV4_SERVER_ADDR_RESERVED,
DHCPV4_SERVER_ADDR_ALLOCATED,
DHCPV4_SERVER_ADDR_DECLINED,
};
struct dhcpv4_client_id {
uint8_t buf[DHCPV4_CLIENT_ID_MAX_SIZE];
uint8_t len;
};
struct dhcpv4_addr_slot {
enum dhcpv4_server_addr_state state;
struct dhcpv4_client_id client_id;
struct in_addr addr;
uint32_t lease_time;
k_timepoint_t expiry;
};
/** @endcond */
/**
* @brief Start DHCPv4 server instance on an iface
*
* @details Start DHCPv4 server on a given interface. The server will start
* listening for DHCPv4 Discover/Request messages on the interface and assign
* IPv4 addresses from the configured address pool accordingly.
*
* @param iface A valid pointer on an interface
* @param base_addr First IPv4 address from the DHCPv4 address pool. The number
* of addresses in the pool is configured statically with Kconfig
* (CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT).
*
* @return 0 on success, a negative error code otherwise.
*/
int net_dhcpv4_server_start(struct net_if *iface, struct in_addr *base_addr);
/**
* @brief Stop DHCPv4 server instance on an iface
*
* @details Stop DHCPv4 server on a given interface. DHCPv4 requests will no
* longer be handled on the interface, and all of the allocations are cleared.
*
* @param iface A valid pointer on an interface
*
* @return 0 on success, a negative error code otherwise.
*/
int net_dhcpv4_server_stop(struct net_if *iface);
/**
* @typedef net_dhcpv4_lease_cb_t
* @brief Callback used while iterating over active DHCPv4 address leases
*
* @param iface Pointer to the network interface
* @param lease Pointer to the DHPCv4 address lease slot
* @param user_data A valid pointer to user data or NULL
*/
typedef void (*net_dhcpv4_lease_cb_t)(struct net_if *iface,
struct dhcpv4_addr_slot *lease,
void *user_data);
/**
* @brief Iterate over all DHCPv4 address leases on a given network interface
* and call callback for each lease. In case no network interface is provided
* (NULL interface pointer), will iterate over all interfaces running DHCPv4
* server instance.
*
* @param iface Pointer to the network interface, can be NULL
* @param cb User-supplied callback function to call
* @param user_data User specified data
*/
int net_dhcpv4_server_foreach_lease(struct net_if *iface,
net_dhcpv4_lease_cb_t cb,
void *user_data);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ */

View file

@ -62,6 +62,7 @@ struct dhcp_msg {
#define DHCPV4_OPTIONS_REQ_LIST 55
#define DHCPV4_OPTIONS_RENEWAL 58
#define DHCPV4_OPTIONS_REBINDING 59
#define DHCPV4_OPTIONS_CLIENT_ID 61
#define DHCPV4_OPTIONS_END 255
/* Useful size macros */
@ -142,4 +143,14 @@ static inline bool net_dhcpv4_accept_unicast(struct net_pkt *pkt)
#endif /* CONFIG_NET_DHCPV4 && CONFIG_NET_DHCPV4_ACCEPT_UNICAST */
#if defined(CONFIG_NET_DHCPV4_SERVER)
void net_dhcpv4_server_init(void);
#else
#define net_dhcpv4_server_init()
#endif /* CONFIG_NET_DHCPV4_SERVER */
#endif /* __INTERNAL_DHCPV4_H */

View file

@ -559,6 +559,8 @@ static inline int services_init(void)
return status;
}
net_dhcpv4_server_init();
dns_init_resolver();
websocket_init();

View file

@ -15,6 +15,7 @@ add_subdirectory_ifdef(CONFIG_NET_CAPTURE capture)
add_subdirectory_ifdef(CONFIG_NET_ZPERF zperf)
add_subdirectory_ifdef(CONFIG_NET_SHELL shell)
add_subdirectory_ifdef(CONFIG_NET_TRICKLE trickle)
add_subdirectory_ifdef(CONFIG_NET_DHCPV4_SERVER dhcpv4)
if (CONFIG_DNS_RESOLVER
OR CONFIG_MDNS_RESPONDER

View file

@ -39,6 +39,8 @@ menu "Network additional services"
source "subsys/net/lib/capture/Kconfig"
source "subsys/net/lib/dhcpv4/Kconfig"
source "subsys/net/lib/trickle/Kconfig"
source "subsys/net/lib/zperf/Kconfig"

View file

@ -0,0 +1,11 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
zephyr_library_sources(
dhcpv4_server.c
)

View file

@ -0,0 +1,46 @@
# DHCPv4 server implementation for Zephyr
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
config NET_DHCPV4_SERVER
bool "DHCPv4 server"
depends on NET_IPV4 && NET_UDP
select NET_SOCKETS
select NET_SOCKETS_SERVICE
if NET_DHCPV4_SERVER
module = NET_DHCPV4_SERVER
module-dep = NET_LOG
module-str = Log level for DHCPv4 server
module-help = Enables DHCPv4 server output debug messages
source "subsys/net/Kconfig.template.log_config.net"
config NET_DHCPV4_SERVER_INSTANCES
int "Maximum number of DHCPv4 server instances"
default 1
help
Maximum number of DHCPv4 server instances supported by the system.
Each network interface that wants to act as a DHCPv4 server requires
a separate instance.
config NET_DHCPV4_SERVER_ADDR_COUNT
int "Number of IPv4 addresses that can be assigned by the server"
default 4
help
Maximum number of IPv4 addresses that can be assigned by the DHCPv4
server instance. The base IPv4 address in the address pool is provided
at runtime, during server initialization. Consecutive addresses in the
pool have the lowest address octet incremented.
config NET_DHCPV4_SERVER_ADDR_LEASE_TIME
int "Lease time for IPv4 addresses assigned by the server (seconds)"
default 86400
help
Lease time in seconds for IPv4 addresses assigned by the server.
The lease time determines when the IPv4 address lease expires if the
client does not renew it.
endif # NET_DHCPV4_SERVER

File diff suppressed because it is too large Load diff