From 417f4b11d3523c3b7367496e2b30cc850e8fd018 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20H=C3=A4rdeman?= Date: Tue, 7 Oct 2025 10:09:38 +0200 Subject: [PATCH] dhcpv4: don't hardcode options array length MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Instead of copying around the same data on the stack, keep two arrays with mandatory and requested options, then loop over both of them. Signed-off-by: David Härdeman Link: https://github.com/openwrt/odhcpd/pull/278 Signed-off-by: Álvaro Fernández Rojas --- src/dhcpv4.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 509f9e7..aa72bdc 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -780,8 +780,6 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, .code = DHCPV4_OPT_DNR, }; uint8_t reply_end = DHCPV4_OPT_END; - uint8_t *reply_opts; - size_t reply_opts_len = 0; struct iovec iov[IOV_TOTAL] = { [IOV_HEADER] = { &reply, sizeof(reply) }, @@ -812,6 +810,22 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, [IOV_PADDING] = { NULL, 0 }, }; + /* Options which *might* be included in the reply unrequested */ + uint8_t std_opts[] = { + DHCPV4_OPT_NETMASK, + DHCPV4_OPT_ROUTER, + DHCPV4_OPT_DNSSERVER, + DHCPV4_OPT_HOSTNAME, + DHCPV4_OPT_MTU, + DHCPV4_OPT_BROADCAST, + DHCPV4_OPT_LEASETIME, + DHCPV4_OPT_RENEW, + DHCPV4_OPT_REBIND, + DHCPV4_OPT_AUTHENTICATION, + DHCPV4_OPT_SEARCH_DOMAIN, + DHCPV4_OPT_FORCERENEW_NONCE_CAPABLE, + }; + /* Misc */ struct sockaddr_in dest_addr; bool incl_fr_opt = false; @@ -957,25 +971,11 @@ void dhcpv4_handle_msg(void *src_addr, void *data, size_t len, return; } - reply_opts = alloca(req_opts_len + 32); - reply_opts[reply_opts_len++] = DHCPV4_OPT_NETMASK; - reply_opts[reply_opts_len++] = DHCPV4_OPT_ROUTER; - reply_opts[reply_opts_len++] = DHCPV4_OPT_DNSSERVER; - reply_opts[reply_opts_len++] = DHCPV4_OPT_HOSTNAME; - reply_opts[reply_opts_len++] = DHCPV4_OPT_MTU; - reply_opts[reply_opts_len++] = DHCPV4_OPT_BROADCAST; - reply_opts[reply_opts_len++] = DHCPV4_OPT_LEASETIME; - reply_opts[reply_opts_len++] = DHCPV4_OPT_RENEW; - reply_opts[reply_opts_len++] = DHCPV4_OPT_REBIND; - reply_opts[reply_opts_len++] = DHCPV4_OPT_AUTHENTICATION; - reply_opts[reply_opts_len++] = DHCPV4_OPT_SEARCH_DOMAIN; - reply_opts[reply_opts_len++] = DHCPV4_OPT_FORCERENEW_NONCE_CAPABLE; - memcpy(&reply_opts[reply_opts_len], req_opts, req_opts_len); - reply_opts_len += req_opts_len; - /* Note: each option might get called more than once */ - for (size_t i = 0; i < reply_opts_len; i++) { - switch (reply_opts[i]) { + for (size_t i = 0; i < sizeof(std_opts) + req_opts_len; i++) { + uint8_t opt = i < sizeof(std_opts) ? std_opts[i] : req_opts[i - sizeof(std_opts)]; + + switch (opt) { case DHCPV4_OPT_NETMASK: if (!a) break; -- 2.30.2