diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index e31adbe6e3..9516911cbe 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -430,6 +430,11 @@ struct net_if_dhcpv4 { /** The source address of a received DHCP message */ struct in_addr response_src_addr; + +#ifdef CONFIG_NET_DHCPV4_OPTION_NTP_SERVER + /** NTP server address */ + struct in_addr ntp_addr; +#endif }; #endif /* CONFIG_NET_DHCPV4 */ diff --git a/subsys/net/lib/dhcpv4/Kconfig b/subsys/net/lib/dhcpv4/Kconfig index e76fc78e35..5a0f1aae31 100644 --- a/subsys/net/lib/dhcpv4/Kconfig +++ b/subsys/net/lib/dhcpv4/Kconfig @@ -69,6 +69,14 @@ config NET_DHCPV4_VENDOR_CLASS_IDENTIFIER_STRING The string to include in the DHCPv4 vendor class identifier option in the DHCPv4 request. +config NET_DHCPV4_OPTION_NTP_SERVER + bool "Use NTP server from DHCPv4 option and save it in the net_if" + default y + depends on SNTP + help + If this option is set, then the NTP server can be set from the + DHCPv4 option. + endif # NET_DHCPV4 config NET_DHCPV4_SERVER diff --git a/subsys/net/lib/dhcpv4/dhcpv4.c b/subsys/net/lib/dhcpv4/dhcpv4.c index cb43a3a22e..e916d3f86c 100644 --- a/subsys/net/lib/dhcpv4/dhcpv4.c +++ b/subsys/net/lib/dhcpv4/dhcpv4.c @@ -52,6 +52,9 @@ static int unique_types_in_callbacks; static const uint8_t min_req_options[] = { DHCPV4_OPTIONS_SUBNET_MASK, DHCPV4_OPTIONS_ROUTER, +#ifdef CONFIG_NET_DHCPV4_OPTION_NTP_SERVER + DHCPV4_OPTIONS_NTP_SERVER, +#endif DHCPV4_OPTIONS_DNS_SERVER }; @@ -892,6 +895,32 @@ static bool dhcpv4_parse_options(struct net_pkt *pkt, break; } #endif +#if defined(CONFIG_NET_DHCPV4_OPTION_NTP_SERVER) + case DHCPV4_OPTIONS_NTP_SERVER: { + + /* NTP server option may present 1 or more + * addresses. Each 4 bytes in length. NTP + * servers should be listed in order + * of preference. Hence we choose the first + * and skip the rest. + */ + if (length % 4 != 0U) { + NET_ERR("options_log_server, bad length"); + return false; + } + + if (net_pkt_read(pkt, iface->config.dhcpv4.ntp_addr.s4_addr, 4) < 0 || + net_pkt_skip(pkt, length - 4U) < 0) { + NET_ERR("options_ntp_server, short packet"); + return false; + } + + NET_DBG("options_ntp_server: %s", + net_sprint_ipv4_addr(&iface->config.dhcpv4.ntp_addr)); + + break; + } +#endif /* CONFIG_NET_DHCPV4_OPTION_NTP_SERVER */ case DHCPV4_OPTIONS_LEASE_TIME: if (length != 4U) { NET_ERR("options_lease_time, bad length"); diff --git a/subsys/net/lib/dhcpv4/dhcpv4_internal.h b/subsys/net/lib/dhcpv4/dhcpv4_internal.h index 3f859379ce..677ccf99ac 100644 --- a/subsys/net/lib/dhcpv4/dhcpv4_internal.h +++ b/subsys/net/lib/dhcpv4/dhcpv4_internal.h @@ -55,6 +55,7 @@ struct dhcp_msg { #define DHCPV4_OPTIONS_ROUTER 3 #define DHCPV4_OPTIONS_DNS_SERVER 6 #define DHCPV4_OPTIONS_HOST_NAME 12 +#define DHCPV4_OPTIONS_NTP_SERVER 42 #define DHCPV4_OPTIONS_REQ_IPADDR 50 #define DHCPV4_OPTIONS_LEASE_TIME 51 #define DHCPV4_OPTIONS_MSG_TYPE 53