From 4b705721cae4d029b93ac9cd5df42fa81940b535 Mon Sep 17 00:00:00 2001 From: shichunma Date: Sat, 11 Apr 2026 18:26:39 +0800 Subject: [PATCH] netutils/dhcpc: parse DHCP NTP server option Request DHCP option 42 and store the returned IPv4 NTP server addresses in struct dhcpc_state for later consumers. Signed-off-by: Jerry Ma --- include/netutils/dhcpc.h | 6 +++++ netutils/dhcpc/dhcpc.c | 52 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/include/netutils/dhcpc.h b/include/netutils/dhcpc.h index 0cf16907b..b17d6f368 100644 --- a/include/netutils/dhcpc.h +++ b/include/netutils/dhcpc.h @@ -55,6 +55,10 @@ # define CONFIG_NETDB_DNSSERVER_NAMESERVERS 1 #endif +#if !defined(CONFIG_NETUTILS_DHCPC_NTP_SERVERS) +# define CONFIG_NETUTILS_DHCPC_NTP_SERVERS 1 +#endif + /**************************************************************************** * Public Types ****************************************************************************/ @@ -66,6 +70,8 @@ struct dhcpc_state struct in_addr netmask; struct in_addr dnsaddr[CONFIG_NETDB_DNSSERVER_NAMESERVERS]; uint8_t num_dnsaddr; /* Number of DNS addresses received */ + struct in_addr ntpaddr[CONFIG_NETUTILS_DHCPC_NTP_SERVERS]; + uint8_t num_ntpaddr; /* Number of NTP addresses received */ struct in_addr default_router; uint32_t lease_time; /* Lease expires in this number of seconds */ uint32_t renewal_time; /* Seconds to transition to RENEW state(T1) */ diff --git a/netutils/dhcpc/dhcpc.c b/netutils/dhcpc/dhcpc.c index e899b6930..a449c96ca 100644 --- a/netutils/dhcpc/dhcpc.c +++ b/netutils/dhcpc/dhcpc.c @@ -91,6 +91,7 @@ #define DHCP_OPTION_ROUTER 3 #define DHCP_OPTION_DNS_SERVER 6 #define DHCP_OPTION_HOST_NAME 12 +#define DHCP_OPTION_NTP_SERVER 42 #define DHCP_OPTION_REQ_IPADDR 50 #define DHCP_OPTION_LEASE_TIME 51 #define DHCP_OPTION_MSG_TYPE 53 @@ -210,10 +211,11 @@ static FAR uint8_t *dhcpc_addclientid(FAR uint8_t *clientid, static FAR uint8_t *dhcpc_addreqoptions(FAR uint8_t *optptr) { *optptr++ = DHCP_OPTION_REQ_LIST; - *optptr++ = 3; + *optptr++ = 4; *optptr++ = DHCP_OPTION_SUBNET_MASK; *optptr++ = DHCP_OPTION_ROUTER; *optptr++ = DHCP_OPTION_DNS_SERVER; + *optptr++ = DHCP_OPTION_NTP_SERVER; return optptr; } @@ -411,6 +413,39 @@ static uint8_t dhcpc_parseoptions(FAR struct dhcpc_state *presult, } break; + case DHCP_OPTION_NTP_SERVER: + + /* Get the NTP server addresses in network order. + * DHCP option 42 can contain multiple IPv4 addresses, + * each 4 bytes long. + */ + + if (optptr + 2 <= end) + { + uint8_t optlen = *(optptr + 1); + uint8_t num_ntp = optlen / 4; + uint8_t i; + + if (num_ntp > CONFIG_NETUTILS_DHCPC_NTP_SERVERS) + { + num_ntp = CONFIG_NETUTILS_DHCPC_NTP_SERVERS; + } + + presult->num_ntpaddr = 0; + for (i = 0; i < num_ntp && (optptr + 2 + i * 4 + 4) <= end; + i++) + { + memcpy(&presult->ntpaddr[i].s_addr, optptr + 2 + i * 4, + 4); + presult->num_ntpaddr++; + } + } + else + { + nerr("Packet too short (NTP address missing)\n"); + } + break; + case DHCP_OPTION_MSG_TYPE: /* Get message type */ @@ -999,6 +1034,21 @@ int dhcpc_request(FAR void *handle, FAR struct dhcpc_state *presult) } } + /* Print all NTP servers received */ + + if (presult->num_ntpaddr > 0) + { + uint8_t i; + for (i = 0; i < presult->num_ntpaddr; i++) + { + ninfo("Got NTP server %d: %u.%u.%u.%u\n", i, + ip4_addr1(presult->ntpaddr[i].s_addr), + ip4_addr2(presult->ntpaddr[i].s_addr), + ip4_addr3(presult->ntpaddr[i].s_addr), + ip4_addr4(presult->ntpaddr[i].s_addr)); + } + } + ninfo("Got default router %u.%u.%u.%u\n", ip4_addr1(presult->default_router.s_addr), ip4_addr2(presult->default_router.s_addr),