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 <masc2008@gmail.com>
This commit is contained in:
shichunma 2026-04-11 18:26:39 +08:00 committed by Alan C. Assis
parent 62f3d37041
commit 4b705721ca
2 changed files with 57 additions and 1 deletions

View file

@ -55,6 +55,10 @@
# define CONFIG_NETDB_DNSSERVER_NAMESERVERS 1 # define CONFIG_NETDB_DNSSERVER_NAMESERVERS 1
#endif #endif
#if !defined(CONFIG_NETUTILS_DHCPC_NTP_SERVERS)
# define CONFIG_NETUTILS_DHCPC_NTP_SERVERS 1
#endif
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
@ -66,6 +70,8 @@ struct dhcpc_state
struct in_addr netmask; struct in_addr netmask;
struct in_addr dnsaddr[CONFIG_NETDB_DNSSERVER_NAMESERVERS]; struct in_addr dnsaddr[CONFIG_NETDB_DNSSERVER_NAMESERVERS];
uint8_t num_dnsaddr; /* Number of DNS addresses received */ 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; struct in_addr default_router;
uint32_t lease_time; /* Lease expires in this number of seconds */ uint32_t lease_time; /* Lease expires in this number of seconds */
uint32_t renewal_time; /* Seconds to transition to RENEW state(T1) */ uint32_t renewal_time; /* Seconds to transition to RENEW state(T1) */

View file

@ -91,6 +91,7 @@
#define DHCP_OPTION_ROUTER 3 #define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6 #define DHCP_OPTION_DNS_SERVER 6
#define DHCP_OPTION_HOST_NAME 12 #define DHCP_OPTION_HOST_NAME 12
#define DHCP_OPTION_NTP_SERVER 42
#define DHCP_OPTION_REQ_IPADDR 50 #define DHCP_OPTION_REQ_IPADDR 50
#define DHCP_OPTION_LEASE_TIME 51 #define DHCP_OPTION_LEASE_TIME 51
#define DHCP_OPTION_MSG_TYPE 53 #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) static FAR uint8_t *dhcpc_addreqoptions(FAR uint8_t *optptr)
{ {
*optptr++ = DHCP_OPTION_REQ_LIST; *optptr++ = DHCP_OPTION_REQ_LIST;
*optptr++ = 3; *optptr++ = 4;
*optptr++ = DHCP_OPTION_SUBNET_MASK; *optptr++ = DHCP_OPTION_SUBNET_MASK;
*optptr++ = DHCP_OPTION_ROUTER; *optptr++ = DHCP_OPTION_ROUTER;
*optptr++ = DHCP_OPTION_DNS_SERVER; *optptr++ = DHCP_OPTION_DNS_SERVER;
*optptr++ = DHCP_OPTION_NTP_SERVER;
return optptr; return optptr;
} }
@ -411,6 +413,39 @@ static uint8_t dhcpc_parseoptions(FAR struct dhcpc_state *presult,
} }
break; 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: case DHCP_OPTION_MSG_TYPE:
/* Get message 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", ninfo("Got default router %u.%u.%u.%u\n",
ip4_addr1(presult->default_router.s_addr), ip4_addr1(presult->default_router.s_addr),
ip4_addr2(presult->default_router.s_addr), ip4_addr2(presult->default_router.s_addr),