From 6329e37d595d6fd6b2c40951ca6774a702c250d8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Mon, 6 Oct 2025 12:23:18 +0200 Subject: [PATCH] dhcpv4: use iovec for NTP MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Note that the previous code would send out several NTP options if the client requested the option more than once, and would also send out zero-sized options (against RFC2132, §8.3). Signed-off-by: David Härdeman Link: https://github.com/openwrt/odhcpd/pull/278 Signed-off-by: Álvaro Fernández Rojas --- src/dhcpv4.c | 22 ++++++++++++++++------ src/dhcpv4.h | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 7201c4a..62f6853 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -621,6 +621,8 @@ enum { IOV_HEADER = 0, IOV_MESSAGE, IOV_SERVERID, + IOV_NTP, + IOV_NTP_ADDR, IOV_END, IOV_TOTAL }; @@ -664,13 +666,19 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, .len = sizeof(struct in_addr), .data = iface->dhcpv4_local.s_addr, }; + struct dhcpv4_option reply_ntp = { + .code = DHCPV4_OPT_NTPSERVER, + .len = iface->dhcpv4_ntp_cnt * sizeof(*iface->dhcpv4_ntp), + }; uint8_t reply_end = DHCPV4_OPT_END; struct iovec iov[IOV_TOTAL] = { - [IOV_HEADER] = { &reply, 0 }, - [IOV_MESSAGE] = { &reply_msg, sizeof(reply_msg) }, - [IOV_SERVERID] = { &reply_serverid, sizeof(reply_serverid) }, - [IOV_END] = { &reply_end, sizeof(reply_end) }, + [IOV_HEADER] = { &reply, 0 }, + [IOV_MESSAGE] = { &reply_msg, sizeof(reply_msg) }, + [IOV_SERVERID] = { &reply_serverid, sizeof(reply_serverid) }, + [IOV_NTP] = { &reply_ntp, 0 }, + [IOV_NTP_ADDR] = { iface->dhcpv4_ntp, 0 }, + [IOV_END] = { &reply_end, sizeof(reply_end) }, }; /* Misc */ @@ -905,8 +913,10 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, for (size_t opt = 0; a && opt < req_opts_len; opt++) { switch (req_opts[opt]) { case DHCPV4_OPT_NTPSERVER: - dhcpv4_put(&reply, &cursor, DHCPV4_OPT_NTPSERVER, - 4 * iface->dhcpv4_ntp_cnt, iface->dhcpv4_ntp); + if (!a) + break; + iov[IOV_NTP].iov_len = sizeof(reply_ntp); + iov[IOV_NTP_ADDR].iov_len = iface->dhcpv4_ntp_cnt * sizeof(*iface->dhcpv4_ntp); break; case DHCPV4_OPT_DNR: diff --git a/src/dhcpv4.h b/src/dhcpv4.h index f96e5bf..089a626 100644 --- a/src/dhcpv4.h +++ b/src/dhcpv4.h @@ -151,7 +151,7 @@ struct dhcpv4_option_u32 { uint8_t code; uint8_t len; uint32_t data; -}; +} _packed; /* DNR */ struct dhcpv4_dnr { -- 2.30.2